Skip to content

Commit 8be090c

Browse files
committed
Merge pull request #111569 from DeeJayLSP/harfbuzz-update
Update HarfBuzz to 12.1.0
2 parents c5754cc + 276e1c2 commit 8be090c

File tree

132 files changed

+8276
-6750
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

132 files changed

+8276
-6750
lines changed

modules/text_server_adv/SCsub

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ if env["builtin_harfbuzz"]:
5555
# "src/hb-glib.cc",
5656
# "src/hb-gobject-structs.cc",
5757
"src/hb-icu.cc",
58+
# "src/hb-kbts.cc",
5859
"src/hb-map.cc",
5960
"src/hb-number.cc",
6061
"src/hb-ot-cff1-table.cc",
@@ -95,14 +96,19 @@ if env["builtin_harfbuzz"]:
9596
"src/hb-shaper.cc",
9697
"src/hb-static.cc",
9798
"src/hb-style.cc",
98-
"src/hb-subset-cff-common.cc",
99-
"src/hb-subset-cff1.cc",
100-
"src/hb-subset-cff2.cc",
101-
"src/hb-subset-input.cc",
102-
"src/hb-subset-instancer-iup.cc",
103-
"src/hb-subset-instancer-solver.cc",
104-
"src/hb-subset-plan.cc",
105-
"src/hb-subset-serialize.cc",
99+
# "src/hb-subset-cff-common.cc",
100+
# "src/hb-subset-cff1.cc",
101+
# "src/hb-subset-cff2.cc",
102+
# "src/hb-subset-input.cc",
103+
# "src/hb-subset-instancer-iup.cc",
104+
# "src/hb-subset-instancer-solver.cc",
105+
# "src/hb-subset-plan.cc",
106+
# "src/hb-subset-serialize.cc",
107+
# "src/hb-subset-table-cff.cc",
108+
# "src/hb-subset-table-color.cc",
109+
# "src/hb-subset-table-layout.cc",
110+
# "src/hb-subset-table-other.cc",
111+
# "src/hb-subset-table-var.cc",
106112
"src/hb-subset.cc",
107113
"src/hb-ucd.cc",
108114
"src/hb-unicode.cc",

thirdparty/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ Patches:
436436
## harfbuzz
437437

438438
- Upstream: https://github.com/harfbuzz/harfbuzz
439-
- Version: 11.3.2 (4e3df1c1383481ed5717603d5dd3453a04fb16ba, 2025)
439+
- Version: 12.1.0 (a790c38b782f9d8e6f0299d2837229e5726fc669, 2025)
440440
- License: MIT
441441

442442
Files extracted from upstream source:

thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,10 @@ struct hb_colrv1_closure_context_t :
178178
{ glyphs->add (glyph_id); }
179179

180180
void add_layer_indices (unsigned first_layer_index, unsigned num_of_layers)
181-
{ layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); }
181+
{
182+
if (num_of_layers == 0) return;
183+
layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1);
184+
}
182185

183186
void add_palette_index (unsigned palette_index)
184187
{ palette_indices->add (palette_index); }
@@ -650,10 +653,10 @@ struct PaintColrLayers
650653
TRACE_SUBSET (this);
651654
auto *out = c->serializer->embed (this);
652655
if (unlikely (!out)) return_trace (false);
653-
return_trace (c->serializer->check_assign (out->firstLayerIndex, c->plan->colrv1_layers.get (firstLayerIndex),
654-
HB_SERIALIZE_ERROR_INT_OVERFLOW));
655656

656-
return_trace (true);
657+
uint32_t first_layer_index = numLayers ? c->plan->colrv1_layers.get (firstLayerIndex) : 0;
658+
return_trace (c->serializer->check_assign (out->firstLayerIndex, first_layer_index,
659+
HB_SERIALIZE_ERROR_INT_OVERFLOW));
657660
}
658661

659662
bool sanitize (hb_sanitize_context_t *c) const
@@ -2057,7 +2060,7 @@ struct delta_set_index_map_subset_plan_t
20572060
outer_bit_count = 1;
20582061
inner_bit_count = 1;
20592062

2060-
if (unlikely (!output_map.resize (map_count, false))) return false;
2063+
if (unlikely (!output_map.resize_dirty (map_count))) return false;
20612064

20622065
for (unsigned idx = 0; idx < map_count; idx++)
20632066
{

thirdparty/harfbuzz/src/OT/Color/CPAL/CPAL.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ struct CPAL
307307
if (first_color_to_layer_index.has (first_color_record_idx)) continue;
308308

309309
first_color_index_for_layer.push (first_color_record_idx);
310+
if (unlikely (!c->serializer->propagate_error (first_color_index_for_layer))) return_trace (false);
310311
first_color_to_layer_index.set (first_color_record_idx,
311312
first_color_index_for_layer.length - 1);
312313
}

thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,17 @@ struct Coverage
9797
}
9898
}
9999
unsigned int get_coverage (hb_codepoint_t glyph_id,
100-
hb_ot_lookup_cache_t *cache) const
100+
hb_ot_layout_mapping_cache_t *cache) const
101101
{
102102
unsigned coverage;
103-
if (cache && cache->get (glyph_id, &coverage)) return coverage;
103+
if (cache && cache->get (glyph_id, &coverage)) return coverage < cache->MAX_VALUE ? coverage : NOT_COVERED;
104104
coverage = get_coverage (glyph_id);
105-
if (cache) cache->set (glyph_id, coverage);
105+
if (cache) {
106+
if (coverage == NOT_COVERED)
107+
cache->set_unchecked (glyph_id, cache->MAX_VALUE);
108+
else if (likely (coverage < cache->MAX_VALUE))
109+
cache->set_unchecked (glyph_id, coverage);
110+
}
106111
return coverage;
107112
}
108113

@@ -332,7 +337,7 @@ struct Coverage
332337
}
333338
iter_t __end__ () const
334339
{
335-
iter_t it = {};
340+
iter_t it;
336341
it.format = format;
337342
switch (format)
338343
{

thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,7 @@ struct GDEF
977977
}
978978

979979
#ifndef HB_NO_GDEF_CACHE
980-
table->get_mark_glyph_sets ().collect_coverage (mark_glyph_set_digests);
980+
table->get_mark_glyph_sets ().collect_coverage (mark_glyph_sets);
981981
#endif
982982
}
983983
~accelerator_t () { table.destroy (); }
@@ -1006,14 +1006,16 @@ struct GDEF
10061006
{
10071007
return
10081008
#ifndef HB_NO_GDEF_CACHE
1009-
mark_glyph_set_digests[set_index].may_have (glyph_id) &&
1009+
mark_glyph_sets[set_index].may_have (glyph_id)
1010+
#else
1011+
table->mark_set_covers (set_index, glyph_id)
10101012
#endif
1011-
table->mark_set_covers (set_index, glyph_id);
1013+
;
10121014
}
10131015

10141016
hb_blob_ptr_t<GDEF> table;
10151017
#ifndef HB_NO_GDEF_CACHE
1016-
hb_vector_t<hb_set_digest_t> mark_glyph_set_digests;
1018+
hb_vector_t<hb_bit_set_t> mark_glyph_sets;
10171019
mutable hb_cache_t<21, 3> glyph_props_cache;
10181020
static_assert (sizeof (glyph_props_cache) == 512, "");
10191021
#endif

thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ struct AnchorMatrix
7777

7878
return_trace (true);
7979
}
80+
81+
bool offset_is_null (unsigned row, unsigned col, unsigned num_cols) const
82+
{
83+
if (unlikely (row >= rows || col >= num_cols)) return true;
84+
auto &offset = matrixZ[row * num_cols + col];
85+
return offset.is_null ();
86+
}
8087
};
8188

8289

thirdparty/harfbuzz/src/OT/Layout/GPOS/GPOS.hh

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,8 @@ propagate_attachment_offsets (hb_glyph_position_t *pos,
8080
{
8181
/* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate
8282
* offset of glyph they are attached to. */
83-
int chain = pos[i].attach_chain(), type = pos[i].attach_type();
84-
if (likely (!chain))
85-
return;
83+
int chain = pos[i].attach_chain();
84+
int type = pos[i].attach_type();
8685

8786
pos[i].attach_chain() = 0;
8887

@@ -94,7 +93,8 @@ propagate_attachment_offsets (hb_glyph_position_t *pos,
9493
if (unlikely (!nesting_level))
9594
return;
9695

97-
propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1);
96+
if (pos[j].attach_chain())
97+
propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1);
9898

9999
assert (!!(type & GPOS_impl::ATTACH_TYPE_MARK) ^ !!(type & GPOS_impl::ATTACH_TYPE_CURSIVE));
100100

@@ -110,17 +110,37 @@ propagate_attachment_offsets (hb_glyph_position_t *pos,
110110
pos[i].x_offset += pos[j].x_offset;
111111
pos[i].y_offset += pos[j].y_offset;
112112

113-
assert (j < i);
114-
if (HB_DIRECTION_IS_FORWARD (direction))
115-
for (unsigned int k = j; k < i; k++) {
116-
pos[i].x_offset -= pos[k].x_advance;
117-
pos[i].y_offset -= pos[k].y_advance;
118-
}
119-
else
120-
for (unsigned int k = j + 1; k < i + 1; k++) {
121-
pos[i].x_offset += pos[k].x_advance;
122-
pos[i].y_offset += pos[k].y_advance;
123-
}
113+
// i is the position of the mark; j is the base.
114+
if (j < i)
115+
{
116+
/* This is the common case: mark follows base.
117+
* And currently the only way in OpenType. */
118+
if (HB_DIRECTION_IS_FORWARD (direction))
119+
for (unsigned int k = j; k < i; k++) {
120+
pos[i].x_offset -= pos[k].x_advance;
121+
pos[i].y_offset -= pos[k].y_advance;
122+
}
123+
else
124+
for (unsigned int k = j + 1; k < i + 1; k++) {
125+
pos[i].x_offset += pos[k].x_advance;
126+
pos[i].y_offset += pos[k].y_advance;
127+
}
128+
}
129+
else // j > i
130+
{
131+
/* This can happen with `kerx`: a mark attaching
132+
* to a base after it in the logical order. */
133+
if (HB_DIRECTION_IS_FORWARD (direction))
134+
for (unsigned int k = i; k < j; k++) {
135+
pos[i].x_offset += pos[k].x_advance;
136+
pos[i].y_offset += pos[k].y_advance;
137+
}
138+
else
139+
for (unsigned int k = i + 1; k < j + 1; k++) {
140+
pos[i].x_offset -= pos[k].x_advance;
141+
pos[i].y_offset -= pos[k].y_advance;
142+
}
143+
}
124144
}
125145
}
126146

