[kerx] Implement variation-kerning tables (without the variation part)
SFSNDisplay uses these. We just apply the default kern without variations right now. But at least makes the default kern work.
This commit is contained in:
parent
f7c0b4319c
commit
29d877518f
|
@ -45,6 +45,21 @@ namespace AAT {
|
||||||
using namespace OT;
|
using namespace OT;
|
||||||
|
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
kerxTupleKern (int value,
|
||||||
|
unsigned int tupleCount,
|
||||||
|
const void *base,
|
||||||
|
hb_aat_apply_context_t *c)
|
||||||
|
{
|
||||||
|
if (likely (!tupleCount)) return value;
|
||||||
|
|
||||||
|
unsigned int offset = value;
|
||||||
|
const FWORD *pv = &StructAtOffset<FWORD> (base, offset);
|
||||||
|
if (unlikely (!pv->sanitize (&c->sanitizer))) return 0;
|
||||||
|
return *pv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct KerxSubTableHeader
|
struct KerxSubTableHeader
|
||||||
{
|
{
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
@ -65,6 +80,7 @@ struct KerxSubTableFormat0
|
||||||
{
|
{
|
||||||
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
|
||||||
{
|
{
|
||||||
|
if (header.tupleCount) return 0; /* TODO kerxTupleKern */
|
||||||
hb_glyph_pair_t pair = {left, right};
|
hb_glyph_pair_t pair = {left, right};
|
||||||
int i = pairs.bsearch (pair);
|
int i = pairs.bsearch (pair);
|
||||||
return i == -1 ? 0 : pairs[i].get_kerning ();
|
return i == -1 ? 0 : pairs[i].get_kerning ();
|
||||||
|
@ -201,6 +217,9 @@ struct KerxSubTableFormat1
|
||||||
if (!c->plan->requested_kerning)
|
if (!c->plan->requested_kerning)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (header.tupleCount)
|
||||||
|
return_trace (false); /* TODO kerxTupleKern */
|
||||||
|
|
||||||
driver_context_t dc (this, c);
|
driver_context_t dc (this, c);
|
||||||
|
|
||||||
StateTableDriver<EntryData> driver (machine, c->buffer, c->font->face);
|
StateTableDriver<EntryData> driver (machine, c->buffer, c->font->face);
|
||||||
|
@ -236,7 +255,7 @@ struct KerxSubTableFormat2
|
||||||
unsigned int offset = l + r;
|
unsigned int offset = l + r;
|
||||||
const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
|
const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
|
||||||
if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
|
if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
|
||||||
return *v;
|
return kerxTupleKern (*v, header.tupleCount, this, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool apply (hb_aat_apply_context_t *c) const
|
inline bool apply (hb_aat_apply_context_t *c) const
|
||||||
|
@ -482,7 +501,7 @@ struct KerxSubTableFormat6
|
||||||
if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0;
|
if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0;
|
||||||
const FWORD32 *v = &StructAtOffset<FWORD32> (&(this+t.array), offset * sizeof (FWORD32));
|
const FWORD32 *v = &StructAtOffset<FWORD32> (&(this+t.array), offset * sizeof (FWORD32));
|
||||||
if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
|
if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
|
||||||
return *v;
|
return kerxTupleKern (*v, header.tupleCount, &(this+vector), c);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -492,7 +511,7 @@ struct KerxSubTableFormat6
|
||||||
unsigned int offset = l + r;
|
unsigned int offset = l + r;
|
||||||
const FWORD *v = &StructAtOffset<FWORD> (&(this+t.array), offset * sizeof (FWORD));
|
const FWORD *v = &StructAtOffset<FWORD> (&(this+t.array), offset * sizeof (FWORD));
|
||||||
if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
|
if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
|
||||||
return *v;
|
return kerxTupleKern (*v, header.tupleCount, &(this+vector), c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,7 +542,9 @@ struct KerxSubTableFormat6
|
||||||
u.s.rowIndexTable.sanitize (c, this) &&
|
u.s.rowIndexTable.sanitize (c, this) &&
|
||||||
u.s.columnIndexTable.sanitize (c, this) &&
|
u.s.columnIndexTable.sanitize (c, this) &&
|
||||||
c->check_range (this, u.s.array)
|
c->check_range (this, u.s.array)
|
||||||
))));
|
)) &&
|
||||||
|
(header.tupleCount == 0 ||
|
||||||
|
c->check_range (this, vector))));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct accelerator_t
|
struct accelerator_t
|
||||||
|
@ -559,8 +580,9 @@ struct KerxSubTableFormat6
|
||||||
LOffsetTo<UnsizedArrayOf<FWORD>, false> array;
|
LOffsetTo<UnsizedArrayOf<FWORD>, false> array;
|
||||||
} s;
|
} s;
|
||||||
} u;
|
} u;
|
||||||
|
LOffsetTo<UnsizedArrayOf<FWORD>, false> vector;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (32);
|
DEFINE_SIZE_STATIC (36);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct KerxTable
|
struct KerxTable
|
||||||
|
@ -642,9 +664,8 @@ struct kerx
|
||||||
{
|
{
|
||||||
bool reverse;
|
bool reverse;
|
||||||
|
|
||||||
if (table->u.header.coverage & (KerxTable::CrossStream | KerxTable::Variation) ||
|
if (table->u.header.coverage & (KerxTable::CrossStream))
|
||||||
table->u.header.tupleCount)
|
goto skip; /* We do NOT handle cross-stream. */
|
||||||
goto skip; /* We do NOT handle cross-stream or variation kerning. */
|
|
||||||
|
|
||||||
if (HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
|
if (HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
|
||||||
bool (table->u.header.coverage & KerxTable::Vertical))
|
bool (table->u.header.coverage & KerxTable::Vertical))
|
||||||
|
|
Loading…
Reference in New Issue