diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 5945b0fba..61c569743 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1552,7 +1552,8 @@ struct PosLookup : Lookup else while (c->buffer->idx < c->buffer->len) { - if ((c->buffer->cur().mask & c->lookup_mask) && apply_once (c)) + if ((c->buffer->cur().mask & c->lookup_mask) && + apply_once (c)) ret = true; else c->buffer->idx++; @@ -1585,8 +1586,8 @@ struct GPOS : GSUBGPOS inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_index) const { return get_lookup (lookup_index).apply_string (c); } - static inline void position_start (hb_buffer_t *buffer); - static inline void position_finish (hb_buffer_t *buffer); + static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); + static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer); inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (); @@ -1644,7 +1645,7 @@ fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t di } void -GPOS::position_start (hb_buffer_t *buffer) +GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { buffer->clear_positions (); @@ -1654,7 +1655,7 @@ GPOS::position_start (hb_buffer_t *buffer) } void -GPOS::position_finish (hb_buffer_t *buffer) +GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { unsigned int len; hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len); diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 6a292a1e8..d62d97a5b 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -1220,7 +1220,8 @@ struct SubstLookup : Lookup else while (c->buffer->idx < c->buffer->len) { - if ((c->buffer->cur().mask & c->lookup_mask) && apply_once (c)) + if ((c->buffer->cur().mask & c->lookup_mask) && + apply_once (c)) ret = true; else c->buffer->next_glyph (); @@ -1289,8 +1290,8 @@ struct GSUB : GSUBGPOS inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index) const { return get_lookup (lookup_index).apply_string (c); } - static inline void substitute_start (hb_buffer_t *buffer); - static inline void substitute_finish (hb_buffer_t *buffer); + static inline void substitute_start (hb_face_t *face, hb_buffer_t *buffer); + static inline void substitute_finish (hb_face_t *face, hb_buffer_t *buffer); inline void closure_lookup (hb_closure_context_t *c, unsigned int lookup_index) const @@ -1308,19 +1309,22 @@ struct GSUB : GSUBGPOS void -GSUB::substitute_start (hb_buffer_t *buffer) +GSUB::substitute_start (hb_face_t *face, hb_buffer_t *buffer) { HB_BUFFER_ALLOCATE_VAR (buffer, props_cache); HB_BUFFER_ALLOCATE_VAR (buffer, lig_props); HB_BUFFER_ALLOCATE_VAR (buffer, syllable); + const GDEF &gdef = *hb_ot_layout_from_face (face)->gdef; unsigned int count = buffer->len; - for (unsigned int i = 0; i < count; i++) - buffer->info[i].props_cache() = buffer->info[i].lig_props() = buffer->info[i].syllable() = 0; + for (unsigned int i = 0; i < count; i++) { + buffer->info[i].lig_props() = buffer->info[i].syllable() = 0; + buffer->info[i].props_cache() = gdef.get_glyph_props (buffer->info[i].codepoint); + } } void -GSUB::substitute_finish (hb_buffer_t *buffer HB_UNUSED) +GSUB::substitute_finish (hb_face_t *face HB_UNUSED, hb_buffer_t *buffer HB_UNUSED) { } diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index 61dea3a14..00c64d5f7 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -97,6 +97,81 @@ struct hb_would_apply_context_t +static inline hb_bool_t +_hb_ot_layout_match_properties_mark (hb_face_t *face, + hb_codepoint_t glyph, + unsigned int glyph_props, + unsigned int lookup_props) +{ + /* If using mark filtering sets, the high short of + * lookup_props has the set index. + */ + if (lookup_props & LookupFlag::UseMarkFilteringSet) + return hb_ot_layout_from_face (face)->gdef->mark_set_covers (lookup_props >> 16, glyph); + + /* The second byte of lookup_props has the meaning + * "ignore marks of attachment type different than + * the attachment type specified." + */ + if (lookup_props & LookupFlag::MarkAttachmentType) + return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType); + + return true; +} + +static inline hb_bool_t +_hb_ot_layout_match_properties (hb_face_t *face, + hb_codepoint_t glyph, + unsigned int glyph_props, + unsigned int lookup_props) +{ + /* Not covered, if, for example, glyph class is ligature and + * lookup_props includes LookupFlags::IgnoreLigatures + */ + if (glyph_props & lookup_props & LookupFlag::IgnoreFlags) + return false; + + if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_CLASS_MARK)) + return _hb_ot_layout_match_properties_mark (face, glyph, glyph_props, lookup_props); + + return true; +} + +static inline hb_bool_t +_hb_ot_layout_check_glyph_property (hb_face_t *face, + hb_glyph_info_t *ginfo, + unsigned int lookup_props, + unsigned int *property_out) +{ + unsigned int property; + + property = ginfo->props_cache(); + *property_out = property; + + return _hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props); +} + +static inline hb_bool_t +_hb_ot_layout_skip_mark (hb_face_t *face, + hb_glyph_info_t *ginfo, + unsigned int lookup_props, + unsigned int *property_out) +{ + unsigned int property; + + property = ginfo->props_cache(); + if (property_out) + *property_out = property; + + /* If it's a mark, skip it if we don't accept it. */ + if (unlikely (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)) + return !_hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props); + + /* If not a mark, don't skip. */ + return false; +} + + struct hb_apply_context_t { hb_font_t *font; @@ -109,6 +184,7 @@ struct hb_apply_context_t unsigned int property; /* propety of first glyph */ unsigned int debug_depth; bool has_glyph_classes; + const GDEF &gdef; hb_apply_context_t (hb_font_t *font_, @@ -120,7 +196,8 @@ struct hb_apply_context_t lookup_mask (lookup_mask_), nesting_level_left (MAX_NESTING_LEVEL), lookup_props (0), property (0), debug_depth (0), - has_glyph_classes (hb_ot_layout_has_glyph_classes (face_)) {} + has_glyph_classes (hb_ot_layout_has_glyph_classes (face_)), + gdef (*hb_ot_layout_from_face (face_)->gdef /* XXX Unsafe dereference */) {} void set_lookup (const Lookup &l) { lookup_props = l.get_props (); @@ -229,30 +306,30 @@ struct hb_apply_context_t return _hb_ot_layout_skip_mark (face, &buffer->cur(), lookup_props, &property); } - inline void set_klass_guess (unsigned int klass_guess) const + inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const { if (likely (has_glyph_classes)) - buffer->cur().props_cache() = 0; - else if (klass_guess) - buffer->cur().props_cache() = klass_guess; + buffer->cur().props_cache() = gdef.get_glyph_props (glyph_index); + else if (class_guess) + buffer->cur().props_cache() = class_guess; } inline void output_glyph (hb_codepoint_t glyph_index, - unsigned int klass_guess = 0) const + unsigned int class_guess = 0) const { - set_klass_guess (klass_guess); + set_class (glyph_index, class_guess); buffer->output_glyph (glyph_index); } inline void replace_glyph (hb_codepoint_t glyph_index, - unsigned int klass_guess = 0) const + unsigned int class_guess = 0) const { - set_klass_guess (klass_guess); + set_class (glyph_index, class_guess); buffer->replace_glyph (glyph_index); } inline void replace_glyph_inplace (hb_codepoint_t glyph_index, - unsigned int klass_guess = 0) const + unsigned int class_guess = 0) const { - set_klass_guess (klass_guess); + set_class (glyph_index, class_guess); buffer->cur().codepoint = glyph_index; } }; diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index 78c9d64dd..3da3dfe5c 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -57,18 +57,6 @@ typedef enum { } hb_ot_layout_glyph_class_t; -HB_INTERNAL hb_bool_t -_hb_ot_layout_check_glyph_property (hb_face_t *face, - hb_glyph_info_t *ginfo, - unsigned int lookup_props, - unsigned int *property_out); - -HB_INTERNAL hb_bool_t -_hb_ot_layout_skip_mark (hb_face_t *face, - hb_glyph_info_t *ginfo, - unsigned int lookup_props, - unsigned int *property_out); - /* * GSUB/GPOS diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 253034012..1e5787496 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -106,93 +106,6 @@ hb_ot_layout_has_glyph_classes (hb_face_t *face) return _get_gdef (face).has_glyph_classes (); } -static inline unsigned int -_hb_ot_layout_get_glyph_property (hb_face_t *face, - hb_glyph_info_t *info) -{ - if (!info->props_cache()) - { - info->props_cache() = hb_ot_layout_from_face (face)->gdef->get_glyph_props (info->codepoint); - } - - return info->props_cache(); -} - -static inline hb_bool_t -_hb_ot_layout_match_properties_mark (hb_face_t *face, - hb_codepoint_t glyph, - unsigned int glyph_props, - unsigned int lookup_props) -{ - /* If using mark filtering sets, the high short of - * lookup_props has the set index. - */ - if (lookup_props & LookupFlag::UseMarkFilteringSet) - return hb_ot_layout_from_face (face)->gdef->mark_set_covers (lookup_props >> 16, glyph); - - /* The second byte of lookup_props has the meaning - * "ignore marks of attachment type different than - * the attachment type specified." - */ - if (lookup_props & LookupFlag::MarkAttachmentType) - return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType); - - return true; -} - -static inline hb_bool_t -_hb_ot_layout_match_properties (hb_face_t *face, - hb_codepoint_t glyph, - unsigned int glyph_props, - unsigned int lookup_props) -{ - /* Not covered, if, for example, glyph class is ligature and - * lookup_props includes LookupFlags::IgnoreLigatures - */ - if (glyph_props & lookup_props & LookupFlag::IgnoreFlags) - return false; - - if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_CLASS_MARK)) - return _hb_ot_layout_match_properties_mark (face, glyph, glyph_props, lookup_props); - - return true; -} - -hb_bool_t -_hb_ot_layout_check_glyph_property (hb_face_t *face, - hb_glyph_info_t *ginfo, - unsigned int lookup_props, - unsigned int *property_out) -{ - unsigned int property; - - property = _hb_ot_layout_get_glyph_property (face, ginfo); - *property_out = property; - - return _hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props); -} - -hb_bool_t -_hb_ot_layout_skip_mark (hb_face_t *face, - hb_glyph_info_t *ginfo, - unsigned int lookup_props, - unsigned int *property_out) -{ - unsigned int property; - - property = _hb_ot_layout_get_glyph_property (face, ginfo); - if (property_out) - *property_out = property; - - /* If it's a mark, skip it if we don't accept it. */ - if (unlikely (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)) - return !_hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props); - - /* If not a mark, don't skip. */ - return false; -} - - unsigned int hb_ot_layout_get_attach_points (hb_face_t *face, @@ -215,6 +128,7 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font, return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array); } + /* * GSUB/GPOS */ @@ -492,9 +406,9 @@ hb_ot_layout_would_substitute_lookup_fast (hb_face_t *face, } void -hb_ot_layout_substitute_start (hb_buffer_t *buffer) +hb_ot_layout_substitute_start (hb_face_t *face, hb_buffer_t *buffer) { - GSUB::substitute_start (buffer); + GSUB::substitute_start (face, buffer); } hb_bool_t @@ -518,9 +432,9 @@ hb_ot_layout_substitute_lookup_fast (hb_face_t *face, } void -hb_ot_layout_substitute_finish (hb_buffer_t *buffer HB_UNUSED) +hb_ot_layout_substitute_finish (hb_face_t *face, hb_buffer_t *buffer) { - GSUB::substitute_finish (buffer); + GSUB::substitute_finish (face, buffer); } void @@ -543,9 +457,9 @@ hb_ot_layout_has_positioning (hb_face_t *face) } void -hb_ot_layout_position_start (hb_buffer_t *buffer) +hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer) { - GPOS::position_start (buffer); + GPOS::position_start (font, buffer); } hb_bool_t @@ -569,9 +483,9 @@ hb_ot_layout_position_lookup_fast (hb_font_t *font, } void -hb_ot_layout_position_finish (hb_buffer_t *buffer) +hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer) { - GPOS::position_finish (buffer); + GPOS::position_finish (font, buffer); } diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 07e062f38..4e205d71d 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -178,7 +178,8 @@ hb_ot_layout_would_substitute_lookup (hb_face_t *face, /* Should be called before all the substitute_lookup's are done. */ void -hb_ot_layout_substitute_start (hb_buffer_t *buffer); +hb_ot_layout_substitute_start (hb_face_t *face, + hb_buffer_t *buffer); hb_bool_t hb_ot_layout_substitute_lookup (hb_face_t *face, @@ -188,7 +189,8 @@ hb_ot_layout_substitute_lookup (hb_face_t *face, /* Should be called after all the substitute_lookup's are done */ void -hb_ot_layout_substitute_finish (hb_buffer_t *buffer); +hb_ot_layout_substitute_finish (hb_face_t *face, + hb_buffer_t *buffer); void @@ -205,7 +207,8 @@ hb_ot_layout_has_positioning (hb_face_t *face); /* Should be called before all the position_lookup's are done. Resets positions to zero. */ void -hb_ot_layout_position_start (hb_buffer_t *buffer); +hb_ot_layout_position_start (hb_font_t *font, + hb_buffer_t *buffer); hb_bool_t hb_ot_layout_position_lookup (hb_font_t *font, @@ -215,7 +218,8 @@ hb_ot_layout_position_lookup (hb_font_t *font, /* Should be called after all the position_lookup's are done */ void -hb_ot_layout_position_finish (hb_buffer_t *buffer); +hb_ot_layout_position_finish (hb_font_t *font, + hb_buffer_t *buffer); HB_END_DECLS diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index c727fa6e5..0cd548ff9 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -342,8 +342,6 @@ hb_map_glyphs (hb_font_t *font, static void hb_substitute_default (hb_ot_shape_context_t *c) { - hb_ot_layout_substitute_start (c->buffer); - hb_mirror_chars (c); hb_map_glyphs (c->font, c->buffer); @@ -352,11 +350,13 @@ hb_substitute_default (hb_ot_shape_context_t *c) static void hb_ot_substitute_complex (hb_ot_shape_context_t *c) { + hb_ot_layout_substitute_start (c->face, c->buffer); + if (hb_ot_layout_has_substitution (c->face)) { c->plan->map.substitute (c->face, c->buffer); } - hb_ot_layout_substitute_finish (c->buffer); + hb_ot_layout_substitute_finish (c->face, c->buffer); return; } @@ -367,7 +367,7 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c) static void hb_position_default (hb_ot_shape_context_t *c) { - hb_ot_layout_position_start (c->buffer); + hb_ot_layout_position_start (c->font, c->buffer); unsigned int count = c->buffer->len; for (unsigned int i = 0; i < count; i++) { @@ -410,7 +410,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c) c->applied_position_complex = true; } - hb_ot_layout_position_finish (c->buffer); + hb_ot_layout_position_finish (c->font, c->buffer); return; }