diff options
Diffstat (limited to 'thirdparty/harfbuzz/src/OT')
14 files changed, 291 insertions, 9 deletions
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh index 7c34bb3c93..7f58fac8b8 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh @@ -140,6 +140,13 @@ struct CursivePosFormat1 unsigned int i = skippy_iter.idx; unsigned int j = buffer->idx; + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "cursive attaching glyph at %d to glyph at %d", + i, j); + } + buffer->unsafe_to_break (i, j + 1); float entry_x, entry_y, exit_x, exit_y; (this+prev_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y); @@ -231,6 +238,13 @@ struct CursivePosFormat1 pos[parent].x_offset = 0; } + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "cursive attached glyph at %d to glyph at %d", + i, j); + } + buffer->idx++; return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh index f8cddd1991..cb5e8b2689 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh @@ -39,6 +39,13 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Cove mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y); glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "attaching mark glyph at %d to glyph at %d", + c->buffer->idx, glyph_pos); + } + hb_glyph_position_t &o = buffer->cur_pos(); o.x_offset = roundf (base_x - mark_x); o.y_offset = roundf (base_y - mark_y); @@ -46,6 +53,13 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Cove o.attach_chain() = (int) glyph_pos - (int) buffer->idx; buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "attached mark glyph at %d to glyph at %d", + c->buffer->idx, glyph_pos); + } + buffer->idx++; return_trace (true); } @@ -83,10 +97,11 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Cove } }; -static void Markclass_closure_and_remap_indexes (const Coverage &mark_coverage, - const MarkArray &mark_array, - const hb_set_t &glyphset, - hb_map_t* klass_mapping /* INOUT */) +HB_INTERNAL inline +void Markclass_closure_and_remap_indexes (const Coverage &mark_coverage, + const MarkArray &mark_array, + const hb_set_t &glyphset, + hb_map_t* klass_mapping /* INOUT */) { hb_set_t orig_classes; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh index f58bcb1b30..a80fe0c226 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh @@ -217,10 +217,23 @@ struct PairPosFormat2_4 } bail: + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "kerning glyphs at %d,%d", + c->buffer->idx, skippy_iter.idx); + } applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos()); applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "kerned glyphs at %d,%d", + c->buffer->idx, skippy_iter.idx); + } + success: if (applied_first || applied_second) buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh index 58ba4de6c1..4578fbd1d6 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh @@ -109,12 +109,28 @@ struct PairSet record_size); if (record) { + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "kerning glyphs at %d,%d", + c->buffer->idx, pos); + } + bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()); bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "kerned glyphs at %d,%d", + c->buffer->idx, pos); + } + if (applied_first || applied_second) buffer->unsafe_to_break (buffer->idx, pos + 1); if (len2) pos++; + buffer->idx = pos; return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh index 55de5abebf..bd95abde16 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh @@ -1,6 +1,8 @@ #ifndef OT_LAYOUT_GPOS_PAIRVALUERECORD_HH #define OT_LAYOUT_GPOS_PAIRVALUERECORD_HH +#include "ValueFormat.hh" + namespace OT { namespace Layout { namespace GPOS_impl { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh index c0e7d29cea..7cbdf6dc6c 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh @@ -39,12 +39,10 @@ struct SinglePosFormat1 { if (!valueFormat.has_device ()) return; - auto it = - + hb_iter (this+coverage) - | hb_filter (c->glyph_set) - ; + hb_set_t intersection; + (this+coverage).intersect_set (*c->glyph_set, intersection); + if (!intersection) return; - if (!it) return; valueFormat.collect_variation_indices (c, this, values.as_array (valueFormat.get_len ())); } @@ -62,8 +60,22 @@ struct SinglePosFormat1 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "positioning glyph at %d", + c->buffer->idx); + } + valueFormat.apply_value (c, this, values, buffer->cur_pos()); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "positioned glyph at %d", + c->buffer->idx); + } + buffer->idx++; return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh index 0d038b4422..518fa9dcb0 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh @@ -70,10 +70,24 @@ struct SinglePosFormat2 if (likely (index >= valueCount)) return_trace (false); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "positioning glyph at %d", + c->buffer->idx); + } + valueFormat.apply_value (c, this, &values[index * valueFormat.get_len ()], buffer->cur_pos()); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "positioned glyph at %d", + c->buffer->idx); + } + buffer->idx++; return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh index a5dcb65359..4a9e9672eb 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh @@ -57,8 +57,23 @@ struct AlternateSet if (unlikely (alt_index > count || alt_index == 0)) return_trace (false); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "replacing glyph at %d (alternate substitution)", + c->buffer->idx); + } + c->replace_glyph (alternates[alt_index - 1]); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %d (alternate substitution)", + c->buffer->idx - 1); + } + return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh index 22ed65f858..f373d921b5 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh @@ -64,7 +64,24 @@ struct Ligature * as a "ligated" substitution. */ if (unlikely (count == 1)) { + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "replacing glyph at %d (ligature substitution)", + c->buffer->idx); + } + c->replace_glyph (ligGlyph); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %d (ligature substitution)", + c->buffer->idx - 1); + } + return_trace (true); } @@ -85,6 +102,31 @@ struct Ligature return_trace (false); } + unsigned pos = 0; + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + unsigned delta = c->buffer->sync_so_far (); + + pos = c->buffer->idx; + + char buf[HB_MAX_CONTEXT_LENGTH * 16] = {0}; + char *p = buf; + + match_end += delta; + for (unsigned i = 0; i < count; i++) + { + match_positions[i] += delta; + if (i) + *p++ = ','; + sprintf (p, "%u", match_positions[i]); + p += strlen(p); + } + + c->buffer->message (c->font, + "ligating glyphs at %s", + buf); + } + ligate_input (c, count, match_positions, @@ -92,6 +134,14 @@ struct Ligature ligGlyph, total_component_count); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "ligated glyph at %d", + pos); + } + return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh index 1d27df95dd..a23e92028e 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh @@ -131,7 +131,23 @@ struct ReverseChainSingleSubstFormat1 c->buffer->idx + 1, &end_index)) { c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replacing glyph at %d (reverse chaining substitution)", + c->buffer->idx); + } + c->replace_glyph_inplace (substitute[index]); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %d (reverse chaining substitution)", + c->buffer->idx); + } + /* Note: We DON'T decrease buffer->idx. The main loop does it * for us. This is useful for preventing surprises if someone * calls us through a Context lookup. */ diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh index c5cd15bb23..3d84a5e6ea 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh @@ -40,17 +40,58 @@ struct Sequence * as a "multiplied" substitution. */ if (unlikely (count == 1)) { + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "replacing glyph at %d (multiple substitution)", + c->buffer->idx); + } + c->replace_glyph (substitute.arrayZ[0]); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %d (multiple subtitution)", + c->buffer->idx - 1); + } + return_trace (true); } /* Spec disallows this, but Uniscribe allows it. * https://github.com/harfbuzz/harfbuzz/issues/253 */ else if (unlikely (count == 0)) { + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "deleting glyph at %d (multiple substitution)", + c->buffer->idx); + } + c->buffer->delete_glyph (); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "deleted glyph at %d (multiple substitution)", + c->buffer->idx); + } + return_trace (true); } + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "multiplying glyph at %d", + c->buffer->idx); + } + unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; unsigned lig_id = _hb_glyph_info_get_lig_id (&c->buffer->cur()); @@ -65,6 +106,26 @@ struct Sequence } c->buffer->skip_glyph (); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + + char buf[HB_MAX_CONTEXT_LENGTH * 16] = {0}; + char *p = buf; + + for (unsigned i = c->buffer->idx - count; i < c->buffer->idx; i++) + { + if (buf < p) + *p++ = ','; + sprintf (p, "%u", i); + p += strlen(p); + } + + c->buffer->message (c->font, + "multiplied glyphs at %s", + buf); + } + return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh index dd44595741..4b17243d81 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh @@ -45,6 +45,18 @@ struct SingleSubstFormat1_3 hb_set_t intersection; (this+coverage).intersect_set (c->parent_active_glyphs (), intersection); + /* In degenerate fuzzer-found fonts, but not real fonts, + * this table can keep adding new glyphs in each round of closure. + * Refuse to close-over, if it maps glyph range to overlapping range. */ + hb_codepoint_t min_before = intersection.get_min (); + hb_codepoint_t max_before = intersection.get_max (); + hb_codepoint_t min_after = (min_before + d) & mask; + hb_codepoint_t max_after = (max_before + d) & mask; + if ((this+coverage).get_population () >= max_before - min_before && + ((min_before <= min_after && min_after <= max_before) || + (min_before <= max_after && max_after <= max_before))) + return; + + hb_iter (intersection) | hb_map ([d, mask] (hb_codepoint_t g) { return (g + d) & mask; }) | hb_sink (c->output) @@ -82,8 +94,23 @@ struct SingleSubstFormat1_3 glyph_id = (glyph_id + d) & mask; + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "replacing glyph at %d (single substitution)", + c->buffer->idx); + } + c->replace_glyph (glyph_id); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %d (single substitution)", + c->buffer->idx - 1); + } + return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh index 386419a2a5..fb1e90d03e 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh @@ -68,8 +68,23 @@ struct SingleSubstFormat2_4 if (unlikely (index >= substitute.len)) return_trace (false); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "replacing glyph at %d (single substitution)", + c->buffer->idx); + } + c->replace_glyph (substitute[index]); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %d (single substitution)", + c->buffer->idx - 1); + } + return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh index abe4c8330c..98c2ee4e73 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh @@ -26,7 +26,9 @@ struct CompositeGlyphRecord OVERLAP_COMPOUND = 0x0400, SCALED_COMPONENT_OFFSET = 0x0800, UNSCALED_COMPONENT_OFFSET = 0x1000, +#ifndef HB_NO_BEYOND_64K GID_IS_24BIT = 0x2000 +#endif }; public: @@ -34,7 +36,9 @@ struct CompositeGlyphRecord { unsigned int size = min_size; /* glyphIndex is 24bit instead of 16bit */ +#ifndef HB_NO_BEYOND_64K if (flags & GID_IS_24BIT) size += HBGlyphID24::static_size - HBGlyphID16::static_size; +#endif /* arg1 and 2 are int16 */ if (flags & ARG_1_AND_2_ARE_WORDS) size += 4; /* arg1 and 2 are int8 */ @@ -64,9 +68,11 @@ struct CompositeGlyphRecord void get_anchor_points (unsigned int &point1, unsigned int &point2) const { const auto *p = &StructAfter<const HBUINT8> (flags); +#ifndef HB_NO_BEYOND_64K if (flags & GID_IS_24BIT) p += HBGlyphID24::static_size; else +#endif p += HBGlyphID16::static_size; if (flags & ARG_1_AND_2_ARE_WORDS) { @@ -109,9 +115,11 @@ struct CompositeGlyphRecord matrix[1] = matrix[2] = 0.f; const auto *p = &StructAfter<const HBINT8> (flags); +#ifndef HB_NO_BEYOND_64K if (flags & GID_IS_24BIT) p += HBGlyphID24::static_size; else +#endif p += HBGlyphID16::static_size; int tx, ty; if (flags & ARG_1_AND_2_ARE_WORDS) @@ -158,16 +166,20 @@ struct CompositeGlyphRecord public: hb_codepoint_t get_gid () const { +#ifndef HB_NO_BEYOND_64K if (flags & GID_IS_24BIT) return StructAfter<const HBGlyphID24> (flags); else +#endif return StructAfter<const HBGlyphID16> (flags); } void set_gid (hb_codepoint_t gid) { +#ifndef HB_NO_BEYOND_64K if (flags & GID_IS_24BIT) StructAfter<HBGlyphID24> (flags) = gid; else +#endif /* TODO assert? */ StructAfter<HBGlyphID16> (flags) = gid; } |