commit e944aead54319f0718b27a3cb2bc7207b95135dc
parent 0c730e993de2c7c247d767968d81dbab50591f69
Author: Updatebot <updatebot@mozilla.com>
Date: Thu, 2 Oct 2025 09:13:55 +0000
Bug 1991827 - Update harfbuzz to 12.1.0 r=jfkthame
Differential Revision: https://phabricator.services.mozilla.com/D266957
Diffstat:
15 files changed, 172 insertions(+), 13 deletions(-)
diff --git a/gfx/harfbuzz/NEWS b/gfx/harfbuzz/NEWS
@@ -1,3 +1,17 @@
+Overview of changes leading to 12.1.0
+Wednesday, October 1, 2025
+=====================================
+- Build fixes with GCC 15 on some 32 bit platforms.
+- Fix misaligned pointer use.
+- New API, `hb_ot_layout_lookup_collect_glyph_alternates()`, to collect glyph
+ substitutions from single and alternate substitution lookups in one call,
+ instead of getting substitutions one by one using
+ `hb_ot_layout_lookup_get_glyph_alternates()`.
+
+- New API
++hb_ot_layout_lookup_collect_glyph_alternates()
+
+
Overview of changes leading to 12.0.0
Sunday, September 28, 2025
=====================================
diff --git a/gfx/harfbuzz/moz.yaml b/gfx/harfbuzz/moz.yaml
@@ -20,11 +20,11 @@ origin:
# Human-readable identifier for this version/release
# Generally "version NNN", "tag SSS", "bookmark SSS"
- release: 12.0.0 (2025-09-28T00:55:46+03:00).
+ release: 12.1.0 (2025-10-01T08:26:58+03:00).
# Revision to pull in
# Must be a long or short commit SHA (long preferred)
- revision: 12.0.0
+ revision: 12.1.0
# The package's license, where possible using the mnemonic from
# https://spdx.org/licenses/
diff --git a/gfx/harfbuzz/src/OT/Layout/Common/Coverage.hh b/gfx/harfbuzz/src/OT/Layout/Common/Coverage.hh
@@ -337,7 +337,7 @@ struct Coverage
}
iter_t __end__ () const
{
- iter_t it = {};
+ iter_t it;
it.format = format;
switch (format)
{
diff --git a/gfx/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh b/gfx/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh
@@ -91,6 +91,19 @@ struct AlternateSet
return alternates.len;
}
+ void
+ collect_alternates (hb_codepoint_t gid,
+ hb_map_t *alternate_count /* IN/OUT */,
+ hb_map_t *alternate_glyphs /* IN/OUT */) const
+ {
+ + hb_enumerate (alternates)
+ | hb_map ([gid] (hb_pair_t<unsigned, hb_codepoint_t> _) { return hb_pair (gid + (_.first << 24), _.second); })
+ | hb_apply ([&] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t> &p) -> void
+ { _hb_collect_glyph_alternates_add (p.first, p.second,
+ alternate_count, alternate_glyphs); })
+ ;
+ }
+
template <typename Iterator,
hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))>
bool serialize (hb_serialize_context_t *c,
diff --git a/gfx/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh b/gfx/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh
@@ -69,6 +69,19 @@ struct AlternateSubstFormat1_2
{ return (this+alternateSet[(this+coverage).get_coverage (gid)])
.get_alternates (start_offset, alternate_count, alternate_glyphs); }
+ void
+ collect_glyph_alternates (hb_map_t *alternate_count /* IN/OUT */,
+ hb_map_t *alternate_glyphs /* IN/OUT */) const
+ {
+ + hb_iter (alternateSet)
+ | hb_map (hb_add (this))
+ | hb_zip (this+coverage)
+ | hb_apply ([&] (const hb_pair_t<const AlternateSet<Types> &, hb_codepoint_t> _) {
+ _.first.collect_alternates (_.second, alternate_count, alternate_glyphs);
+ })
+ ;
+ }
+
bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
diff --git a/gfx/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/gfx/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh
@@ -123,6 +123,21 @@ struct SingleSubstFormat1_3
return 1;
}
+ void
+ collect_glyph_alternates (hb_map_t *alternate_count /* IN/OUT */,
+ hb_map_t *alternate_glyphs /* IN/OUT */) const
+ {
+ hb_codepoint_t d = deltaGlyphID;
+ hb_codepoint_t mask = get_mask ();
+
+ + hb_iter (this+coverage)
+ | hb_map ([d, mask] (hb_codepoint_t g) { return hb_pair (g, (g + d) & mask); })
+ | hb_apply ([&] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t> &p) -> void
+ { _hb_collect_glyph_alternates_add (p.first, p.second,
+ alternate_count, alternate_glyphs); })
+ ;
+ }
+
bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
diff --git a/gfx/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh b/gfx/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh
@@ -100,6 +100,17 @@ struct SingleSubstFormat2_4
return 1;
}
+ void
+ collect_glyph_alternates (hb_map_t *alternate_count /* IN/OUT */,
+ hb_map_t *alternate_glyphs /* IN/OUT */) const
+ {
+ + hb_zip (this+coverage, substitute)
+ | hb_apply ([&] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t> &p) -> void
+ { _hb_collect_glyph_alternates_add (p.first, p.second,
+ alternate_count, alternate_glyphs); })
+ ;
+ }
+
bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
diff --git a/gfx/harfbuzz/src/hb-alloc-pool.hh b/gfx/harfbuzz/src/hb-alloc-pool.hh
@@ -67,8 +67,7 @@ struct hb_alloc_pool_t
return ret;
}
- unsigned pad = current_chunk.length & (alignment - 1);
- if (pad) pad = alignment - pad;
+ unsigned pad = (unsigned)(-(uintptr_t) current_chunk.arrayZ) & (alignment - 1);
// Small chunk, allocate from the last chunk.
if (current_chunk.length < pad + size)
@@ -78,9 +77,10 @@ struct hb_alloc_pool_t
hb_vector_t<char> &chunk = chunks.arrayZ[chunks.length - 1];
if (unlikely (!chunk.resize (ChunkSize))) return nullptr;
current_chunk = chunk;
+ pad = (unsigned)(-(uintptr_t) current_chunk.arrayZ) & (alignment - 1);
}
- else
- current_chunk += pad;
+
+ current_chunk += pad;
assert (current_chunk.length >= size);
void *ret = current_chunk.arrayZ;
diff --git a/gfx/harfbuzz/src/hb-map.hh b/gfx/harfbuzz/src/hb-map.hh
@@ -491,10 +491,17 @@ struct hb_hashmap_t
/* Sink interface. */
hb_hashmap_t& operator << (const hb_pair_t<K, V>& v)
{ set (v.first, v.second); return *this; }
+ template <typename V2 = V,
+ hb_enable_if (!std::is_trivially_copyable<V2>::value)>
hb_hashmap_t& operator << (const hb_pair_t<K, V&&>& v)
{ set (v.first, std::move (v.second)); return *this; }
+ template <typename K2 = K,
+ hb_enable_if (!std::is_trivially_copyable<K2>::value)>
hb_hashmap_t& operator << (const hb_pair_t<K&&, V>& v)
{ set (std::move (v.first), v.second); return *this; }
+ template <typename K2 = K, typename V2 = V,
+ hb_enable_if (!std::is_trivially_copyable<K2>::value &&
+ !std::is_trivially_copyable<V2>::value)>
hb_hashmap_t& operator << (const hb_pair_t<K&&, V&&>& v)
{ set (std::move (v.first), std::move (v.second)); return *this; }
diff --git a/gfx/harfbuzz/src/hb-ot-layout.cc b/gfx/harfbuzz/src/hb-ot-layout.cc
@@ -2597,6 +2597,7 @@ hb_ot_layout_get_baseline_with_fallback2 (hb_font_t *font,
#endif
+#ifndef HB_NO_LAYOUT_RARELY_USED
struct hb_get_glyph_alternates_dispatch_t :
hb_dispatch_context_t<hb_get_glyph_alternates_dispatch_t, unsigned>
{
@@ -2616,7 +2617,6 @@ struct hb_get_glyph_alternates_dispatch_t :
( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
};
-#ifndef HB_NO_LAYOUT_RARELY_USED
/**
* hb_ot_layout_lookup_get_glyph_alternates:
* @face: a face.
@@ -2650,6 +2650,64 @@ hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face,
return ret;
}
+struct hb_collect_glyph_alternates_dispatch_t :
+ hb_dispatch_context_t<hb_collect_glyph_alternates_dispatch_t, bool>
+{
+ static return_t default_return_value () { return false; }
+ bool stop_sublookup_iteration (return_t r) const { return false; }
+
+ private:
+ template <typename T, typename ...Ts> auto
+ _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
+ ( (obj.collect_glyph_alternates (std::forward<Ts> (ds)...), true) )
+ template <typename T, typename ...Ts> auto
+ _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
+ ( default_return_value () )
+ public:
+ template <typename T, typename ...Ts> auto
+ dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
+ ( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
+};
+
+/**
+ * hb_ot_layout_lookup_collect_glyph_alternates:
+ * @face: a face.
+ * @lookup_index: index of the feature lookup to query.
+ * @alternate_count: (inout): mapping from glyph index to number of alternates for that glyph.
+ * @alternate_glyphs: (inout): mapping from encoded glyph index and alternate index, to alternate glyph ids.
+ *
+ * Collects alternates of glyphs from a given GSUB lookup index.
+ *
+ * For one-to-one GSUB glyph substitutions, this function collects the
+ * substituted glyph.
+ *
+ * For lookups that assign multiple alternates to a glyph, all alternate glyphs are collected.
+ *
+ * For other lookup types, nothing is performed and `false` is returned.
+ *
+ * The `alternate_count` mapping will contain the number of alternates for each glyph id.
+ * Upon entry, this mapping should contain the glyph ids as keys, and the number of alternates
+ * currently known for each glyph id as values.
+ *
+ * The `alternate_glyphs` mapping will contain the alternate glyph ids for each glyph id.
+ * The mapping is encoded in the following way, upon entry and after processing:
+ * If G is the glyph id, and A0, A1, ..., A(n-1) are the alternate glyph ids,
+ * the mapping will contain the following entries: (G + (i << 24)) -> A(i)
+ * for i = 0, 1, ..., n-1 where n is the number of alternates for G as per `alternate_count`.
+ *
+ * Return value: `true` if alternates were collected, `false` otherwise.
+ * Since: 12.1.0
+ */
+HB_EXTERN hb_bool_t
+hb_ot_layout_lookup_collect_glyph_alternates (hb_face_t *face,
+ unsigned lookup_index,
+ hb_map_t *alternate_count /* IN/OUT */,
+ hb_map_t *alternate_glyphs /* IN/OUT */)
+{
+ hb_collect_glyph_alternates_dispatch_t c;
+ const OT::SubstLookup &lookup = face->table.GSUB->table->get_lookup (lookup_index);
+ return lookup.dispatch (&c, alternate_count, alternate_glyphs);
+}
struct hb_position_single_dispatch_t :
hb_dispatch_context_t<hb_position_single_dispatch_t, bool>
diff --git a/gfx/harfbuzz/src/hb-ot-layout.h b/gfx/harfbuzz/src/hb-ot-layout.h
@@ -384,6 +384,12 @@ hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face,
hb_codepoint_t *alternate_glyphs /* OUT */);
HB_EXTERN hb_bool_t
+hb_ot_layout_lookup_collect_glyph_alternates (hb_face_t *face,
+ unsigned lookup_index,
+ hb_map_t *alternate_count /* IN/OUT */,
+ hb_map_t *alternate_glyphs /* IN/OUT */);
+
+HB_EXTERN hb_bool_t
hb_ot_layout_lookup_would_substitute (hb_face_t *face,
unsigned int lookup_index,
const hb_codepoint_t *glyphs,
diff --git a/gfx/harfbuzz/src/hb-ot-layout.hh b/gfx/harfbuzz/src/hb-ot-layout.hh
@@ -645,4 +645,18 @@ _hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer)
#undef lig_props
#undef glyph_props
+static inline void
+_hb_collect_glyph_alternates_add (hb_codepoint_t from,
+ hb_codepoint_t to,
+ hb_map_t *alternate_count,
+ hb_map_t *alternate_glyphs)
+{
+ hb_codepoint_t zero = 0;
+ hb_codepoint_t *i = &zero;
+ alternate_count->has (from, &i);
+ alternate_glyphs->set (from | (*i << 24), to);
+ alternate_count->set (from, *i + 1);
+}
+
+
#endif /* HB_OT_LAYOUT_HH */
diff --git a/gfx/harfbuzz/src/hb-script-list.h b/gfx/harfbuzz/src/hb-script-list.h
@@ -466,7 +466,7 @@ typedef enum
HB_SCRIPT_TULU_TIGALARI = HB_TAG ('T','u','t','g'), /*16.0*/
/*
- * Since REPLACEME
+ * Since 11.5.0
*/
HB_SCRIPT_BERIA_ERFE = HB_TAG ('B','e','r','f'), /*17.0*/
HB_SCRIPT_SIDETIC = HB_TAG ('S','i','d','t'), /*17.0*/
diff --git a/gfx/harfbuzz/src/hb-version.h b/gfx/harfbuzz/src/hb-version.h
@@ -47,7 +47,7 @@ HB_BEGIN_DECLS
*
* The minor component of the library version available at compile-time.
*/
-#define HB_VERSION_MINOR 0
+#define HB_VERSION_MINOR 1
/**
* HB_VERSION_MICRO:
*
@@ -60,7 +60,7 @@ HB_BEGIN_DECLS
*
* A string literal containing the library version available at compile-time.
*/
-#define HB_VERSION_STRING "12.0.0"
+#define HB_VERSION_STRING "12.1.0"
/**
* HB_VERSION_ATLEAST:
diff --git a/gfx/harfbuzz/src/hb.hh b/gfx/harfbuzz/src/hb.hh
@@ -89,7 +89,6 @@
#pragma GCC diagnostic error "-Wstring-conversion"
#pragma GCC diagnostic error "-Wswitch-enum"
#pragma GCC diagnostic error "-Wtautological-overlap-compare"
-#pragma GCC diagnostic error "-Wuninitialized"
#pragma GCC diagnostic error "-Wunneeded-internal-declaration"
#pragma GCC diagnostic error "-Wunused"
#pragma GCC diagnostic error "-Wunused-local-typedefs"
@@ -110,12 +109,21 @@
#pragma GCC diagnostic warning "-Wformat-signedness"
#pragma GCC diagnostic warning "-Wignored-pragma-optimize"
#pragma GCC diagnostic warning "-Wlogical-op"
-#pragma GCC diagnostic warning "-Wmaybe-uninitialized"
#pragma GCC diagnostic warning "-Wmissing-format-attribute"
#pragma GCC diagnostic warning "-Wpessimizing-move"
#pragma GCC diagnostic warning "-Wundef"
#pragma GCC diagnostic warning "-Wunsafe-loop-optimizations"
#pragma GCC diagnostic warning "-Wunused-but-set-variable"
+#ifdef __clang__
+// The following are too buggy on gcc
+// https://github.com/harfbuzz/harfbuzz/issues/5589
+// https://github.com/harfbuzz/harfbuzz/pull/5367
+#pragma GCC diagnostic warning "-Wmaybe-uninitialized"
+#pragma GCC diagnostic warning "-Wuninitialized"
+#else
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wuninitialized"
+#endif
#endif
/* Ignored currently, but should be fixed at some point. */