[HarfBuzz] harfbuzz: Branch 'master' - 8 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Fri Nov 2 18:48:39 UTC 2018
src/hb-aat-layout-kerx-table.hh | 11 +
src/hb-open-type.hh | 3
src/hb-ot-face.hh | 2
src/hb-ot-kern-table.hh | 332 ++++++++++++++++++++++++++++++++--------
src/hb-ot-layout.cc | 28 ++-
src/hb-ot-layout.hh | 8
src/hb-ot-shape.cc | 2
7 files changed, 305 insertions(+), 81 deletions(-)
New commits:
commit 8034d1dda091998d356e77f249d3c9f50501cc77
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Nov 2 14:47:42 2018 -0400
[kern] Implement Format1
Also, implement backwards kerning for Format1 in kern and kerx.
Fixes https://github.com/harfbuzz/harfbuzz/issues/1350
diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index 94e0a9b6..b227af10 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -207,11 +207,18 @@ struct KerxSubTableFormat1
int v = *actions++;
if (idx < buffer->len && buffer->info[idx].mask & kern_mask)
{
- /* XXX Non-forward direction... */
if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+ {
buffer->pos[idx].x_advance += c->font->em_scale_x (v);
+ if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+ buffer->pos[idx].x_offset += c->font->em_scale_x (v);
+ }
else
+ {
buffer->pos[idx].y_advance += c->font->em_scale_y (v);
+ if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+ buffer->pos[idx].y_offset += c->font->em_scale_y (v);
+ }
}
}
depth = 0;
@@ -255,7 +262,7 @@ struct KerxSubTableFormat1
protected:
KerxSubTableHeader header;
- StateTable<MorxTypes, EntryData> machine;
+ StateTable<MorxTypes, EntryData> machine;
LOffsetTo<UnsizedArrayOf<FWORD>, false> kernAction;
public:
DEFINE_SIZE_STATIC (32);
diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index ec33d603..9f8a0115 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -192,6 +192,130 @@ struct KernSubTableFormat0
DEFINE_SIZE_ARRAY (8, pairs);
};
+struct KernSubTableFormat1
+{
+ typedef void EntryData;
+
+ 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. */
+ Offset = 0x3FFF, /* Byte offset from beginning of subtable to the
+ * value table for the glyphs on the kerning stack. */
+ };
+
+ inline driver_context_t (const KernSubTableFormat1 *table_,
+ AAT::hb_aat_apply_context_t *c_) :
+ c (c_),
+ table (table_),
+ /* Apparently the offset kernAction is from the beginning of the state-machine,
+ * similar to offsets in morx table, NOT from beginning of this table, like
+ * other subtables in kerx. Discovered via testing. */
+ kernAction (&table->machine + table->kernAction),
+ depth (0) {}
+
+ inline bool is_actionable (AAT::StateTableDriver<AAT::MortTypes, EntryData> *driver HB_UNUSED,
+ const AAT::Entry<EntryData> *entry)
+ {
+ return entry->flags & Offset;
+ }
+ inline bool transition (AAT::StateTableDriver<AAT::MortTypes, EntryData> *driver,
+ const AAT::Entry<EntryData> *entry)
+ {
+ hb_buffer_t *buffer = driver->buffer;
+ unsigned int flags = entry->flags;
+
+ 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->flags & Offset)
+ {
+ unsigned int kernIndex = AAT::MortTypes::offsetToIndex (entry->flags & Offset, &table->machine, kernAction.arrayZ);
+ const FWORD *actions = &kernAction[kernIndex];
+ if (!c->sanitizer.check_array (actions, depth))
+ {
+ depth = 0;
+ return false;
+ }
+
+ hb_mask_t kern_mask = c->plan->kern_mask;
+ for (unsigned int i = 0; i < depth; i++)
+ {
+ /* 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++;
+ if (idx < buffer->len && buffer->info[idx].mask & kern_mask)
+ {
+ if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+ {
+ buffer->pos[idx].x_advance += c->font->em_scale_x (v);
+ if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+ buffer->pos[idx].x_offset += c->font->em_scale_x (v);
+ }
+ else
+ {
+ buffer->pos[idx].y_advance += c->font->em_scale_y (v);
+ if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+ buffer->pos[idx].y_offset += c->font->em_scale_y (v);
+ }
+ }
+ }
+ depth = 0;
+ }
+
+ return true;
+ }
+
+ private:
+ AAT::hb_aat_apply_context_t *c;
+ const KernSubTableFormat1 *table;
+ const UnsizedArrayOf<FWORD> &kernAction;
+ unsigned int stack[8];
+ unsigned int depth;
+ };
+
+ inline bool apply (AAT::hb_aat_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+
+ if (!c->plan->requested_kerning)
+ return false;
+
+ driver_context_t dc (this, c);
+
+ AAT::StateTableDriver<AAT::MortTypes, EntryData> driver (machine, c->buffer, c->font->face);
+ driver.drive (&dc);
+
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ /* The rest of array sanitizations are done at run-time. */
+ return_trace (likely (c->check_struct (this) &&
+ machine.sanitize (c)));
+ }
+
+ protected:
+ AAT::StateTable<AAT::MortTypes, EntryData> machine;
+ OffsetTo<UnsizedArrayOf<FWORD>, HBUINT16, false> kernAction;
+ public:
+ DEFINE_SIZE_STATIC (10);
+};
+
struct KernClassTable
{
inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; }
@@ -361,6 +485,7 @@ struct KernSubTable
/* TODO Switch to dispatch(). */
switch (format) {
case 0: u.format0.apply (c); return;
+ case 1: u.format1.apply (c); return;
case 2: u.format2.apply (c); return;
case 3: u.format3.apply (c); return;
default: return;
@@ -372,6 +497,7 @@ struct KernSubTable
TRACE_SANITIZE (this);
switch (format) {
case 0: return_trace (u.format0.sanitize (c));
+ case 1: return_trace (u.format1.sanitize (c));
case 2: return_trace (u.format2.sanitize (c));
case 3: return_trace (u.format3.sanitize (c));
default:return_trace (true);
@@ -381,6 +507,7 @@ struct KernSubTable
protected:
union {
KernSubTableFormat0 format0;
+ KernSubTableFormat1 format1;
KernSubTableFormat2 format2;
KernSubTableFormat3 format3;
} u;
commit 46b3885c1a8ea3b85efbdd1704edcee385797c5d
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Nov 2 14:43:38 2018 -0400
[kern] Set subtable on sanitizer
diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index 3845da8e..ec33d603 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -474,6 +474,8 @@ struct KernTable
if (!c->buffer->message (c->font, "start kern subtable %d", c->lookup_index))
goto skip;
+ c->sanitizer.set_object (*st);
+
st->apply (c);
(void) c->buffer->message (c->font, "end kern subtable %d", c->lookup_index);
commit 74c7a2c6c892446dcec574986e128967bd570e47
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Nov 2 14:26:04 2018 -0400
[kern] Respect more flags
diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index 303e1bb3..3845da8e 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -395,8 +395,11 @@ 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_supported (void) const
+ { return !(thiz()->coverage & T::CheckFlags); }
+
inline bool is_horizontal (void) const
- { return (thiz()->coverage & T::CheckFlags) == T::CheckHorizontal; }
+ { return (thiz()->coverage & T::Direction) == T::CheckHorizontal; }
inline bool is_override (void) const
{ return bool (thiz()->coverage & T::Override); }
@@ -405,7 +408,7 @@ struct KernSubTableWrapper
{ return thiz()->subtable.get_kerning (left, right, thiz()->format); }
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
- { return is_horizontal () ? get_kerning (left, right) : 0; }
+ { return is_supported () && is_horizontal () ? get_kerning (left, right) : 0; }
inline void apply (AAT::hb_aat_apply_context_t *c) const
{ thiz()->subtable.apply (c, thiz()->format); }
@@ -435,7 +438,7 @@ struct KernTable
unsigned int count = thiz()->nTables;
for (unsigned int i = 0; i < count; i++)
{
- if (st->is_override ())
+ if (st->is_supported () && st->is_override ())
v = 0;
v += st->get_h_kerning (left, right);
st = &StructAfter<typename T::SubTableWrapper> (*st);
@@ -452,13 +455,19 @@ struct KernTable
unsigned int last_override = 0;
for (unsigned int i = 0; i < count; i++)
{
- if (st->is_override ())
+ if (st->is_supported () && st->is_override ())
last_override = i;
st = &StructAfter<typename T::SubTableWrapper> (*st);
}
st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
for (unsigned int i = 0; i < count; i++)
{
+ if (!st->is_supported ())
+ goto skip;
+
+ if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->is_horizontal ())
+ goto skip;
+
if (i < last_override)
goto skip;
@@ -514,7 +523,7 @@ struct KernOT : KernTable<KernOT>
Variation = 0x00u, /* Not supported. */
- CheckFlags = 0x07u,
+ CheckFlags = 0x06u,
CheckHorizontal = 0x01u
};
@@ -555,7 +564,7 @@ struct KernAAT : KernTable<KernAAT>
Override = 0x00u, /* Not supported. */
- CheckFlags = 0xE0u,
+ CheckFlags = 0x60u,
CheckHorizontal = 0x00u
};
commit 9f880bad0d7291eaab10d814567c7a680e139c48
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Nov 2 13:57:41 2018 -0400
[kern] Minor
We like check_struct() more.
diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index 77dd7b36..303e1bb3 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -199,7 +199,8 @@ struct KernClassTable
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (firstGlyph.sanitize (c) && classes.sanitize (c));
+ return_trace (c->check_struct (this) &&
+ classes.sanitize (c));
}
protected:
@@ -262,7 +263,7 @@ struct KernSubTableFormat2
{
TRACE_SANITIZE (this);
return_trace (true); /* Disabled. See above. */
- return_trace (rowWidth.sanitize (c) &&
+ return_trace (c->check_struct (this) &&
leftClassTable.sanitize (c, this) &&
rightClassTable.sanitize (c, this) &&
array.sanitize (c, this));
commit 04b82b181d06c229a98314c1620d3ae8a2825267
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Nov 2 13:47:33 2018 -0400
Remove pointer cast operators from ArrayOf<>
ArrayOf<>, unlike UnsizedArrayOf<>, has data before the array.
This was confusing. Remove.
diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
index afd75be4..0f6efdc6 100644
--- a/src/hb-open-type.hh
+++ b/src/hb-open-type.hh
@@ -452,9 +452,6 @@ struct ArrayOf
return arrayZ[i];
}
- template <typename T> inline operator T * (void) { return arrayZ; }
- template <typename T> inline operator const T * (void) const { return arrayZ; }
-
inline unsigned int get_size (void) const
{ return len.static_size + len * Type::static_size; }
commit f1df441bedaf5b2c7fadf9954ea39616af87702a
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Nov 2 13:26:15 2018 -0400
[kern] Comment
diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index 311d61d5..77dd7b36 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -217,8 +217,7 @@ struct KernSubTableFormat2
/* This subtable is disabled. It's not cleaer to me *exactly* where the offests are
* based from. I *think* they should be based from beginning of kern subtable wrapper,
* *NOT* "this". Since we know of no fonts that use this subtable, we are disabling
- * it. Someday fix it and re-enable. Better yet, find fonts that use it... Meh,
- * Windows doesn't implement it. Maybe just remove... */
+ * it. Someday fix it and re-enable. */
return 0;
unsigned int l = (this+leftClassTable).get_class (left);
unsigned int r = (this+rightClassTable).get_class (right);
commit 095f5add0b1ca39dd09842594b80fae92f0796e4
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Nov 2 13:23:54 2018 -0400
[kern] Push apply loop to each subtable
diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index 8c436f99..311d61d5 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -30,6 +30,8 @@
#include "hb-open-type.hh"
#include "hb-ot-shape.hh"
#include "hb-ot-layout-gsubgpos.hh"
+#include "hb-aat-layout-ankr-table.hh" // Ugly but needed.
+#include "hb-aat-layout-common.hh"
template <typename Driver>
@@ -165,6 +167,19 @@ struct KernSubTableFormat0
return pairs[i].get_kerning ();
}
+ inline bool apply (AAT::hb_aat_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+
+ if (!c->plan->requested_kerning)
+ return false;
+
+ hb_kern_machine_t<KernSubTableFormat0> machine (*this);
+ machine.kern (c->font, c->buffer, c->plan->kern_mask);
+
+ return_trace (true);
+ }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -196,7 +211,8 @@ struct KernClassTable
struct KernSubTableFormat2
{
- inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
+ inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
+ AAT::hb_aat_apply_context_t *c) const
{
/* This subtable is disabled. It's not cleaer to me *exactly* where the offests are
* based from. I *think* they should be based from beginning of kern subtable wrapper,
@@ -208,12 +224,41 @@ struct KernSubTableFormat2
unsigned int r = (this+rightClassTable).get_class (right);
unsigned int offset = l + r;
const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
+#if 0
if (unlikely ((const char *) v < (const char *) &array ||
(const char *) v > (const char *) end - 2))
+#endif
return 0;
return *v;
}
+ inline bool apply (AAT::hb_aat_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+
+ if (!c->plan->requested_kerning)
+ return false;
+
+ accelerator_t accel (*this, c);
+ hb_kern_machine_t<accelerator_t> machine (accel);
+ machine.kern (c->font, c->buffer, c->plan->kern_mask);
+
+ return_trace (true);
+ }
+
+ struct accelerator_t
+ {
+ const KernSubTableFormat2 &table;
+ AAT::hb_aat_apply_context_t *c;
+
+ inline accelerator_t (const KernSubTableFormat2 &table_,
+ AAT::hb_aat_apply_context_t *c_) :
+ table (table_), c (c_) {}
+
+ inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+ { return table.get_kerning (left, right, c); }
+ };
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -241,7 +286,7 @@ struct KernSubTableFormat2
struct KernSubTableFormat3
{
- inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
+ inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{
hb_array_t<const FWORD> kernValue = kernValueZ.as_array (kernValueCount);
hb_array_t<const HBUINT8> leftClass = StructAfter<const UnsizedArrayOf<HBUINT8> > (kernValue).as_array (glyphCount);
@@ -252,6 +297,19 @@ struct KernSubTableFormat3
return kernValue[kernIndex[i]];
}
+ inline bool apply (AAT::hb_aat_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+
+ if (!c->plan->requested_kerning)
+ return false;
+
+ hb_kern_machine_t<KernSubTableFormat3> machine (*this);
+ machine.kern (c->font, c->buffer, c->plan->kern_mask);
+
+ return_trace (true);
+ }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -289,16 +347,26 @@ struct KernSubTableFormat3
struct KernSubTable
{
- inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end, unsigned int format) const
+ inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int format) const
{
switch (format) {
+ /* 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 2: return u.format2.get_kerning (left, right, end);
- case 3: return u.format3.get_kerning (left, right, end);
default:return 0;
}
}
+ inline void apply (AAT::hb_aat_apply_context_t *c, unsigned int format) const
+ {
+ /* TODO Switch to dispatch(). */
+ switch (format) {
+ case 0: u.format0.apply (c); return;
+ case 2: u.format2.apply (c); return;
+ case 3: u.format3.apply (c); return;
+ default: return;
+ }
+ }
+
inline bool sanitize (hb_sanitize_context_t *c, unsigned int format) const
{
TRACE_SANITIZE (this);
@@ -333,11 +401,14 @@ struct KernSubTableWrapper
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 char *end) const
- { return thiz()->subtable.get_kerning (left, right, end, thiz()->format); }
+ inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+ { return thiz()->subtable.get_kerning (left, right, thiz()->format); }
- inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
- { return is_horizontal () ? get_kerning (left, right, end) : 0; }
+ inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+ { return is_horizontal () ? get_kerning (left, right) : 0; }
+
+ 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; }
@@ -366,12 +437,43 @@ struct KernTable
{
if (st->is_override ())
v = 0;
- v += st->get_h_kerning (left, right, st->length + (const char *) st);
+ v += st->get_h_kerning (left, right);
st = &StructAfter<typename T::SubTableWrapper> (*st);
}
return v;
}
+ inline void apply (AAT::hb_aat_apply_context_t *c) const
+ {
+ c->set_lookup_index (0);
+ const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
+ unsigned int count = thiz()->nTables;
+ /* If there's an override subtable, skip subtables before that. */
+ unsigned int last_override = 0;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (st->is_override ())
+ last_override = i;
+ st = &StructAfter<typename T::SubTableWrapper> (*st);
+ }
+ st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (i < last_override)
+ goto skip;
+
+ if (!c->buffer->message (c->font, "start kern subtable %d", c->lookup_index))
+ goto skip;
+
+ st->apply (c);
+
+ (void) c->buffer->message (c->font, "end kern subtable %d", c->lookup_index);
+
+ skip:
+ st = &StructAfter<typename T::SubTableWrapper> (*st);
+ }
+ }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -492,6 +594,16 @@ struct kern
}
}
+ inline void apply (AAT::hb_aat_apply_context_t *c) const
+ {
+ /* TODO Switch to dispatch(). */
+ switch (u.major) {
+ case 0: u.ot.apply (c); return;
+ case 1: u.aat.apply (c); return;
+ default: return;
+ }
+ }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -503,27 +615,6 @@ struct kern
}
}
- inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const
- { return get_h_kerning (first, second); }
-
- inline void apply (hb_font_t *font,
- hb_buffer_t *buffer,
- hb_mask_t kern_mask) const
- {
- /* We only apply horizontal kerning in this table. */
- if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
- return;
-
- hb_kern_machine_t<kern> machine (*this);
-
- if (!buffer->message (font, "start kern table"))
- return;
-
- machine.kern (font, buffer, kern_mask);
-
- (void) buffer->message (font, "end kern table");
- }
-
protected:
union {
HBUINT32 version32;
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index f4ae840b..b81aabd2 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -55,10 +55,19 @@
**/
-static const OT::kern& _get_kern (hb_face_t *face)
+static inline const OT::kern&
+_get_kern (hb_face_t *face, hb_blob_t **blob = nullptr)
{
- if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern);
- return *hb_ot_face_data (face)->kern;
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face)))
+ {
+ if (blob)
+ *blob = hb_blob_get_empty ();
+ return Null(OT::kern);
+ }
+ const OT::kern& kern = *(hb_ot_face_data (face)->kern.get ());
+ if (blob)
+ *blob = hb_ot_face_data (face)->kern.get_blob ();
+ return kern;
}
const OT::GDEF& _get_gdef (hb_face_t *face)
{
@@ -106,11 +115,16 @@ hb_ot_layout_has_kerning (hb_face_t *face)
}
void
-hb_ot_layout_kern (hb_font_t *font,
- hb_buffer_t *buffer,
- hb_mask_t kern_mask)
+hb_ot_layout_kern (hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
{
- _get_kern (font->face).apply (font, buffer, kern_mask);
+ hb_blob_t *blob;
+ const AAT::kern& kern = _get_kern (font->face, &blob);
+
+ AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
+
+ kern.apply (&c);
}
diff --git a/src/hb-ot-layout.hh b/src/hb-ot-layout.hh
index 64b3d748..b29f87c5 100644
--- a/src/hb-ot-layout.hh
+++ b/src/hb-ot-layout.hh
@@ -34,6 +34,7 @@
#include "hb-font.hh"
#include "hb-buffer.hh"
#include "hb-open-type.hh"
+#include "hb-ot-shape.hh"
#include "hb-set-digest.hh"
@@ -48,6 +49,7 @@ HB_INTERNAL const OT::GDEF& _get_gdef (hb_face_t *face);
HB_INTERNAL const OT::GSUB& _get_gsub_relaxed (hb_face_t *face);
HB_INTERNAL const OT::GPOS& _get_gpos_relaxed (hb_face_t *face);
+struct hb_ot_shape_plan_t;
/*
* kern
@@ -57,9 +59,9 @@ HB_INTERNAL hb_bool_t
hb_ot_layout_has_kerning (hb_face_t *face);
HB_INTERNAL void
-hb_ot_layout_kern (hb_font_t *font,
- hb_buffer_t *buffer,
- hb_mask_t kern_mask);
+hb_ot_layout_kern (hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
/* Private API corresponding to hb-ot-layout.h: */
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index c55d8dcb..b687996f 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -918,7 +918,7 @@ hb_ot_position (const hb_ot_shape_context_t *c)
/* Visual fallback goes here. */
if (c->plan->apply_kern)
- hb_ot_layout_kern (c->font, c->buffer, c->plan->kern_mask);
+ hb_ot_layout_kern (c->plan, c->font, c->buffer);
else if (c->plan->fallback_kerning)
_hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
commit 949dad89a81ff5b6ef92e8737962b667249a3f2b
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Nov 2 12:47:55 2018 -0400
[kern] Remove accelerator
It wasn't doing anything.
diff --git a/src/hb-ot-face.hh b/src/hb-ot-face.hh
index 6e629eb4..caa1d97e 100644
--- a/src/hb-ot-face.hh
+++ b/src/hb-ot-face.hh
@@ -67,7 +67,7 @@
HB_OT_ACCELERATOR(OT, hmtx) \
HB_OT_ACCELERATOR(OT, vmtx) \
HB_OT_ACCELERATOR(OT, post) \
- HB_OT_ACCELERATOR(OT, kern) \
+ HB_OT_TABLE(OT, kern) \
HB_OT_ACCELERATOR(OT, glyf) \
HB_OT_TABLE(OT, VORG) \
HB_OT_ACCELERATOR(OT, name) \
diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index 4f196789..8c436f99 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -503,49 +503,26 @@ struct kern
}
}
- struct accelerator_t
- {
- inline void init (hb_face_t *face)
- {
- blob = hb_sanitize_context_t().reference_table<kern> (face);
- table = blob->as<kern> ();
- }
- inline void fini (void)
- {
- hb_blob_destroy (blob);
- }
-
- inline bool has_data (void) const
- { return table->has_data (); }
-
- inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
- { return table->get_h_kerning (left, right); }
-
- inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const
- { return get_h_kerning (first, second); }
+ inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const
+ { return get_h_kerning (first, second); }
- inline void apply (hb_font_t *font,
- hb_buffer_t *buffer,
- hb_mask_t kern_mask) const
- {
- /* We only apply horizontal kerning in this table. */
- if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
- return;
-
- hb_kern_machine_t<accelerator_t> machine (*this);
+ inline void apply (hb_font_t *font,
+ hb_buffer_t *buffer,
+ hb_mask_t kern_mask) const
+ {
+ /* We only apply horizontal kerning in this table. */
+ if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+ return;
- if (!buffer->message (font, "start kern table"))
- return;
+ hb_kern_machine_t<kern> machine (*this);
- machine.kern (font, buffer, kern_mask);
+ if (!buffer->message (font, "start kern table"))
+ return;
- (void) buffer->message (font, "end kern table");
- }
+ machine.kern (font, buffer, kern_mask);
- private:
- hb_blob_t *blob;
- const kern *table;
- };
+ (void) buffer->message (font, "end kern table");
+ }
protected:
union {
@@ -558,8 +535,6 @@ struct kern
DEFINE_SIZE_UNION (4, version32);
};
-struct kern_accelerator_t : kern::accelerator_t {};
-
} /* namespace OT */
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index e1b6b2e3..f4ae840b 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -55,9 +55,9 @@
**/
-static const OT::kern::accelerator_t& _get_kern (hb_face_t *face)
+static const OT::kern& _get_kern (hb_face_t *face)
{
- if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern::accelerator_t);
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern);
return *hb_ot_face_data (face)->kern;
}
const OT::GDEF& _get_gdef (hb_face_t *face)
More information about the HarfBuzz
mailing list