@@ -149,8 +169,20 @@ GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
149169

150170
/* Handle attachments */
151171
if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT)
152-
for (unsigned i = 0; i < len; i++)
153-
propagate_attachment_offsets (pos, len, i, direction);
172+
{
173+
auto *pos = buffer->pos;
174+
// https://github.com/harfbuzz/harfbuzz/issues/5514
175+
if (HB_DIRECTION_IS_FORWARD (direction))
176+
{
177+
for (unsigned i = 0; i < len; i++)
178+
if (pos[i].attach_chain())
179+
propagate_attachment_offsets (pos, len, i, direction);
180+
} else {
181+
for (unsigned i = len; i-- > 0; )
182+
if (pos[i].attach_chain())
183+
propagate_attachment_offsets (pos, len, i, direction);
184+
}
185+
}
154186

155187
if (unlikely (font->slant_xy) &&
156188
HB_DIRECTION_IS_HORIZONTAL (direction))

thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,30 @@ struct LigatureArray : List16OfOffset16To<LigatureAttach>
1919
bool subset (hb_subset_context_t *c,
2020
Iterator coverage,
2121
unsigned class_count,
22-
const hb_map_t *klass_mapping) const
22+
const hb_map_t *klass_mapping,
23+
hb_sorted_vector_t<hb_codepoint_t> &new_coverage /* OUT */) const
2324
{
2425
TRACE_SUBSET (this);
25-
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
26+
const hb_map_t &glyph_map = c->plan->glyph_map_gsub;
2627

2728
auto *out = c->serializer->start_embed (this);
2829
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
2930

3031
bool ret = false;
3132
for (const auto _ : + hb_zip (coverage, *this)
32-
| hb_filter (glyphset, hb_first))
33+
| hb_filter (glyph_map, hb_first))
3334
{
35+
const LigatureAttach& src = (this + _.second);
36+
bool non_empty = + hb_range (src.rows * class_count)
37+
| hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); })
38+
| hb_map ([&] (const unsigned index) { return !src.offset_is_null (index / class_count, index % class_count, class_count); })
39+
| hb_any;
40+
41+
if (!non_empty) continue;
42+
3443
auto *matrix = out->serialize_append (c->serializer);
3544
if (unlikely (!matrix)) return_trace (false);
3645

37-
const LigatureAttach& src = (this + _.second);
3846
auto indexes =
3947
+ hb_range (src.rows * class_count)
4048
| hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); })
@@ -44,6 +52,9 @@ struct LigatureArray : List16OfOffset16To<LigatureAttach>
4452
this,
4553
src.rows,
4654
indexes);
55+
56+
hb_codepoint_t new_gid = glyph_map.get (_.first);
57+
new_coverage.push (new_gid);
4758
}
4859
return_trace (ret);
4960
}

thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -209,28 +209,35 @@ struct MarkBasePosFormat1_2
209209
;
210210

211211
new_coverage.reset ();
212-
+ base_iter
213-
| hb_map (hb_first)
214-
| hb_map (glyph_map)
215-
| hb_sink (new_coverage)
216-
;
217-
218-
if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ()))
219-
return_trace (false);
220-
221212
hb_sorted_vector_t<unsigned> base_indexes;
222-
for (const unsigned row : + base_iter
223-
| hb_map (hb_second))
213+
auto &base_array = (this+baseArray);
214+
for (const auto _ : + base_iter)
224215
{
216+
unsigned row = _.second;
217+
bool non_empty = + hb_range ((unsigned) classCount)
218+
| hb_filter (klass_mapping)
219+
| hb_map ([&] (const unsigned col) { return !base_array.offset_is_null (row, col, (unsigned) classCount); })
220+
| hb_any
221+
;
222+
223+
if (!non_empty) continue;
224+
225+
hb_codepoint_t new_g = glyph_map.get ( _.first);
226+
new_coverage.push (new_g);
227+
225228
+ hb_range ((unsigned) classCount)
226229
| hb_filter (klass_mapping)
227230
| hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
228231
| hb_sink (base_indexes)
229232
;
230233
}
231234

235+
if (!new_coverage) return_trace (false);
236+
if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ()))
237+
return_trace (false);
238+
232239
return_trace (out->baseArray.serialize_subset (c, baseArray, this,
233-
base_iter.len (),
240+
new_coverage.length,
234241
base_indexes.iter ()));
235242
}
236243
};

0 commit comments

Comments
 (0)