commit
f8b26f43ec
|
@ -2689,7 +2689,7 @@ struct VarData
|
||||||
{ return regionIndices.len; }
|
{ return regionIndices.len; }
|
||||||
|
|
||||||
unsigned int get_row_size () const
|
unsigned int get_row_size () const
|
||||||
{ return shortCount + regionIndices.len; }
|
{ return (wordCount () + regionIndices.len) * (longWords () ? 2 : 1); }
|
||||||
|
|
||||||
unsigned int get_size () const
|
unsigned int get_size () const
|
||||||
{ return min_size
|
{ return min_size
|
||||||
|
@ -2706,7 +2706,10 @@ struct VarData
|
||||||
return 0.;
|
return 0.;
|
||||||
|
|
||||||
unsigned int count = regionIndices.len;
|
unsigned int count = regionIndices.len;
|
||||||
unsigned int scount = shortCount;
|
bool is_long = longWords ();
|
||||||
|
unsigned word_count = wordCount ();
|
||||||
|
unsigned int scount = is_long ? count - word_count : word_count;
|
||||||
|
unsigned int lcount = is_long ? word_count : 0;
|
||||||
|
|
||||||
const HBUINT8 *bytes = get_delta_bytes ();
|
const HBUINT8 *bytes = get_delta_bytes ();
|
||||||
const HBUINT8 *row = bytes + inner * (scount + count);
|
const HBUINT8 *row = bytes + inner * (scount + count);
|
||||||
|
@ -2714,7 +2717,13 @@ struct VarData
|
||||||
float delta = 0.;
|
float delta = 0.;
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
|
||||||
const HBINT16 *scursor = reinterpret_cast<const HBINT16 *> (row);
|
const HBINT16 *lcursor = reinterpret_cast<const HBINT16 *> (row);
|
||||||
|
for (; i < lcount; i++)
|
||||||
|
{
|
||||||
|
float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache);
|
||||||
|
delta += scalar * *lcursor++;
|
||||||
|
}
|
||||||
|
const HBINT16 *scursor = reinterpret_cast<const HBINT16 *> (lcursor);
|
||||||
for (; i < scount; i++)
|
for (; i < scount; i++)
|
||||||
{
|
{
|
||||||
float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache);
|
float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache);
|
||||||
|
@ -2747,7 +2756,7 @@ struct VarData
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return_trace (c->check_struct (this) &&
|
return_trace (c->check_struct (this) &&
|
||||||
regionIndices.sanitize (c) &&
|
regionIndices.sanitize (c) &&
|
||||||
shortCount <= regionIndices.len &&
|
wordCount () <= regionIndices.len &&
|
||||||
c->check_range (get_delta_bytes (),
|
c->check_range (get_delta_bytes (),
|
||||||
itemCount,
|
itemCount,
|
||||||
get_row_size ()));
|
get_row_size ()));
|
||||||
|
@ -2762,43 +2771,66 @@ struct VarData
|
||||||
if (unlikely (!c->extend_min (this))) return_trace (false);
|
if (unlikely (!c->extend_min (this))) return_trace (false);
|
||||||
itemCount = inner_map.get_next_value ();
|
itemCount = inner_map.get_next_value ();
|
||||||
|
|
||||||
/* Optimize short count */
|
/* Optimize word count */
|
||||||
unsigned short ri_count = src->regionIndices.len;
|
unsigned ri_count = src->regionIndices.len;
|
||||||
enum delta_size_t { kZero=0, kByte, kShort };
|
enum delta_size_t { kZero=0, kNonWord, kWord };
|
||||||
hb_vector_t<delta_size_t> delta_sz;
|
hb_vector_t<delta_size_t> delta_sz;
|
||||||
hb_vector_t<unsigned int> ri_map; /* maps old index to new index */
|
hb_vector_t<unsigned int> ri_map; /* maps old index to new index */
|
||||||
delta_sz.resize (ri_count);
|
delta_sz.resize (ri_count);
|
||||||
ri_map.resize (ri_count);
|
ri_map.resize (ri_count);
|
||||||
unsigned int new_short_count = 0;
|
unsigned int new_word_count = 0;
|
||||||
unsigned int r;
|
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++)
|
for (r = 0; r < ri_count; r++)
|
||||||
{
|
{
|
||||||
delta_sz[r] = kZero;
|
delta_sz[r] = kZero;
|
||||||
for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
|
for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
|
||||||
{
|
{
|
||||||
unsigned int old = inner_map.backward (i);
|
unsigned int old = inner_map.backward (i);
|
||||||
int16_t delta = src->get_item_delta (old, r);
|
int32_t delta = src->get_item_delta (old, r);
|
||||||
if (delta < -128 || 127 < delta)
|
if (delta < min_threshold || max_threshold < delta)
|
||||||
{
|
{
|
||||||
delta_sz[r] = kShort;
|
delta_sz[r] = kWord;
|
||||||
new_short_count++;
|
new_word_count++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (delta != 0)
|
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;
|
unsigned int new_ri_count = 0;
|
||||||
for (r = 0; r < ri_count; r++)
|
for (r = 0; r < ri_count; r++)
|
||||||
if (delta_sz[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++;
|
new_ri_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
shortCount = new_short_count;
|
wordSizeCount = new_word_count | (has_long ? 0x8000u /* LONG_WORDS */ : 0);
|
||||||
|
|
||||||
regionIndices.len = new_ri_count;
|
regionIndices.len = new_ri_count;
|
||||||
|
|
||||||
if (unlikely (!c->extend (this))) return_trace (false);
|
if (unlikely (!c->extend (this))) return_trace (false);
|
||||||
|
@ -2838,28 +2870,55 @@ struct VarData
|
||||||
HBUINT8 *get_delta_bytes ()
|
HBUINT8 *get_delta_bytes ()
|
||||||
{ return &StructAfter<HBUINT8> (regionIndices); }
|
{ return &StructAfter<HBUINT8> (regionIndices); }
|
||||||
|
|
||||||
int16_t get_item_delta (unsigned int item, unsigned int region) const
|
int32_t get_item_delta (unsigned int item, unsigned int region) const
|
||||||
{
|
{
|
||||||
if ( item >= itemCount || unlikely (region >= regionIndices.len)) return 0;
|
if ( item >= itemCount || unlikely (region >= regionIndices.len)) return 0;
|
||||||
const HBINT8 *p = (const HBINT8 *)get_delta_bytes () + item * get_row_size ();
|
const HBINT8 *p = (const HBINT8 *) get_delta_bytes () + item * get_row_size ();
|
||||||
if (region < shortCount)
|
unsigned word_count = wordCount ();
|
||||||
return ((const HBINT16 *)p)[region];
|
bool is_long = longWords ();
|
||||||
|
if (is_long)
|
||||||
|
{
|
||||||
|
if (region < word_count)
|
||||||
|
return ((const HBINT32 *) p)[region];
|
||||||
else
|
else
|
||||||
return (p + HBINT16::static_size * shortCount)[region - shortCount];
|
return ((const HBINT16 *)(p + HBINT32::static_size * word_count))[region - word_count];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (region < word_count)
|
||||||
|
return ((const HBINT16 *) p)[region];
|
||||||
|
else
|
||||||
|
return (p + HBINT16::static_size * word_count)[region - word_count];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_item_delta (unsigned int item, unsigned int region, int16_t delta)
|
void set_item_delta (unsigned int item, unsigned int region, int32_t delta)
|
||||||
{
|
{
|
||||||
HBINT8 *p = (HBINT8 *)get_delta_bytes () + item * get_row_size ();
|
HBINT8 *p = (HBINT8 *)get_delta_bytes () + item * get_row_size ();
|
||||||
if (region < shortCount)
|
unsigned word_count = wordCount ();
|
||||||
((HBINT16 *)p)[region] = delta;
|
bool is_long = longWords ();
|
||||||
|
if (is_long)
|
||||||
|
{
|
||||||
|
if (region < word_count)
|
||||||
|
((HBINT32 *) p)[region] = delta;
|
||||||
else
|
else
|
||||||
(p + HBINT16::static_size * shortCount)[region - shortCount] = delta;
|
((HBINT16 *)(p + HBINT32::static_size * word_count))[region - word_count] = delta;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (region < word_count)
|
||||||
|
((HBINT16 *) p)[region] = delta;
|
||||||
|
else
|
||||||
|
(p + HBINT16::static_size * word_count)[region - word_count] = delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool longWords () const { return wordSizeCount & 0x8000u /* LONG_WORDS */; }
|
||||||
|
unsigned wordCount () const { return wordSizeCount & 0x7FFFu /* WORD_DELTA_COUNT_MASK */; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 itemCount;
|
HBUINT16 itemCount;
|
||||||
HBUINT16 shortCount;
|
HBUINT16 wordSizeCount;
|
||||||
Array16Of<HBUINT16> regionIndices;
|
Array16Of<HBUINT16> regionIndices;
|
||||||
/*UnsizedArrayOf<HBUINT8>bytesX;*/
|
/*UnsizedArrayOf<HBUINT8>bytesX;*/
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in New Issue