[VarStore] Implement writing 32bit var-store

Untested.

Finishes fixing https://github.com/harfbuzz/harfbuzz/issues/2965
This commit is contained in:
Behdad Esfahbod 2022-05-30 08:32:50 -06:00
parent 75112098ac
commit 5af5a56593
1 changed files with 35 additions and 14 deletions

View File

@ -2771,44 +2771,65 @@ struct VarData
if (unlikely (!c->extend_min (this))) return_trace (false);
itemCount = inner_map.get_next_value ();
/* Optimize short count */
unsigned short ri_count = src->regionIndices.len;
enum delta_size_t { kZero=0, kByte, kShort };
/* Optimize word count */
unsigned ri_count = src->regionIndices.len;
enum delta_size_t { kZero=0, kNonWord, kWord };
hb_vector_t<delta_size_t> delta_sz;
hb_vector_t<unsigned int> ri_map; /* maps old index to new index */
delta_sz.resize (ri_count);
ri_map.resize (ri_count);
unsigned int new_short_count = 0;
unsigned int new_word_count = 0;
unsigned int r;
bool has_long = false;
if (src->longWords ())
{
for (r = 0; r < ri_count; r++)
{
for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
{
unsigned int old = inner_map.backward (i);
int32_t delta = src->get_item_delta (old, r);
if (delta < -65536 || 65535 < delta)
{
has_long = true;
break;
}
}
}
}
signed min_threshold = has_long ? -65536 : -128;
signed max_threshold = has_long ? +65535 : +127;
for (r = 0; r < ri_count; r++)
{
delta_sz[r] = kZero;
for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
{
unsigned int old = inner_map.backward (i);
int16_t delta = src->get_item_delta (old, r);
if (delta < -128 || 127 < delta)
int32_t delta = src->get_item_delta (old, r);
if (delta < min_threshold || max_threshold < delta)
{
delta_sz[r] = kShort;
new_short_count++;
delta_sz[r] = kWord;
new_word_count++;
break;
}
else if (delta != 0)
delta_sz[r] = kByte;
delta_sz[r] = kNonWord;
}
}
unsigned int short_index = 0;
unsigned int byte_index = new_short_count;
unsigned int word_index = 0;
unsigned int non_word_index = new_word_count;
unsigned int new_ri_count = 0;
for (r = 0; r < ri_count; r++)
if (delta_sz[r])
{
ri_map[r] = (delta_sz[r] == kShort)? short_index++ : byte_index++;
ri_map[r] = (delta_sz[r] == kWord)? word_index++ : non_word_index++;
new_ri_count++;
}
/* XXX TODO Support serializing 32bit VarStore. */
wordSizeCount = new_short_count;
wordSizeCount = new_word_count | (has_long ? 0x8000u /* LONG_WORDS */ : 0);
regionIndices.len = new_ri_count;