[HarfBuzz] harfbuzz: Branch 'master' - 6 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Thu Oct 11 01:49:49 UTC 2018
src/hb-aat-layout-kerx-table.hh | 128 +++++++++++++++++++++++++++++++++-------
src/hb-aat-layout-morx-table.hh | 4 -
src/hb-ot-shape.cc | 50 ++++++++-------
3 files changed, 136 insertions(+), 46 deletions(-)
New commits:
commit 9f450f07b0a1593962e3b45d00f2cf93916f3466
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Oct 10 21:46:58 2018 -0400
[kerx] Make Format1 work
Tested using Kannada MN:
$ HB_OPTIONS=aat ./hb-shape Kannada\ MN.ttc -u 0C95,0CCd,C95,CCD
[kn_ka.virama=0+1299|kn_ka.vattu=0+115|_blank=0 at -115,0+385]
$ HB_OPTIONS=aat ./hb-shape Kannada\ MN.ttc -u 0C95,0CCd,C95,CCD --features=-kern
[kn_ka.virama=0+1799|kn_ka.vattu=0+230|_blank=0+0]
I don't see the GPOS table in the font do the same. ¯\_(ツ)_/¯
diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index 552bb065..cc99868d 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -123,7 +123,7 @@ struct KerxSubTableFormat1
inline driver_context_t (const KerxSubTableFormat1 *table,
hb_aat_apply_context_t *c_) :
c (c_),
- kernAction (table+table->kernAction),
+ kernAction (&table->machine + table->kernAction),
depth (0) {}
inline bool is_actionable (StateTableDriver<EntryData> *driver,
@@ -159,16 +159,21 @@ struct KerxSubTableFormat1
return false;
}
- for (; depth; depth--)
+ for (unsigned int i = 0; i < depth; i++)
{
- unsigned int idx = stack[depth - 1];
+ /* Apparently, when spec says "Each pops one glyph from the kerning stack
+ * and applies the kerning value to it.", it doesn't mean it in that order.
+ * The deepest item in the stack corresponds to the first item in the action
+ * list. Discovered by testing. */
+ unsigned int idx = stack[i];
int v = *actions++;
/* XXX Non-forward direction... */
if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
- buffer->pos[idx].x_advance += v;
+ buffer->pos[idx].x_advance += c->font->em_scale_x (v);
else
- buffer->pos[idx].y_advance += v;
+ buffer->pos[idx].y_advance += c->font->em_scale_y (v);
}
+ depth = 0;
}
return true;
commit 504cb68fc972c7f606bf9fc62015376382f78f45
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Oct 10 21:29:46 2018 -0400
Disable mark advance zeroing as well as mark fallback positioning if doing kerx
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 3b1c93db..e2405237 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -114,7 +114,7 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
}
plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
- if (!plan.apply_gpos)
+ if (!plan.apply_gpos && !plan.apply_kerx)
plan.fallback_mark_positioning = true;
}
@@ -820,34 +820,36 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c)
hb_ot_layout_position_start (c->font, c->buffer);
- switch (c->plan->shaper->zero_width_marks)
- {
- case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
- zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
- break;
-
- default:
- case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
- case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
- break;
- }
+ if (!c->plan->apply_kerx)
+ switch (c->plan->shaper->zero_width_marks)
+ {
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
+ zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
+ break;
+
+ default:
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
+ break;
+ }
if (c->plan->apply_gpos)
- c->plan->position (c->font, c->buffer);
+ ;//c->plan->position (c->font, c->buffer);
else if (c->plan->apply_kerx)
hb_aat_layout_position (c->plan, c->font, c->buffer);
- switch (c->plan->shaper->zero_width_marks)
- {
- case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
- zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
- break;
-
- default:
- case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
- case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
- break;
- }
+ if (!c->plan->apply_kerx)
+ switch (c->plan->shaper->zero_width_marks)
+ {
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
+ zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
+ break;
+
+ default:
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
+ break;
+ }
/* Finishing off GPOS has to follow a certain order. */
hb_ot_layout_position_finish_advances (c->font, c->buffer);
commit 84967537966a76297c89460d95e7336f1bfc332d
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Oct 10 21:18:37 2018 -0400
[kerx] Implement Format1
Untested.
diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index edc17a39..552bb065 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -101,9 +101,9 @@ struct KerxSubTableFormat1
{
struct EntryData
{
- HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry
- * for processing this group, if indicated
- * by the flags. */
+ HBUINT16 kernActionIndex;/* Index into the kerning value array. If
+ * this index is 0xFFFF, then no kerning
+ * is to be performed. */
public:
DEFINE_SIZE_STATIC (2);
};
@@ -120,25 +120,65 @@ struct KerxSubTableFormat1
Reserved = 0x1FFF, /* Not used; set to 0. */
};
- inline driver_context_t (const KerxSubTableFormat1 *table)
- {}
+ inline driver_context_t (const KerxSubTableFormat1 *table,
+ hb_aat_apply_context_t *c_) :
+ c (c_),
+ kernAction (table+table->kernAction),
+ depth (0) {}
inline bool is_actionable (StateTableDriver<EntryData> *driver,
const Entry<EntryData> *entry)
{
- return false; // XXX return (entry->flags & Verb) && start < end;
+ return entry->data.kernActionIndex != 0xFFFF;
}
inline bool transition (StateTableDriver<EntryData> *driver,
const Entry<EntryData> *entry)
{
- //hb_buffer_t *buffer = driver->buffer;
- //unsigned int flags = entry->flags;
+ hb_buffer_t *buffer = driver->buffer;
+ unsigned int flags = entry->flags;
+
+ if (flags & Reset)
+ {
+ depth = 0;
+ }
+
+ if (flags & Push)
+ {
+ if (likely (depth < ARRAY_LENGTH (stack)))
+ stack[depth++] = buffer->idx;
+ else
+ depth = 0; /* Probably not what CoreText does, but better? */
+ }
+
+ if (entry->data.kernActionIndex != 0xFFFF)
+ {
+ const FWORD *actions = &kernAction[entry->data.kernActionIndex];
+ if (!c->sanitizer.check_array (actions, depth))
+ {
+ depth = 0;
+ return false;
+ }
+
+ for (; depth; depth--)
+ {
+ unsigned int idx = stack[depth - 1];
+ int v = *actions++;
+ /* XXX Non-forward direction... */
+ if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+ buffer->pos[idx].x_advance += v;
+ else
+ buffer->pos[idx].y_advance += v;
+ }
+ }
return true;
}
- public:
private:
+ hb_aat_apply_context_t *c;
+ const UnsizedArrayOf<FWORD> &kernAction;
+ unsigned int stack[8];
+ unsigned int depth;
};
inline bool apply (hb_aat_apply_context_t *c) const
@@ -148,7 +188,7 @@ struct KerxSubTableFormat1
if (!c->plan->requested_kerning)
return false;
- driver_context_t dc (this);
+ driver_context_t dc (this, c);
StateTableDriver<EntryData> driver (machine, c->buffer, c->font->face);
driver.drive (&dc);
@@ -165,7 +205,7 @@ struct KerxSubTableFormat1
protected:
KerxSubTableHeader header;
StateTable<EntryData> machine;
- LOffsetTo<UnsizedArrayOf<FWORD>, false> values;
+ LOffsetTo<UnsizedArrayOf<FWORD>, false> kernAction;
public:
DEFINE_SIZE_STATIC (32);
};
diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index 5de85126..b902fd79 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -365,7 +365,7 @@ struct LigatureSubtable
inline bool is_actionable (StateTableDriver<EntryData> *driver,
const Entry<EntryData> *entry)
{
- return !!(entry->flags & PerformAction);
+ return entry->flags & PerformAction;
}
inline bool transition (StateTableDriver<EntryData> *driver,
const Entry<EntryData> *entry)
commit c9165f5450b99e6d93e2a168b198384a221eef58
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Oct 10 20:43:21 2018 -0400
[kerx] More UnsizedArrayOf<>
diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index 0d3b330a..edc17a39 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -205,8 +205,7 @@ struct KerxSubTableFormat2
TRACE_SANITIZE (this);
return_trace (likely (rowWidth.sanitize (c) &&
leftClassTable.sanitize (c, this) &&
- rightClassTable.sanitize (c, this) &&
- array.sanitize (c, this)));
+ rightClassTable.sanitize (c, this)));
}
struct accelerator_t
@@ -233,7 +232,8 @@ struct KerxSubTableFormat2
LOffsetTo<Lookup<HBUINT16> >
rightClassTable;/* Offset from beginning of this subtable to
* right-hand class table. */
- LOffsetTo<FWORD> array; /* Offset from beginning of this subtable to
+ LOffsetTo<UnsizedArrayOf<FWORD>, false>
+ array; /* Offset from beginning of this subtable to
* the start of the kerning array. */
public:
DEFINE_SIZE_STATIC (28);
@@ -324,12 +324,10 @@ struct KerxSubTableFormat6
is_long () ?
(
u.l.rowIndexTable.sanitize (c, this) &&
- u.l.columnIndexTable.sanitize (c, this) &&
- u.l.array.sanitize (c, this)
+ u.l.columnIndexTable.sanitize (c, this)
) : (
u.s.rowIndexTable.sanitize (c, this) &&
- u.s.columnIndexTable.sanitize (c, this) &&
- u.s.array.sanitize (c, this)
+ u.s.columnIndexTable.sanitize (c, this)
)));
}
@@ -359,13 +357,15 @@ struct KerxSubTableFormat6
{
LOffsetTo<Lookup<HBUINT32> > rowIndexTable;
LOffsetTo<Lookup<HBUINT32> > columnIndexTable;
- LOffsetTo<FWORD32> array;
+ LOffsetTo<UnsizedArrayOf<FWORD32>, false>
+ array;
} l;
struct Short
{
LOffsetTo<Lookup<HBUINT16> > rowIndexTable;
LOffsetTo<Lookup<HBUINT16> > columnIndexTable;
- LOffsetTo<FWORD> array;
+ LOffsetTo<UnsizedArrayOf<FWORD>, false>
+ array;
} s;
} u;
public:
commit ca54eba4846d0afda4601929556617a7ebe51714
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Oct 10 20:41:16 2018 -0400
[kerx] Fix bound-checking error introduced a couple commits past
diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index 4118d8ee..0d3b330a 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -180,7 +180,7 @@ struct KerxSubTableFormat2
unsigned int offset = l + r;
const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
if (unlikely ((const char *) v < (const char *) &array ||
- (const char *) v + v->static_size - (const char *) this <= header.length))
+ (const char *) v + v->static_size - (const char *) this > header.length))
return 0;
return *v;
}
@@ -284,7 +284,7 @@ struct KerxSubTableFormat6
unsigned int offset = l + r;
const FWORD32 *v = &StructAtOffset<FWORD32> (&(this+t.array), offset * sizeof (FWORD32));
if (unlikely ((const char *) v < (const char *) &t.array ||
- (const char *) v + v->static_size - (const char *) this <= header.length))
+ (const char *) v + v->static_size - (const char *) this > header.length))
return 0;
return *v;
}
@@ -296,7 +296,7 @@ struct KerxSubTableFormat6
unsigned int offset = l + r;
const FWORD *v = &StructAtOffset<FWORD> (&(this+t.array), offset * sizeof (FWORD));
if (unlikely ((const char *) v < (const char *) &t.array ||
- (const char *) v + v->static_size - (const char *) this <= header.length))
+ (const char *) v + v->static_size - (const char *) this > header.length))
return 0;
return *v;
}
commit 339036dd970625e03696b4533ced1e25fc4fd131
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Oct 10 20:37:22 2018 -0400
[kerx] Start fleshing out Format1
diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index 3cff334a..4118d8ee 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -99,6 +99,48 @@ struct KerxSubTableFormat0
struct KerxSubTableFormat1
{
+ struct EntryData
+ {
+ HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry
+ * for processing this group, if indicated
+ * by the flags. */
+ public:
+ DEFINE_SIZE_STATIC (2);
+ };
+
+ struct driver_context_t
+ {
+ static const bool in_place = true;
+ enum Flags
+ {
+ Push = 0x8000, /* If set, push this glyph on the kerning stack. */
+ DontAdvance = 0x4000, /* If set, don't advance to the next glyph
+ * before going to the new state. */
+ Reset = 0x2000, /* If set, reset the kerning data (clear the stack) */
+ Reserved = 0x1FFF, /* Not used; set to 0. */
+ };
+
+ inline driver_context_t (const KerxSubTableFormat1 *table)
+ {}
+
+ inline bool is_actionable (StateTableDriver<EntryData> *driver,
+ const Entry<EntryData> *entry)
+ {
+ return false; // XXX return (entry->flags & Verb) && start < end;
+ }
+ inline bool transition (StateTableDriver<EntryData> *driver,
+ const Entry<EntryData> *entry)
+ {
+ //hb_buffer_t *buffer = driver->buffer;
+ //unsigned int flags = entry->flags;
+
+ return true;
+ }
+
+ public:
+ private:
+ };
+
inline bool apply (hb_aat_apply_context_t *c) const
{
TRACE_APPLY (this);
@@ -106,7 +148,10 @@ struct KerxSubTableFormat1
if (!c->plan->requested_kerning)
return false;
- /* TODO */
+ driver_context_t dc (this);
+
+ StateTableDriver<EntryData> driver (machine, c->buffer, c->font->face);
+ driver.drive (&dc);
return_trace (true);
}
@@ -114,14 +159,13 @@ struct KerxSubTableFormat1
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- stateHeader.sanitize (c)));
+ return_trace (likely (machine.sanitize (c)));
}
protected:
- KerxSubTableHeader header;
- StateTable<HBUINT16> stateHeader;
- LOffsetTo<ArrayOf<HBUINT16> > valueTable;
+ KerxSubTableHeader header;
+ StateTable<EntryData> machine;
+ LOffsetTo<UnsizedArrayOf<FWORD>, false> values;
public:
DEFINE_SIZE_STATIC (32);
};
@@ -159,8 +203,7 @@ struct KerxSubTableFormat2
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- rowWidth.sanitize (c) &&
+ return_trace (likely (rowWidth.sanitize (c) &&
leftClassTable.sanitize (c, this) &&
rightClassTable.sanitize (c, this) &&
array.sanitize (c, this)));
diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index 0020750c..5de85126 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -164,7 +164,7 @@ struct RearrangementSubtable
driver_context_t dc (this);
- StateTableDriver<void> driver (machine, c->buffer, c->face);
+ StateTableDriver<EntryData> driver (machine, c->buffer, c->face);
driver.drive (&dc);
return_trace (dc.ret);
More information about the HarfBuzz
mailing list