[var] Implement DeltaSetIndexMap and advance delta fetching

Not hooked up to hb-ot-font yet.
This commit is contained in:
Behdad Esfahbod 2017-01-23 11:56:08 -08:00
parent 7b399f73ef
commit a4fca9f005
2 changed files with 61 additions and 3 deletions

View File

@ -1323,6 +1323,14 @@ struct VariationStore
this+regions);
}
inline float get_delta (unsigned int index,
int *coords, unsigned int coord_count) const
{
unsigned int outer = index >> 16;
unsigned int inner = index & 0xFFFF;
return get_delta (outer, inner, coords, coord_count);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);

View File

@ -39,12 +39,52 @@ struct DeltaSetIndexMap
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
c->check_array (this, 1, 12));
c->check_array (mapData, get_width (), mapCount));
}
USHORT x;
unsigned int map (unsigned int v) const /* Returns 16.16 outer.inner. */
{
/* If count is zero, pass value unchanged. This takes
* care of direct mapping for advance map. */
if (!mapCount)
return v;
if (v >= mapCount)
v = mapCount - 1;
unsigned int u = 0;
{ /* Fetch it. */
unsigned int w = get_width ();
const BYTE *p = mapData + w * v;
for (; w; w--)
u = (u << 8) + *p++;
}
{ /* Repack it. */
unsigned int n = get_inner_bitcount ();
unsigned int outer = u >> n;
unsigned int inner = u & ((1 << n) - 1);
u = (outer<<16) | inner;
}
return u;
}
protected:
inline bool get_width (void) const
{ return ((format >> 4) & 3) + 1; }
inline bool get_inner_bitcount (void) const
{ return (format & 0xF) + 1; }
protected:
USHORT format; /* A packed field that describes the compressed
* representation of delta-set indices. */
USHORT mapCount; /* The number of mapping entries. */
BYTE mapData[VAR]; /* The delta-set index mapping data. */
public:
DEFINE_SIZE_STATIC (2);
DEFINE_SIZE_ARRAY (4, mapData);
};
@ -72,6 +112,16 @@ struct HVARVVAR
rsbMap.sanitize (c, this));
}
inline float get_advance_delta (hb_codepoint_t glyph,
int *coords, unsigned int coord_count) const
{
unsigned int varidx = (this+advMap).map (glyph);
return (this+varStore).get_delta (varidx, coords, coord_count);
}
inline bool has_sidebearing_deltas (void) const
{ return lsbMap && rsbMap; }
protected:
FixedVersion<>version; /* Version of the metrics variation table
* initially set to 0x00010000u */