[kern] Refactor to include header in each subtable type
This commit is contained in:
parent
b0da2cd0b9
commit
213fa3bf71
|
@ -155,6 +155,7 @@ struct KernPair
|
||||||
DEFINE_SIZE_STATIC (6);
|
DEFINE_SIZE_STATIC (6);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename KernSubTableHeader>
|
||||||
struct KernSubTableFormat0
|
struct KernSubTableFormat0
|
||||||
{
|
{
|
||||||
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
|
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
|
||||||
|
@ -186,11 +187,13 @@ struct KernSubTableFormat0
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BinSearchArrayOf<KernPair> pairs; /* Array of kerning pairs. */
|
KernSubTableHeader header;
|
||||||
|
BinSearchArrayOf<KernPair> pairs; /* Array of kerning pairs. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (8, pairs);
|
DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 8, pairs);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename KernSubTableHeader>
|
||||||
struct KernSubTableFormat1
|
struct KernSubTableFormat1
|
||||||
{
|
{
|
||||||
typedef void EntryData;
|
typedef void EntryData;
|
||||||
|
@ -309,10 +312,11 @@ struct KernSubTableFormat1
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
KernSubTableHeader header;
|
||||||
AAT::StateTable<AAT::MortTypes, EntryData> machine;
|
AAT::StateTable<AAT::MortTypes, EntryData> machine;
|
||||||
OffsetTo<UnsizedArrayOf<FWORD>, HBUINT16, false> kernAction;
|
OffsetTo<UnsizedArrayOf<FWORD>, HBUINT16, false> kernAction;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (10);
|
DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 10);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct KernClassTable
|
struct KernClassTable
|
||||||
|
@ -333,6 +337,7 @@ struct KernClassTable
|
||||||
DEFINE_SIZE_ARRAY (4, classes);
|
DEFINE_SIZE_ARRAY (4, classes);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename KernSubTableHeader>
|
||||||
struct KernSubTableFormat2
|
struct KernSubTableFormat2
|
||||||
{
|
{
|
||||||
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
|
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
|
||||||
|
@ -393,20 +398,19 @@ struct KernSubTableFormat2
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 rowWidth; /* The width, in bytes, of a row in the table. */
|
KernSubTableHeader header;
|
||||||
OffsetTo<KernClassTable>
|
HBUINT16 rowWidth; /* The width, in bytes, of a row in the table. */
|
||||||
leftClassTable; /* Offset from beginning of this subtable to
|
OffsetTo<KernClassTable> leftClassTable; /* Offset from beginning of this subtable to
|
||||||
* left-hand class table. */
|
* left-hand class table. */
|
||||||
OffsetTo<KernClassTable>
|
OffsetTo<KernClassTable> rightClassTable;/* Offset from beginning of this subtable to
|
||||||
rightClassTable;/* Offset from beginning of this subtable to
|
* right-hand class table. */
|
||||||
* right-hand class table. */
|
OffsetTo<FWORD> array; /* Offset from beginning of this subtable to
|
||||||
OffsetTo<FWORD>
|
* the start of the kerning array. */
|
||||||
array; /* Offset from beginning of this subtable to
|
|
||||||
* the start of the kerning array. */
|
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_MIN (8);
|
DEFINE_SIZE_MIN (KernSubTableHeader::static_size + 8);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename KernSubTableHeader>
|
||||||
struct KernSubTableFormat3
|
struct KernSubTableFormat3
|
||||||
{
|
{
|
||||||
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
|
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
|
||||||
|
@ -448,44 +452,52 @@ struct KernSubTableFormat3
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 glyphCount; /* The number of glyphs in this font. */
|
KernSubTableHeader header;
|
||||||
HBUINT8 kernValueCount; /* The number of kerning values. */
|
HBUINT16 glyphCount; /* The number of glyphs in this font. */
|
||||||
HBUINT8 leftClassCount; /* The number of left-hand classes. */
|
HBUINT8 kernValueCount; /* The number of kerning values. */
|
||||||
HBUINT8 rightClassCount;/* The number of right-hand classes. */
|
HBUINT8 leftClassCount; /* The number of left-hand classes. */
|
||||||
HBUINT8 flags; /* Set to zero (reserved for future use). */
|
HBUINT8 rightClassCount;/* The number of right-hand classes. */
|
||||||
UnsizedArrayOf<FWORD>
|
HBUINT8 flags; /* Set to zero (reserved for future use). */
|
||||||
kernValueZ; /* The kerning values.
|
UnsizedArrayOf<FWORD> kernValueZ; /* The kerning values.
|
||||||
* Length kernValueCount. */
|
* Length kernValueCount. */
|
||||||
#if 0
|
#if 0
|
||||||
UnsizedArrayOf<HBUINT8>
|
UnsizedArrayOf<HBUINT8>leftClass; /* The left-hand classes.
|
||||||
leftClass; /* The left-hand classes.
|
* Length glyphCount. */
|
||||||
* Length glyphCount. */
|
UnsizedArrayOf<HBUINT8>rightClass; /* The right-hand classes.
|
||||||
UnsizedArrayOf<HBUINT8>
|
* Length glyphCount. */
|
||||||
RightClass; /* The right-hand classes.
|
UnsizedArrayOf<HBUINT8>kernIndex; /* The indices into the kernValue array.
|
||||||
* Length glyphCount. */
|
* Length leftClassCount * rightClassCount */
|
||||||
UnsizedArrayOf<HBUINT8>
|
|
||||||
kernIndex; /* The indices into the kernValue array.
|
|
||||||
* Length leftClassCount * rightClassCount */
|
|
||||||
#endif
|
#endif
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (6, kernValueZ);
|
DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 6, kernValueZ);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename KernSubTableHeader>
|
||||||
struct KernSubTable
|
struct KernSubTable
|
||||||
{
|
{
|
||||||
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int format) const
|
inline unsigned int get_size (void) const { return u.header.length; }
|
||||||
|
|
||||||
|
inline bool is_simple (void) const
|
||||||
|
{ return !(u.header.coverage & (u.header.CrossStream | u.header.Variation)); }
|
||||||
|
|
||||||
|
inline bool is_horizontal (void) const
|
||||||
|
{ return (u.header.coverage & u.header.Direction) == u.header.DirectionHorizontal; }
|
||||||
|
|
||||||
|
inline bool is_override (void) const
|
||||||
|
{ return bool (u.header.coverage & u.header.Override); }
|
||||||
|
|
||||||
|
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
|
||||||
{
|
{
|
||||||
switch (format) {
|
switch (u.header.format) {
|
||||||
/* This method hooks up to hb_font_t's get_h_kerning. Only support Format0. */
|
/* This method hooks up to hb_font_t's get_h_kerning. Only support Format0. */
|
||||||
case 0: return u.format0.get_kerning (left, right);
|
case 0: return u.format0.get_kerning (left, right);
|
||||||
default:return 0;
|
default:return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void apply (AAT::hb_aat_apply_context_t *c, unsigned int format) const
|
inline void apply (AAT::hb_aat_apply_context_t *c) const
|
||||||
{
|
{
|
||||||
/* TODO Switch to dispatch(). */
|
switch (u.header.format) {
|
||||||
switch (format) {
|
|
||||||
case 0: u.format0.apply (c); return;
|
case 0: u.format0.apply (c); return;
|
||||||
case 1: u.format1.apply (c); return;
|
case 1: u.format1.apply (c); return;
|
||||||
case 2: u.format2.apply (c); return;
|
case 2: u.format2.apply (c); return;
|
||||||
|
@ -494,10 +506,13 @@ struct KernSubTable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, unsigned int format) const
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
switch (format) {
|
if (unlikely (!u.header.sanitize (c) ||
|
||||||
|
u.header.length < u.header.min_size ||
|
||||||
|
!c->check_range (this, u.header.length))) return_trace (false);
|
||||||
|
switch (u.header.format) {
|
||||||
case 0: return_trace (u.format0.sanitize (c));
|
case 0: return_trace (u.format0.sanitize (c));
|
||||||
case 1: return_trace (u.format1.sanitize (c));
|
case 1: return_trace (u.format1.sanitize (c));
|
||||||
case 2: return_trace (u.format2.sanitize (c));
|
case 2: return_trace (u.format2.sanitize (c));
|
||||||
|
@ -508,49 +523,17 @@ struct KernSubTable
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
KernSubTableFormat0 format0;
|
KernSubTableHeader header;
|
||||||
KernSubTableFormat1 format1;
|
KernSubTableFormat0<KernSubTableHeader> format0;
|
||||||
KernSubTableFormat2 format2;
|
KernSubTableFormat1<KernSubTableHeader> format1;
|
||||||
KernSubTableFormat3 format3;
|
KernSubTableFormat2<KernSubTableHeader> format2;
|
||||||
|
KernSubTableFormat3<KernSubTableHeader> format3;
|
||||||
} u;
|
} u;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_MIN (0);
|
DEFINE_SIZE_MIN (0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct KernSubTableWrapper
|
|
||||||
{
|
|
||||||
/* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
|
|
||||||
inline const T* thiz (void) const { return static_cast<const T *> (this); }
|
|
||||||
|
|
||||||
inline bool is_simple (void) const
|
|
||||||
{ return !(thiz()->coverage & (T::CrossStream | T::Variation)); }
|
|
||||||
|
|
||||||
inline bool is_horizontal (void) const
|
|
||||||
{ return (thiz()->coverage & T::Direction) == T::DirectionHorizontal; }
|
|
||||||
|
|
||||||
inline bool is_override (void) const
|
|
||||||
{ return bool (thiz()->coverage & T::Override); }
|
|
||||||
|
|
||||||
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
|
|
||||||
{ return thiz()->subtable.get_kerning (left, right, thiz()->format); }
|
|
||||||
|
|
||||||
inline void apply (AAT::hb_aat_apply_context_t *c) const
|
|
||||||
{ thiz()->subtable.apply (c, thiz()->format); }
|
|
||||||
|
|
||||||
inline unsigned int get_size (void) const { return thiz()->length; }
|
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
|
||||||
{
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
return_trace (c->check_struct (thiz()) &&
|
|
||||||
thiz()->length >= T::min_size &&
|
|
||||||
c->check_range (thiz(), thiz()->length) &&
|
|
||||||
thiz()->subtable.sanitize (c, thiz()->format));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct KernTable
|
struct KernTable
|
||||||
{
|
{
|
||||||
|
@ -559,8 +542,10 @@ struct KernTable
|
||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
|
typedef KernSubTable<typename T::SubTableHeader> SubTable;
|
||||||
|
|
||||||
int v = 0;
|
int v = 0;
|
||||||
const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
|
const SubTable *st = CastP<SubTable> (&thiz()->dataZ);
|
||||||
unsigned int count = thiz()->nTables;
|
unsigned int count = thiz()->nTables;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
|
@ -569,15 +554,17 @@ struct KernTable
|
||||||
if (st->is_override ())
|
if (st->is_override ())
|
||||||
v = 0;
|
v = 0;
|
||||||
v += st->get_kerning (left, right);
|
v += st->get_kerning (left, right);
|
||||||
st = &StructAfter<typename T::SubTableWrapper> (*st);
|
st = &StructAfter<SubTable> (*st);
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void apply (AAT::hb_aat_apply_context_t *c) const
|
inline void apply (AAT::hb_aat_apply_context_t *c) const
|
||||||
{
|
{
|
||||||
|
typedef KernSubTable<typename T::SubTableHeader> SubTable;
|
||||||
|
|
||||||
c->set_lookup_index (0);
|
c->set_lookup_index (0);
|
||||||
const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
|
const SubTable *st = CastP<SubTable> (&thiz()->dataZ);
|
||||||
unsigned int count = thiz()->nTables;
|
unsigned int count = thiz()->nTables;
|
||||||
/* If there's an override subtable, skip subtables before that. */
|
/* If there's an override subtable, skip subtables before that. */
|
||||||
unsigned int last_override = 0;
|
unsigned int last_override = 0;
|
||||||
|
@ -585,9 +572,9 @@ struct KernTable
|
||||||
{
|
{
|
||||||
if (st->is_simple () && st->is_override ())
|
if (st->is_simple () && st->is_override ())
|
||||||
last_override = i;
|
last_override = i;
|
||||||
st = &StructAfter<typename T::SubTableWrapper> (*st);
|
st = &StructAfter<SubTable> (*st);
|
||||||
}
|
}
|
||||||
st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
|
st = CastP<SubTable> (&thiz()->dataZ);
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (!st->is_simple ())
|
if (!st->is_simple ())
|
||||||
|
@ -609,7 +596,7 @@ struct KernTable
|
||||||
(void) c->buffer->message (c->font, "end kern subtable %d", c->lookup_index);
|
(void) c->buffer->message (c->font, "end kern subtable %d", c->lookup_index);
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
st = &StructAfter<typename T::SubTableWrapper> (*st);
|
st = &StructAfter<SubTable> (*st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,13 +607,15 @@ struct KernTable
|
||||||
thiz()->version != T::VERSION))
|
thiz()->version != T::VERSION))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
|
|
||||||
const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
|
typedef KernSubTable<typename T::SubTableHeader> SubTable;
|
||||||
|
|
||||||
|
const SubTable *st = CastP<SubTable> (&thiz()->dataZ);
|
||||||
unsigned int count = thiz()->nTables;
|
unsigned int count = thiz()->nTables;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (unlikely (!st->sanitize (c)))
|
if (unlikely (!st->sanitize (c)))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
st = &StructAfter<typename T::SubTableWrapper> (*st);
|
st = &StructAfter<SubTable> (*st);
|
||||||
}
|
}
|
||||||
|
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
|
@ -639,11 +628,8 @@ struct KernOT : KernTable<KernOT>
|
||||||
|
|
||||||
static const uint16_t VERSION = 0x0000u;
|
static const uint16_t VERSION = 0x0000u;
|
||||||
|
|
||||||
struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
|
struct SubTableHeader
|
||||||
{
|
{
|
||||||
friend struct KernTable<KernOT>;
|
|
||||||
friend struct KernSubTableWrapper<SubTableWrapper>;
|
|
||||||
|
|
||||||
enum Coverage
|
enum Coverage
|
||||||
{
|
{
|
||||||
Direction = 0x01u,
|
Direction = 0x01u,
|
||||||
|
@ -656,14 +642,19 @@ struct KernOT : KernTable<KernOT>
|
||||||
DirectionHorizontal= 0x01u
|
DirectionHorizontal= 0x01u
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
return_trace (c->check_struct (this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
HBUINT16 versionZ; /* Unused. */
|
HBUINT16 versionZ; /* Unused. */
|
||||||
HBUINT16 length; /* Length of the subtable (including this header). */
|
HBUINT16 length; /* Length of the subtable (including this header). */
|
||||||
HBUINT8 format; /* Subtable format. */
|
HBUINT8 format; /* Subtable format. */
|
||||||
HBUINT8 coverage; /* Coverage bits. */
|
HBUINT8 coverage; /* Coverage bits. */
|
||||||
KernSubTable subtable; /* Subtable data. */
|
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_MIN (6);
|
DEFINE_SIZE_STATIC (6);
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -680,11 +671,8 @@ struct KernAAT : KernTable<KernAAT>
|
||||||
|
|
||||||
static const uint32_t VERSION = 0x00010000u;
|
static const uint32_t VERSION = 0x00010000u;
|
||||||
|
|
||||||
struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
|
struct SubTableHeader
|
||||||
{
|
{
|
||||||
friend struct KernTable<KernAAT>;
|
|
||||||
friend struct KernSubTableWrapper<SubTableWrapper>;
|
|
||||||
|
|
||||||
enum Coverage
|
enum Coverage
|
||||||
{
|
{
|
||||||
Direction = 0x80u,
|
Direction = 0x80u,
|
||||||
|
@ -696,15 +684,20 @@ struct KernAAT : KernTable<KernAAT>
|
||||||
DirectionHorizontal= 0x00u
|
DirectionHorizontal= 0x00u
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
return_trace (c->check_struct (this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
HBUINT32 length; /* Length of the subtable (including this header). */
|
HBUINT32 length; /* Length of the subtable (including this header). */
|
||||||
HBUINT8 coverage; /* Coverage bits. */
|
HBUINT8 coverage; /* Coverage bits. */
|
||||||
HBUINT8 format; /* Subtable format. */
|
HBUINT8 format; /* Subtable format. */
|
||||||
HBUINT16 tupleIndex; /* The tuple index (used for variations fonts).
|
HBUINT16 tupleIndex; /* The tuple index (used for variations fonts).
|
||||||
* This value specifies which tuple this subtable covers. */
|
* This value specifies which tuple this subtable covers. */
|
||||||
KernSubTable subtable; /* Subtable data. */
|
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_MIN (8);
|
DEFINE_SIZE_STATIC (8);
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Reference in New Issue