diff options
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh')
-rw-r--r-- | Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh | 249 |
1 files changed, 183 insertions, 66 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh index 315951a34f8..695a5df9957 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh @@ -33,6 +33,7 @@ #include "hb-buffer.hh" #include "hb-map.hh" #include "hb-set.hh" +#include "hb-ot-map.hh" #include "hb-ot-layout-common.hh" #include "hb-ot-layout-gdef-table.hh" @@ -213,10 +214,10 @@ struct hb_collect_glyphs_context_t : unsigned int debug_depth; hb_collect_glyphs_context_t (hb_face_t *face_, - hb_set_t *glyphs_before, /* OUT. May be nullptr */ - hb_set_t *glyphs_input, /* OUT. May be nullptr */ - hb_set_t *glyphs_after, /* OUT. May be nullptr */ - hb_set_t *glyphs_output, /* OUT. May be nullptr */ + hb_set_t *glyphs_before, /* OUT. May be NULL */ + hb_set_t *glyphs_input, /* OUT. May be NULL */ + hb_set_t *glyphs_after, /* OUT. May be NULL */ + hb_set_t *glyphs_output, /* OUT. May be NULL */ unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), before (glyphs_before ? glyphs_before : hb_set_get_empty ()), @@ -343,10 +344,10 @@ struct hb_ot_apply_context_t : match_glyph_data = nullptr; matcher.set_match_func (nullptr, nullptr); matcher.set_lookup_props (c->lookup_props); - /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ + /* Ignore ZWNJ if we are matching GPOS, or matching GSUB context and asked to. */ matcher.set_ignore_zwnj (c->table_index == 1 || (context_match && c->auto_zwnj)); - /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ - matcher.set_ignore_zwj (c->table_index == 1 || (context_match || c->auto_zwj)); + /* Ignore ZWJ if we are matching context, or asked to. */ + matcher.set_ignore_zwj (context_match || c->auto_zwj); matcher.set_mask (context_match ? -1 : c->lookup_mask); } inline void set_lookup_props (unsigned int lookup_props) @@ -478,9 +479,12 @@ struct hb_ot_apply_context_t : unsigned int nesting_level_left; unsigned int debug_depth; + bool has_glyph_classes; bool auto_zwnj; bool auto_zwj; - bool has_glyph_classes; + bool random; + + uint32_t random_state; hb_ot_apply_context_t (unsigned int table_index_, @@ -498,22 +502,33 @@ struct hb_ot_apply_context_t : lookup_props (0), nesting_level_left (HB_MAX_NESTING_LEVEL), debug_depth (0), + has_glyph_classes (gdef.has_glyph_classes ()), auto_zwnj (true), auto_zwj (true), - has_glyph_classes (gdef.has_glyph_classes ()) {} + random (false), + random_state (1) { init_iters (); } - inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; } - inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; } - inline void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; } - inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } - inline void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; } - inline void set_lookup_props (unsigned int lookup_props_) + inline void init_iters (void) { - lookup_props = lookup_props_; iter_input.init (this, false); iter_context.init (this, true); } + inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; init_iters (); } + inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; init_iters (); } + inline void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; init_iters (); } + inline void set_random (bool random_) { random = random_; } + inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } + inline void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; } + inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; init_iters (); } + + inline uint32_t random_number (void) + { + /* http://www.cplusplus.com/reference/random/minstd_rand/ */ + random_state = random_state * 48271 % 2147483647; + return random_state; + } + inline bool match_properties_mark (hb_codepoint_t glyph, unsigned int glyph_props, @@ -606,6 +621,64 @@ struct hb_ot_apply_context_t : }; +struct hb_get_subtables_context_t : + hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY> +{ + template <typename Type> + static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c) + { + const Type *typed_obj = (const Type *) obj; + return typed_obj->apply (c); + } + + typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_ot_apply_context_t *c); + + struct hb_applicable_t + { + template <typename T> + inline void init (const T &obj_, hb_apply_func_t apply_func_) + { + obj = &obj_; + apply_func = apply_func_; + digest.init (); + obj_.get_coverage ().add_coverage (&digest); + } + + inline bool apply (OT::hb_ot_apply_context_t *c) const + { + return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c); + } + + private: + const void *obj; + hb_apply_func_t apply_func; + hb_set_digest_t digest; + }; + + typedef hb_vector_t<hb_applicable_t, 2> array_t; + + /* Dispatch interface. */ + inline const char *get_name (void) { return "GET_SUBTABLES"; } + template <typename T> + inline return_t dispatch (const T &obj) + { + hb_applicable_t *entry = array.push(); + entry->init (obj, apply_to<T>); + return HB_VOID; + } + static return_t default_return_value (void) { return HB_VOID; } + bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } + + hb_get_subtables_context_t (array_t &array_) : + array (array_), + debug_depth (0) {} + + array_t &array; + unsigned int debug_depth; +}; + + + typedef bool (*intersects_func_t) (const hb_set_t *glyphs, const HBUINT16 &value, const void *data); typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data); @@ -716,7 +789,6 @@ static inline bool match_input (hb_ot_apply_context_t *c, const void *match_data, unsigned int *end_offset, unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], - bool *p_is_mark_ligature = nullptr, unsigned int *p_total_component_count = nullptr) { TRACE_APPLY (nullptr); @@ -753,8 +825,6 @@ static inline bool match_input (hb_ot_apply_context_t *c, * https://github.com/harfbuzz/harfbuzz/issues/545 */ - bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur()); - unsigned int total_component_count = 0; total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur()); @@ -821,15 +891,11 @@ static inline bool match_input (hb_ot_apply_context_t *c, return_trace (false); } - is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]); total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]); } *end_offset = skippy_iter.idx - buffer->idx + 1; - if (p_is_mark_ligature) - *p_is_mark_ligature = is_mark_ligature; - if (p_total_component_count) *p_total_component_count = total_component_count; @@ -840,7 +906,6 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ unsigned int match_length, hb_codepoint_t lig_glyph, - bool is_mark_ligature, unsigned int total_component_count) { TRACE_APPLY (nullptr); @@ -849,11 +914,15 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, buffer->merge_clusters (buffer->idx, buffer->idx + match_length); - /* - * - If it *is* a mark ligature, we don't allocate a new ligature id, and leave + /* - If a base and one or more marks ligate, consider that as a base, NOT + * ligature, such that all following marks can still attach to it. + * https://github.com/harfbuzz/harfbuzz/issues/1109 + * + * - If all components of the ligature were marks, we call this a mark ligature. + * If it *is* a mark ligature, we don't allocate a new ligature id, and leave * the ligature to keep its old ligature id. This will allow it to attach to * a base ligature in GPOS. Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HEH, - * and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA wit a + * and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA with a * ligature id and component value of 2. Then if SHADDA,FATHA form a ligature * later, we don't want them to lose their ligature id/component, otherwise * GPOS will fail to correctly position the mark ligature on top of the @@ -877,13 +946,24 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, * https://bugzilla.gnome.org/show_bug.cgi?id=437633 */ - unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE; - unsigned int lig_id = is_mark_ligature ? 0 : _hb_allocate_lig_id (buffer); + bool is_base_ligature = _hb_glyph_info_is_base_glyph (&buffer->info[match_positions[0]]); + bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->info[match_positions[0]]); + for (unsigned int i = 1; i < count; i++) + if (!_hb_glyph_info_is_mark (&buffer->info[match_positions[i]])) + { + is_base_ligature = false; + is_mark_ligature = false; + break; + } + bool is_ligature = !is_base_ligature && !is_mark_ligature; + + unsigned int klass = is_ligature ? HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE : 0; + unsigned int lig_id = is_ligature ? _hb_allocate_lig_id (buffer) : 0; unsigned int last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); unsigned int last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur()); unsigned int components_so_far = last_num_components; - if (!is_mark_ligature) + if (is_ligature) { _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_component_count); if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) @@ -897,7 +977,8 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, { while (buffer->idx < match_positions[i] && buffer->successful) { - if (!is_mark_ligature) { + if (is_ligature) + { unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); if (this_comp == 0) this_comp = last_num_components; @@ -1222,42 +1303,42 @@ struct Rule inline bool intersects (const hb_set_t *glyphs, ContextClosureLookupContext &lookup_context) const { return context_intersects (glyphs, - inputCount, inputZ, + inputCount, inputZ.arrayZ, lookup_context); } inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const { TRACE_CLOSURE (this); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); + const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAtOffset<UnsizedArrayOf<LookupRecord> > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); context_closure_lookup (c, - inputCount, inputZ, - lookupCount, lookupRecord, + inputCount, inputZ.arrayZ, + lookupCount, lookupRecord.arrayZ, lookup_context); } inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const { TRACE_COLLECT_GLYPHS (this); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); + const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAtOffset<UnsizedArrayOf<LookupRecord> > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); context_collect_glyphs_lookup (c, - inputCount, inputZ, - lookupCount, lookupRecord, + inputCount, inputZ.arrayZ, + lookupCount, lookupRecord.arrayZ, lookup_context); } inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const { TRACE_WOULD_APPLY (this); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); - return_trace (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); + const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAtOffset<UnsizedArrayOf<LookupRecord> > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); + return_trace (context_would_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context)); } inline bool apply (hb_ot_apply_context_t *c, ContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); - return_trace (context_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); + const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAtOffset<UnsizedArrayOf<LookupRecord> > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); + return_trace (context_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context)); } public: @@ -1266,8 +1347,8 @@ struct Rule TRACE_SANITIZE (this); return_trace (inputCount.sanitize (c) && lookupCount.sanitize (c) && - c->check_range (inputZ, - inputZ[0].static_size * inputCount + + c->check_range (inputZ.arrayZ, + inputZ[0].static_size * (inputCount ? inputCount - 1 : 0) + LookupRecord::static_size * lookupCount)); } @@ -1276,9 +1357,11 @@ struct Rule * glyph sequence--includes the first * glyph */ HBUINT16 lookupCount; /* Number of LookupRecords */ - HBUINT16 inputZ[VAR]; /* Array of match inputs--start with + UnsizedArrayOf<HBUINT16> + inputZ; /* Array of match inputs--start with * second glyph */ -/*LookupRecord lookupRecordX[VAR];*/ /* Array of LookupRecords--in +/*UnsizedArrayOf<LookupRecord> + lookupRecordX;*/ /* Array of LookupRecords--in * design order */ public: DEFINE_SIZE_ARRAY (4, inputZ); @@ -1595,7 +1678,7 @@ struct ContextFormat3 this }; return context_intersects (glyphs, - glyphCount, (const HBUINT16 *) (coverageZ + 1), + glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookup_context); } @@ -1605,13 +1688,13 @@ struct ContextFormat3 if (!(this+coverageZ[0]).intersects (c->glyphs)) return; - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); + const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount); struct ContextClosureLookupContext lookup_context = { {intersects_coverage}, this }; context_closure_lookup (c, - glyphCount, (const HBUINT16 *) (coverageZ + 1), + glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookupCount, lookupRecord, lookup_context); } @@ -1621,14 +1704,14 @@ struct ContextFormat3 TRACE_COLLECT_GLYPHS (this); (this+coverageZ[0]).add_coverage (c->input); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); + const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount); struct ContextCollectGlyphsLookupContext lookup_context = { {collect_coverage}, this }; context_collect_glyphs_lookup (c, - glyphCount, (const HBUINT16 *) (coverageZ + 1), + glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookupCount, lookupRecord, lookup_context); } @@ -1637,12 +1720,12 @@ struct ContextFormat3 { TRACE_WOULD_APPLY (this); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); + const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount); struct ContextApplyLookupContext lookup_context = { {match_coverage}, this }; - return_trace (context_would_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); + return_trace (context_would_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookupCount, lookupRecord, lookup_context)); } inline const Coverage &get_coverage (void) const @@ -1654,12 +1737,12 @@ struct ContextFormat3 unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); + const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount); struct ContextApplyLookupContext lookup_context = { {match_coverage}, this }; - return_trace (context_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); + return_trace (context_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookupCount, lookupRecord, lookup_context)); } inline bool subset (hb_subset_context_t *c) const @@ -1675,11 +1758,11 @@ struct ContextFormat3 if (!c->check_struct (this)) return_trace (false); unsigned int count = glyphCount; if (!count) return_trace (false); /* We want to access coverageZ[0] freely. */ - if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return_trace (false); + if (!c->check_array (coverageZ.arrayZ, count)) return_trace (false); for (unsigned int i = 0; i < count; i++) if (!coverageZ[i].sanitize (c, this)) return_trace (false); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count); - return_trace (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount)); + const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * count); + return_trace (c->check_array (lookupRecord, lookupCount)); } protected: @@ -1687,10 +1770,11 @@ struct ContextFormat3 HBUINT16 glyphCount; /* Number of glyphs in the input glyph * sequence */ HBUINT16 lookupCount; /* Number of LookupRecords */ - OffsetTo<Coverage> - coverageZ[VAR]; /* Array of offsets to Coverage + UnsizedArrayOf<OffsetTo<Coverage> > + coverageZ; /* Array of offsets to Coverage * table in glyph sequence order */ -/*LookupRecord lookupRecordX[VAR];*/ /* Array of LookupRecords--in +/*UnsizedArrayOf<LookupRecord> + lookupRecordX;*/ /* Array of LookupRecords--in * design order */ public: DEFINE_SIZE_ARRAY (6, coverageZ); @@ -1862,7 +1946,7 @@ struct ChainRule const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); return chain_context_intersects (glyphs, backtrack.len, backtrack.arrayZ, - input.len, input.arrayZ, + input.lenP1, input.arrayZ, lookahead.len, lookahead.arrayZ, lookup_context); } @@ -1875,7 +1959,7 @@ struct ChainRule const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); chain_context_closure_lookup (c, backtrack.len, backtrack.arrayZ, - input.len, input.arrayZ, + input.lenP1, input.arrayZ, lookahead.len, lookahead.arrayZ, lookup.len, lookup.arrayZ, lookup_context); @@ -1889,7 +1973,7 @@ struct ChainRule const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); chain_context_collect_glyphs_lookup (c, backtrack.len, backtrack.arrayZ, - input.len, input.arrayZ, + input.lenP1, input.arrayZ, lookahead.len, lookahead.arrayZ, lookup.len, lookup.arrayZ, lookup_context); @@ -1903,7 +1987,7 @@ struct ChainRule const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); return_trace (chain_context_would_apply_lookup (c, backtrack.len, backtrack.arrayZ, - input.len, input.arrayZ, + input.lenP1, input.arrayZ, lookahead.len, lookahead.arrayZ, lookup.len, lookup.arrayZ, lookup_context)); } @@ -1916,7 +2000,7 @@ struct ChainRule const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); return_trace (chain_context_apply_lookup (c, backtrack.len, backtrack.arrayZ, - input.len, input.arrayZ, + input.lenP1, input.arrayZ, lookahead.len, lookahead.arrayZ, lookup.len, lookup.arrayZ, lookup_context)); } @@ -2536,6 +2620,39 @@ struct Extension * GSUB/GPOS Common */ +struct hb_ot_layout_lookup_accelerator_t +{ + template <typename TLookup> + inline void init (const TLookup &lookup) + { + digest.init (); + lookup.add_coverage (&digest); + + subtables.init (); + OT::hb_get_subtables_context_t c_get_subtables (subtables); + lookup.dispatch (&c_get_subtables); + } + inline void fini (void) + { + subtables.fini (); + } + + inline bool may_have (hb_codepoint_t g) const + { return digest.may_have (g); } + + inline bool apply (hb_ot_apply_context_t *c) const + { + for (unsigned int i = 0; i < subtables.len; i++) + if (subtables[i].apply (c)) + return true; + return false; + } + + private: + hb_set_digest_t digest; + hb_get_subtables_context_t::array_t subtables; +}; + struct GSUBGPOS { inline bool has_data (void) const { return version.to_int () != 0; } |