[kern/kerx] More towards sharing KernTable

This commit is contained in:
Behdad Esfahbod 2018-11-07 13:33:23 -05:00
parent 89ec095979
commit db6e658e8c
2 changed files with 69 additions and 42 deletions

View File

@ -773,16 +773,16 @@ struct KerxSubTableHeader
enum Coverage enum Coverage
{ {
Vertical = 0x80000000, /* Set if table has vertical kerning values. */ Vertical = 0x80000000u, /* Set if table has vertical kerning values. */
CrossStream = 0x40000000, /* Set if table has cross-stream kerning values. */ CrossStream = 0x40000000u, /* Set if table has cross-stream kerning values. */
Variation = 0x20000000, /* Set if table has variation kerning values. */ Variation = 0x20000000u, /* Set if table has variation kerning values. */
Backwards = 0x10000000, /* If clear, process the glyphs forwards, that Backwards = 0x10000000u, /* If clear, process the glyphs forwards, that
* is, from first to last in the glyph stream. * is, from first to last in the glyph stream.
* If we, process them from last to first. * If we, process them from last to first.
* This flag only applies to state-table based * This flag only applies to state-table based
* 'kerx' subtables (types 1 and 4). */ * 'kerx' subtables (types 1 and 4). */
Reserved = 0x0FFFFF00, /* Reserved, set to zero. */ Reserved = 0x0FFFFF00u, /* Reserved, set to zero. */
SubtableType = 0x000000FF, /* Subtable type. */ SubtableType= 0x000000FFu, /* Subtable type. */
}; };
inline bool sanitize (hb_sanitize_context_t *c) const inline bool sanitize (hb_sanitize_context_t *c) const
@ -854,12 +854,16 @@ struct kerx
static const hb_tag_t tableTag = HB_AAT_TAG_kerx; static const hb_tag_t tableTag = HB_AAT_TAG_kerx;
static const uint16_t minVersion = 2; static const uint16_t minVersion = 2;
typedef KerxSubTableHeader SubTableHeader;
typedef SubTableHeader::Types Types;
typedef KerxSubTable SubTable;
inline bool has_data (void) const { return version != 0; } inline bool has_data (void) const { return version != 0; }
inline void apply (hb_aat_apply_context_t *c) const inline void apply (hb_aat_apply_context_t *c) const
{ {
c->set_lookup_index (0); c->set_lookup_index (0);
const KerxSubTable *st = &firstSubTable; const SubTable *st = &firstSubTable;
unsigned int count = tableCount; unsigned int count = tableCount;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
{ {
@ -871,7 +875,7 @@ struct kerx
reverse = bool (st->u.header.coverage & st->u.header.Backwards) != reverse = bool (st->u.header.coverage & st->u.header.Backwards) !=
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
if (!c->buffer->message (c->font, "start kerx subtable %d", c->lookup_index)) if (!c->buffer->message (c->font, "start %c%c%c%c subtable %d", HB_UNTAG (tableTag), c->lookup_index))
goto skip; goto skip;
if (reverse) if (reverse)
@ -879,19 +883,17 @@ struct kerx
c->sanitizer.set_object (*st); c->sanitizer.set_object (*st);
/* XXX Reverse-kern is not working yet... /* XXX Reverse-kern is probably not working yet...
* hb_kern_machine_t would need to know that it's reverse-kerning. * hb_kern_machine_t would need to know that it's reverse-kerning. */
* Or better yet, make it work in reverse as well, so we don't have
* to reverse and reverse back? */
st->dispatch (c); st->dispatch (c);
if (reverse) if (reverse)
c->buffer->reverse (); c->buffer->reverse ();
(void) c->buffer->message (c->font, "end kerx subtable %d", c->lookup_index); (void) c->buffer->message (c->font, "end %c%c%c%c subtable %d", HB_UNTAG (tableTag), c->lookup_index);
skip: skip:
st = &StructAfter<KerxSubTable> (*st); st = &StructAfter<SubTable> (*st);
c->set_lookup_index (c->lookup_index + 1); c->set_lookup_index (c->lookup_index + 1);
} }
} }
@ -899,16 +901,18 @@ struct kerx
inline bool sanitize (hb_sanitize_context_t *c) const inline bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (!version.sanitize (c) || version < minVersion || !tableCount.sanitize (c)) if (unlikely (!version.sanitize (c) ||
version < minVersion ||
!tableCount.sanitize (c)))
return_trace (false); return_trace (false);
const KerxSubTable *st = &firstSubTable; const SubTable *st = &firstSubTable;
unsigned int count = tableCount; unsigned int count = tableCount;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
{ {
if (!st->sanitize (c)) if (!st->sanitize (c))
return_trace (false); return_trace (false);
st = &StructAfter<KerxSubTable> (*st); st = &StructAfter<SubTable> (*st);
} }
return_trace (true); return_trace (true);
@ -920,7 +924,7 @@ struct kerx
HBUINT16 unused; /* Set to 0. */ HBUINT16 unused; /* Set to 0. */
HBUINT32 tableCount; /* The number of subtables included in the extended kerning HBUINT32 tableCount; /* The number of subtables included in the extended kerning
* table. */ * table. */
KerxSubTable firstSubTable; /* Subtables. */ SubTable firstSubTable; /* Subtables. */
/*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */ /*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */
public: public:

