[kern/kerx] Share KernTable, renamed to KerxTable

This commit is contained in:
Behdad Esfahbod 2018-11-07 13:40:22 -05:00
parent c038f5be6b
commit 14772da06f
2 changed files with 63 additions and 121 deletions

View File

@ -831,7 +831,7 @@ struct KerxSubTable
return_trace (dispatch (c)); return_trace (dispatch (c));
} }
protected: public:
union { union {
KerxSubTableHeader header; KerxSubTableHeader header;
KerxSubTableFormat0<KerxSubTableHeader> format0; KerxSubTableFormat0<KerxSubTableHeader> format0;
@ -840,7 +840,7 @@ protected:
KerxSubTableFormat4<KerxSubTableHeader> format4; KerxSubTableFormat4<KerxSubTableHeader> format4;
KerxSubTableFormat6<KerxSubTableHeader> format6; KerxSubTableFormat6<KerxSubTableHeader> format6;
} u; } u;
public: public:
DEFINE_SIZE_MIN (12); DEFINE_SIZE_MIN (12);
}; };
@ -849,33 +849,52 @@ public:
* The 'kerx' Table * The 'kerx' Table
*/ */
struct kerx template <typename T>
struct KerxTable
{ {
static const hb_tag_t tableTag = HB_AAT_TAG_kerx; /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
static const uint16_t minVersion = 2; inline const T* thiz (void) const { return static_cast<const T *> (this); }
typedef KerxSubTableHeader SubTableHeader; inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
typedef SubTableHeader::Types Types;
typedef KerxSubTable SubTable;
inline bool has_data (void) const { return version != 0; }
inline void apply (hb_aat_apply_context_t *c) const
{ {
typedef typename T::SubTable SubTable;
int v = 0;
const SubTable *st = &thiz()->firstSubTable;
unsigned int count = thiz()->tableCount;
for (unsigned int i = 0; i < count; i++)
{
if ((st->u.header.coverage & (st->u.header.Variation | st->u.header.CrossStream)) ||
!st->u.header.is_horizontal ())
continue;
v += st->get_kerning (left, right);
st = &StructAfter<SubTable> (*st);
}
return v;
}
inline void apply (AAT::hb_aat_apply_context_t *c) const
{
typedef typename T::SubTable SubTable;
c->set_lookup_index (0); c->set_lookup_index (0);
const SubTable *st = &firstSubTable; const SubTable *st = &thiz()->firstSubTable;
unsigned int count = tableCount; unsigned int count = thiz()->tableCount;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
{ {
bool reverse; bool reverse;
if (!T::Types::extended && (st->u.header.coverage & st->u.header.Variation))
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;
reverse = bool (st->u.header.coverage & st->u.header.Backwards) != 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); HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
if (!c->buffer->message (c->font, "start %c%c%c%c subtable %d", HB_UNTAG (tableTag), c->lookup_index)) 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) if (reverse)
@ -890,7 +909,7 @@ struct kerx
if (reverse) if (reverse)
c->buffer->reverse (); c->buffer->reverse ();
(void) c->buffer->message (c->font, "end %c%c%c%c subtable %d", HB_UNTAG (tableTag), c->lookup_index); (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);
@ -901,22 +920,38 @@ 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 (unlikely (!version.sanitize (c) || if (unlikely (!thiz()->version.sanitize (c) ||
version < minVersion || thiz()->version < T::minVersion ||
!tableCount.sanitize (c))) !thiz()->tableCount.sanitize (c)))
return_trace (false); return_trace (false);
const SubTable *st = &firstSubTable; typedef typename T::SubTable SubTable;
unsigned int count = tableCount;
const SubTable *st = &thiz()->firstSubTable;
unsigned int count = thiz()->tableCount;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
{ {
if (!st->sanitize (c)) if (unlikely (!st->sanitize (c)))
return_trace (false); return_trace (false);
st = &StructAfter<SubTable> (*st); st = &StructAfter<SubTable> (*st);
} }
return_trace (true); return_trace (true);
} }
};
struct kerx : KerxTable<kerx>
{
friend struct KerxTable<kerx>;
static const hb_tag_t tableTag = HB_AAT_TAG_kerx;
static const uint16_t minVersion = 2;
typedef KerxSubTableHeader SubTableHeader;
typedef SubTableHeader::Types Types;
typedef KerxSubTable SubTable;
inline bool has_data (void) const { return version; }
protected: protected:
HBUINT16 version; /* The version number of the extended kerning table HBUINT16 version; /* The version number of the extended kerning table

View File

@ -158,98 +158,6 @@ struct KernSubTable
}; };
template <typename T>
struct KernTable
{
/* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
inline const T* thiz (void) const { return static_cast<const T *> (this); }
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{
typedef typename T::SubTable SubTable;
int v = 0;
const SubTable *st = &thiz()->firstSubTable;
unsigned int count = thiz()->tableCount;
for (unsigned int i = 0; i < count; i++)
{
if ((st->u.header.coverage & (st->u.header.Variation | st->u.header.CrossStream)) ||
!st->u.header.is_horizontal ())
continue;
v += st->get_kerning (left, right);
st = &StructAfter<SubTable> (*st);
}
return v;
}
inline void apply (AAT::hb_aat_apply_context_t *c) const
{
typedef typename T::SubTable SubTable;
c->set_lookup_index (0);
const SubTable *st = &thiz()->firstSubTable;
unsigned int count = thiz()->tableCount;
for (unsigned int i = 0; i < count; i++)
{
bool reverse;
if (!T::Types::extended && (st->u.header.coverage & st->u.header.Variation))
goto skip;
if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->u.header.is_horizontal ())
goto skip;
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;
if (reverse)
c->buffer->reverse ();
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);
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:
st = &StructAfter<SubTable> (*st);
c->set_lookup_index (c->lookup_index + 1);
}
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (unlikely (!thiz()->version.sanitize (c) ||
thiz()->version < T::minVersion ||
!thiz()->tableCount.sanitize (c)))
return_trace (false);
typedef typename T::SubTable SubTable;
const SubTable *st = &thiz()->firstSubTable;
unsigned int count = thiz()->tableCount;
for (unsigned int i = 0; i < count; i++)
{
if (unlikely (!st->sanitize (c)))
return_trace (false);
st = &StructAfter<SubTable> (*st);
}
return_trace (true);
}
};
struct KernOTSubTableHeader struct KernOTSubTableHeader
{ {
static const bool apple = false; static const bool apple = false;
@ -285,9 +193,9 @@ struct KernOTSubTableHeader
DEFINE_SIZE_STATIC (6); DEFINE_SIZE_STATIC (6);
}; };
struct KernOT : KernTable<KernOT> struct KernOT : AAT::KerxTable<KernOT>
{ {
friend struct KernTable<KernOT>; friend struct AAT::KerxTable<KernOT>;
static const hb_tag_t tableTag = HB_OT_TAG_kern; static const hb_tag_t tableTag = HB_OT_TAG_kern;
static const uint16_t minVersion = 0; static const uint16_t minVersion = 0;
@ -340,9 +248,9 @@ struct KernAATSubTableHeader
DEFINE_SIZE_STATIC (8); DEFINE_SIZE_STATIC (8);
}; };
struct KernAAT : KernTable<KernAAT> struct KernAAT : AAT::KerxTable<KernAAT>
{ {
friend struct KernTable<KernAAT>; friend struct AAT::KerxTable<KernAAT>;
static const hb_tag_t tableTag = HB_OT_TAG_kern; static const hb_tag_t tableTag = HB_OT_TAG_kern;
static const uint32_t minVersion = 0x00010000u; static const uint32_t minVersion = 0x00010000u;
@ -363,8 +271,7 @@ struct kern
{ {
static const hb_tag_t tableTag = HB_OT_TAG_kern; static const hb_tag_t tableTag = HB_OT_TAG_kern;
inline bool has_data (void) const inline bool has_data (void) const { return u.version32; }
{ return u.version32 != 0; }
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{ {