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 <beh...@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 <beh...@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 <beh...@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 <beh...@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 <beh...@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 <beh...@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 <beh...@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 <beh...@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) _______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/harfbuzz