[kern/kerx] Share KernTable, renamed to KerxTable
This commit is contained in:
parent
c038f5be6b
commit
14772da06f
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue