Index: third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh |
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh |
index 76b4f33c705a5321ada908f62e034ba6b5398f74..e1939735de6be0f0fd5b76f0236a7f08259cf503 100644 |
--- a/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh |
+++ b/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh |
@@ -44,7 +44,7 @@ struct SingleSubstFormat1 |
for (iter.init (this+coverage); iter.more (); iter.next ()) { |
hb_codepoint_t glyph_id = iter.get_glyph (); |
if (c->glyphs->has (glyph_id)) |
- c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFF); |
+ c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFFu); |
} |
} |
@@ -55,7 +55,7 @@ struct SingleSubstFormat1 |
for (iter.init (this+coverage); iter.more (); iter.next ()) { |
hb_codepoint_t glyph_id = iter.get_glyph (); |
c->input->add (glyph_id); |
- c->output->add ((glyph_id + deltaGlyphID) & 0xFFFF); |
+ c->output->add ((glyph_id + deltaGlyphID) & 0xFFFFu); |
} |
} |
@@ -79,7 +79,7 @@ struct SingleSubstFormat1 |
/* According to the Adobe Annotated OpenType Suite, result is always |
* limited to 16bit. */ |
- glyph_id = (glyph_id + deltaGlyphID) & 0xFFFF; |
+ glyph_id = (glyph_id + deltaGlyphID) & 0xFFFFu; |
c->replace_glyph (glyph_id); |
return TRACE_RETURN (true); |
@@ -270,23 +270,34 @@ struct Sequence |
inline bool apply (hb_apply_context_t *c) const |
{ |
TRACE_APPLY (this); |
- if (unlikely (!substitute.len)) return TRACE_RETURN (false); |
- |
- unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? |
- HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; |
unsigned int count = substitute.len; |
- if (count == 1) /* Special-case to make it in-place. */ |
+ |
+ /* TODO: |
+ * Testing shows that Uniscribe actually allows zero-len susbstitute, |
+ * which essentially deletes a glyph. We don't allow for now. It |
+ * can be confusing to the client since the cluster from the deleted |
+ * glyph won't be merged with any output cluster... Also, currently |
+ * buffer->move_to() makes assumptions about this too. Perhaps fix |
+ * in the future after figuring out what to do with the clusters. |
+ */ |
+ if (unlikely (!count)) return TRACE_RETURN (false); |
+ |
+ /* Special-case to make it in-place and not consider this |
+ * as a "multiplied" substitution. */ |
+ if (unlikely (count == 1)) |
{ |
c->replace_glyph (substitute.array[0]); |
+ return TRACE_RETURN (true); |
} |
- else |
- { |
- for (unsigned int i = 0; i < count; i++) { |
- _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i); |
- c->output_glyph (substitute.array[i], klass); |
- } |
- c->buffer->skip_glyph (); |
+ |
+ unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? |
+ HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; |
+ |
+ for (unsigned int i = 0; i < count; i++) { |
+ _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i); |
+ c->output_glyph_for_component (substitute.array[i], klass); |
} |
+ c->buffer->skip_glyph (); |
return TRACE_RETURN (true); |
} |
@@ -624,7 +635,16 @@ struct Ligature |
{ |
TRACE_APPLY (this); |
unsigned int count = component.len; |
- if (unlikely (count < 1)) return TRACE_RETURN (false); |
+ |
+ if (unlikely (!count)) return TRACE_RETURN (false); |
+ |
+ /* Special-case to make it in-place and not consider this |
+ * as a "ligated" substitution. */ |
+ if (unlikely (count == 1)) |
+ { |
+ c->replace_glyph (ligGlyph); |
+ return TRACE_RETURN (true); |
+ } |
bool is_mark_ligature = false; |
unsigned int total_component_count = 0; |
@@ -1338,7 +1358,7 @@ GSUB::substitute_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSE |
/* Out-of-class implementation for methods recursing */ |
-inline bool ExtensionSubst::is_reverse (void) const |
+/*static*/ inline bool ExtensionSubst::is_reverse (void) const |
{ |
unsigned int type = get_type (); |
if (unlikely (type == SubstLookupSubTable::Extension)) |
@@ -1347,14 +1367,14 @@ inline bool ExtensionSubst::is_reverse (void) const |
} |
template <typename context_t> |
-inline typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index) |
+/*static*/ inline typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index) |
{ |
const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub); |
const SubstLookup &l = gsub.get_lookup (lookup_index); |
return l.dispatch (c); |
} |
-inline bool SubstLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index) |
+/*static*/ inline bool SubstLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index) |
{ |
const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub); |
const SubstLookup &l = gsub.get_lookup (lookup_index); |