View File

@ -191,20 +191,34 @@ struct KernTable
unsigned int count = thiz()->tableCount; unsigned int count = thiz()->tableCount;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
{ {
if (st->u.header.coverage & st->u.header.Variation) bool reverse;
if (!T::Types::extended && (st->u.header.coverage & st->u.header.Variation))
goto skip; goto skip;
if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->u.header.is_horizontal ()) if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->u.header.is_horizontal ())
goto skip; goto skip;
if (!c->buffer->message (c->font, "start kern subtable %d", c->lookup_index)) reverse = T::Types::extended /* TODO remove after kern application is moved earlier. */ &&
bool (st->u.header.coverage & st->u.header.Backwards) !=
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
if (!c->buffer->message (c->font, "start %c%c%c%c subtable %d", HB_UNTAG (thiz()->tableTag), c->lookup_index))
goto skip; goto skip;
if (reverse)
c->buffer->reverse ();
c->sanitizer.set_object (*st); c->sanitizer.set_object (*st);
/* XXX Reverse-kern is probably not working yet...
* hb_kern_machine_t would need to know that it's reverse-kerning. */
st->dispatch (c); st->dispatch (c);
(void) c->buffer->message (c->font, "end kern subtable %d", c->lookup_index); if (reverse)
c->buffer->reverse ();
(void) c->buffer->message (c->font, "end %c%c%c%c subtable %d", HB_UNTAG (thiz()->tableTag), c->lookup_index);
skip: skip:
st = &StructAfter<SubTable> (*st); st = &StructAfter<SubTable> (*st);
@ -247,11 +261,13 @@ struct KernOTSubTableHeader
enum Coverage enum Coverage
{ {
Horizontal = 0x01u, Horizontal = 0x01u,
Minimum = 0x02u, Minimum = 0x02u,
CrossStream = 0x04u, CrossStream = 0x04u,
Override = 0x08u, Override = 0x08u,
Variation = 0x00u, /* Not supported. */ /* Not supported: */
Backwards = 0x00u,
Variation = 0x00u,
}; };
inline bool sanitize (hb_sanitize_context_t *c) const inline bool sanitize (hb_sanitize_context_t *c) const
@ -273,15 +289,17 @@ struct KernOT : KernTable<KernOT>
{ {
friend struct KernTable<KernOT>; friend struct KernTable<KernOT>;
typedef KernOTSubTableHeader SubTableHeader; static const hb_tag_t tableTag = HB_OT_TAG_kern;
typedef KernSubTable<SubTableHeader> SubTable;
static const uint16_t minVersion = 0; static const uint16_t minVersion = 0;
typedef KernOTSubTableHeader SubTableHeader;
typedef SubTableHeader::Types Types;
typedef KernSubTable<SubTableHeader> SubTable;
protected: protected:
HBUINT16 version; /* Version--0x0000u */ HBUINT16 version; /* Version--0x0000u */
HBUINT16 tableCount; /* Number of subtables in the kerning table. */ HBUINT16 tableCount; /* Number of subtables in the kerning table. */
KernSubTable<SubTableHeader> firstSubTable; /* Subtables. */ SubTable firstSubTable; /* Subtables. */
public: public:
DEFINE_SIZE_MIN (4); DEFINE_SIZE_MIN (4);
}; };
@ -297,9 +315,12 @@ struct KernAATSubTableHeader
enum Coverage enum Coverage
{ {
Vertical = 0x80u, Vertical = 0x80u,
CrossStream = 0x40u, CrossStream = 0x40u,
Variation = 0x20u, Variation = 0x20u,
/* Not supported: */
Backwards = 0x00u,
}; };
inline bool sanitize (hb_sanitize_context_t *c) const inline bool sanitize (hb_sanitize_context_t *c) const
@ -323,15 +344,17 @@ struct KernAAT : KernTable<KernAAT>
{ {
friend struct KernTable<KernAAT>; friend struct KernTable<KernAAT>;
typedef KernAATSubTableHeader SubTableHeader; static const hb_tag_t tableTag = HB_OT_TAG_kern;
typedef KernSubTable<SubTableHeader> SubTable;
static const uint32_t minVersion = 0x00010000u; static const uint32_t minVersion = 0x00010000u;
typedef KernAATSubTableHeader SubTableHeader;
typedef SubTableHeader::Types Types;
typedef KernSubTable<SubTableHeader> SubTable;
protected: protected:
HBUINT32 version; /* Version--0x00010000u */ HBUINT32 version; /* Version--0x00010000u */
HBUINT32 tableCount; /* Number of subtables in the kerning table. */ HBUINT32 tableCount; /* Number of subtables in the kerning table. */
KernSubTable<SubTableHeader> firstSubTable; /* Subtables. */ SubTable firstSubTable; /* Subtables. */
public: public:
DEFINE_SIZE_MIN (8); DEFINE_SIZE_MIN (8);
}; };