summaryrefslogtreecommitdiffstats
path: root/gfx/harfbuzz
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/harfbuzz')
-rw-r--r--gfx/harfbuzz/NEWS13
-rw-r--r--gfx/harfbuzz/README.md6
-rw-r--r--gfx/harfbuzz/configure.ac8
-rw-r--r--gfx/harfbuzz/moz.yaml4
-rw-r--r--gfx/harfbuzz/src/OT/Layout/GDEF/GDEF.hh50
-rw-r--r--gfx/harfbuzz/src/hb-buffer.cc44
-rw-r--r--gfx/harfbuzz/src/hb-buffer.h6
-rw-r--r--gfx/harfbuzz/src/hb-buffer.hh1
-rw-r--r--gfx/harfbuzz/src/hb-common.h7
-rw-r--r--gfx/harfbuzz/src/hb-ot-layout-gsubgpos.hh5
-rw-r--r--gfx/harfbuzz/src/hb-ot-os2-table.hh8
-rw-r--r--gfx/harfbuzz/src/hb-ot-shape.cc9
-rw-r--r--gfx/harfbuzz/src/hb-serialize.hh60
-rw-r--r--gfx/harfbuzz/src/hb-version.h6
-rw-r--r--gfx/harfbuzz/src/hb-wasm-shape.cc6
15 files changed, 181 insertions, 52 deletions
diff --git a/gfx/harfbuzz/NEWS b/gfx/harfbuzz/NEWS
index 2d6a4a7d6b..e94c6a8937 100644
--- a/gfx/harfbuzz/NEWS
+++ b/gfx/harfbuzz/NEWS
@@ -1,3 +1,16 @@
+Overview of changes leading to 8.4.0
+Saturday, March 29, 2024
+====================================
+- Add /bigobj to MSVC compiler flags in meson build, to fix building hb-subset.cc
+- Specify minimum versions of various dependencies in meson and autotools build.
+- When subsetting, place variation store at the end of “GDEF” table to fix
+ shaping issues with some versions of Adobe InDesign.
+- Various build fixes.
+
+- New API:
++hb_buffer_set_random_state()
++hb_buffer_get_random_state()
+
Overview of changes leading to 8.3.1
Saturday, March 16, 2024
====================================
diff --git a/gfx/harfbuzz/README.md b/gfx/harfbuzz/README.md
index d11c489f10..da4de65cf0 100644
--- a/gfx/harfbuzz/README.md
+++ b/gfx/harfbuzz/README.md
@@ -72,9 +72,9 @@ For a comparison of old vs new HarfBuzz memory consumption see [this][10].
## Name
-HarfBuzz (حرف‌باز) is my Persian translation of “[OpenType][1]”,
-transliterated using the Latin script. It sports a second meaning, but that
-ain’t translatable.
+HarfBuzz (حرف‌باز) is the literal Persian translation of “[OpenType][1]”,
+transliterated using the Latin script. It also means "talkative" or
+"glib" (also a nod to the GNOME project where HarfBuzz originates from).
> Background: Originally there was this font format called TrueType. People and
> companies started calling their type engines all things ending in Type:
diff --git a/gfx/harfbuzz/configure.ac b/gfx/harfbuzz/configure.ac
index d7ac9333e2..40f5994e85 100644
--- a/gfx/harfbuzz/configure.ac
+++ b/gfx/harfbuzz/configure.ac
@@ -1,6 +1,6 @@
AC_PREREQ([2.64])
AC_INIT([HarfBuzz],
- [8.3.1],
+ [8.4.0],
[https://github.com/harfbuzz/harfbuzz/issues/new],
[harfbuzz],
[http://harfbuzz.org/])
@@ -132,7 +132,7 @@ AC_ARG_WITH(glib,
[Use glib @<:@default=auto@:>@])],,
[with_glib=auto])
have_glib=false
-GLIB_DEPS="glib-2.0 >= 2.19.1"
+GLIB_DEPS="glib-2.0 >= 2.30"
AC_SUBST(GLIB_DEPS)
if test "x$with_glib" = "xyes" -o "x$with_glib" = "xauto"; then
PKG_CHECK_MODULES(GLIB, $GLIB_DEPS, have_glib=true, :)
@@ -193,7 +193,7 @@ AC_ARG_WITH(cairo,
[with_cairo=auto])
have_cairo=false
if test "x$with_cairo" = "xyes" -o "x$with_cairo" = "xauto"; then
- PKG_CHECK_MODULES(CAIRO, cairo >= 1.8.0, have_cairo=true, :)
+ PKG_CHECK_MODULES(CAIRO, cairo >= 1.10, have_cairo=true, :)
save_libs=$LIBS
LIBS="$LIBS $CAIRO_LIBS"
AC_CHECK_FUNCS(cairo_user_font_face_set_render_color_glyph_func)
@@ -242,7 +242,7 @@ AC_ARG_WITH(icu,
[with_icu=auto])
have_icu=false
if test "x$with_icu" = "xyes" -o "x$with_icu" = "xbuiltin" -o "x$with_icu" = "xauto"; then
- PKG_CHECK_MODULES(ICU, icu-uc, have_icu=true, :)
+ PKG_CHECK_MODULES(ICU, icu-uc >= 49.0, have_icu=true, :)
fi
if test \( "x$with_icu" = "xyes" -o "x$with_icu" = "xbuiltin" \) -a "x$have_icu" != "xtrue"; then
AC_MSG_ERROR([icu support requested but icu-uc not found])
diff --git a/gfx/harfbuzz/moz.yaml b/gfx/harfbuzz/moz.yaml
index 182f7f4c28..68f979fc84 100644
--- 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: 8.3.1 (2024-03-17T07:50:59+02:00).
+ release: 8.4.0 (2024-03-29T16:32:00+02:00).
# Revision to pull in
# Must be a long or short commit SHA (long preferred)
- revision: 8.3.1
+ revision: 8.4.0
# The package's license, where possible using the mnemonic from
# https://spdx.org/licenses/
diff --git a/gfx/harfbuzz/src/OT/Layout/GDEF/GDEF.hh b/gfx/harfbuzz/src/OT/Layout/GDEF/GDEF.hh
index 475e6d74d1..317b96c714 100644
--- a/gfx/harfbuzz/src/OT/Layout/GDEF/GDEF.hh
+++ b/gfx/harfbuzz/src/OT/Layout/GDEF/GDEF.hh
@@ -663,21 +663,16 @@ struct GDEFVersion1_2
auto *out = c->serializer->start_embed (*this);
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->version.major = version.major;
- out->version.minor = version.minor;
- bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true);
- bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this);
- bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true);
-
- bool subset_markglyphsetsdef = false;
+ // Push var store first (if it's needed) so that it's last in the
+ // serialization order. Some font consumers assume that varstore runs to
+ // the end of the GDEF table.
+ // See: https://github.com/harfbuzz/harfbuzz/issues/4636
auto snapshot_version0 = c->serializer->snapshot ();
- if (version.to_int () >= 0x00010002u)
- {
- if (unlikely (!c->serializer->embed (markGlyphSetsDef))) return_trace (false);
- subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this);
- }
+ if (unlikely (version.to_int () >= 0x00010002u && !c->serializer->embed (markGlyphSetsDef)))
+ return_trace (false);
bool subset_varstore = false;
+ unsigned varstore_index = (unsigned) -1;
auto snapshot_version2 = c->serializer->snapshot ();
if (version.to_int () >= 0x00010003u)
{
@@ -690,35 +685,58 @@ struct GDEFVersion1_2
{
item_variations_t item_vars;
if (item_vars.instantiate (this+varStore, c->plan, true, true,
- c->plan->gdef_varstore_inner_maps.as_array ()))
+ c->plan->gdef_varstore_inner_maps.as_array ())) {
subset_varstore = out->varStore.serialize_serialize (c->serializer,
item_vars.has_long_word (),
c->plan->axis_tags,
item_vars.get_region_list (),
item_vars.get_vardata_encodings ());
+ varstore_index = c->serializer->last_added_child_index();
+ }
remap_varidx_after_instantiation (item_vars.get_varidx_map (),
c->plan->layout_variation_idx_delta_map);
}
}
else
+ {
subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ());
+ varstore_index = c->serializer->last_added_child_index();
+ }
+ }
+
+ out->version.major = version.major;
+ out->version.minor = version.minor;
+
+ if (!subset_varstore && version.to_int () >= 0x00010002u) {
+ c->serializer->revert (snapshot_version2);
}
+ bool subset_markglyphsetsdef = false;
+ if (version.to_int () >= 0x00010002u)
+ {
+ subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this);
+ }
if (subset_varstore)
{
out->version.minor = 3;
c->plan->has_gdef_varstore = true;
} else if (subset_markglyphsetsdef) {
- out->version.minor = 2;
- c->serializer->revert (snapshot_version2);
+ out->version.minor = 2;
} else {
out->version.minor = 0;
c->serializer->revert (snapshot_version0);
}
+ bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true);
+ bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this);
+ bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true);
bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this);
+ if (subset_varstore && varstore_index != (unsigned) -1) {
+ c->serializer->repack_last(varstore_index);
+ }
+
return_trace (subset_glyphclassdef || subset_attachlist ||
subset_ligcaretlist || subset_markattachclassdef ||
(out->version.to_int () >= 0x00010002u && subset_markglyphsetsdef) ||
@@ -1013,7 +1031,7 @@ struct GDEF
if (!has_var_store ()) return;
const ItemVariationStore &var_store = get_var_store ();
float *store_cache = var_store.create_cache ();
-
+
unsigned new_major = 0, new_minor = 0;
unsigned last_major = (layout_variation_indices->get_min ()) >> 16;
for (unsigned idx : layout_variation_indices->iter ())
diff --git a/gfx/harfbuzz/src/hb-buffer.cc b/gfx/harfbuzz/src/hb-buffer.cc
index 934c6c2129..d621a7cc55 100644
--- a/gfx/harfbuzz/src/hb-buffer.cc
+++ b/gfx/harfbuzz/src/hb-buffer.cc
@@ -309,6 +309,7 @@ hb_buffer_t::clear ()
deallocate_var_all ();
serial = 0;
+ random_state = 1;
scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
}
@@ -1359,6 +1360,49 @@ hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer)
return buffer->not_found;
}
+/**
+ * hb_buffer_set_random_state:
+ * @buffer: An #hb_buffer_t
+ * @state: the new random state
+ *
+ * Sets the random state of the buffer. The state changes
+ * every time a glyph uses randomness (eg. the `rand`
+ * OpenType feature). This function together with
+ * hb_buffer_get_random_state() allow for transferring
+ * the current random state to a subsequent buffer, to
+ * get better randomness distribution.
+ *
+ * Defaults to 1 and when buffer contents are cleared.
+ * A value of 0 disables randomness during shaping.
+ *
+ * Since: 8.4.0
+ **/
+void
+hb_buffer_set_random_state (hb_buffer_t *buffer,
+ unsigned state)
+{
+ if (unlikely (hb_object_is_immutable (buffer)))
+ return;
+
+ buffer->random_state = state;
+}
+
+/**
+ * hb_buffer_get_random_state:
+ * @buffer: An #hb_buffer_t
+ *
+ * See hb_buffer_set_random_state().
+ *
+ * Return value:
+ * The @buffer random state
+ *
+ * Since: 8.4.0
+ **/
+unsigned
+hb_buffer_get_random_state (const hb_buffer_t *buffer)
+{
+ return buffer->random_state;
+}
/**
* hb_buffer_clear_contents:
diff --git a/gfx/harfbuzz/src/hb-buffer.h b/gfx/harfbuzz/src/hb-buffer.h
index 3573127ff0..f75fe96b21 100644
--- a/gfx/harfbuzz/src/hb-buffer.h
+++ b/gfx/harfbuzz/src/hb-buffer.h
@@ -487,6 +487,12 @@ hb_buffer_set_not_found_glyph (hb_buffer_t *buffer,
HB_EXTERN hb_codepoint_t
hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer);
+HB_EXTERN void
+hb_buffer_set_random_state (hb_buffer_t *buffer,
+ unsigned state);
+
+HB_EXTERN unsigned
+hb_buffer_get_random_state (const hb_buffer_t *buffer);
/*
* Content API.
diff --git a/gfx/harfbuzz/src/hb-buffer.hh b/gfx/harfbuzz/src/hb-buffer.hh
index f04ad58f11..0a198722d6 100644
--- a/gfx/harfbuzz/src/hb-buffer.hh
+++ b/gfx/harfbuzz/src/hb-buffer.hh
@@ -116,6 +116,7 @@ struct hb_buffer_t
uint8_t allocated_var_bits;
uint8_t serial;
+ uint32_t random_state;
hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */
unsigned int max_len; /* Maximum allowed len. */
int max_ops; /* Maximum allowed operations. */
diff --git a/gfx/harfbuzz/src/hb-common.h b/gfx/harfbuzz/src/hb-common.h
index dfdefc627e..533de91562 100644
--- a/gfx/harfbuzz/src/hb-common.h
+++ b/gfx/harfbuzz/src/hb-common.h
@@ -49,8 +49,8 @@
#if defined (_AIX)
# include <sys/inttypes.h>
-#elif defined (_MSC_VER) && _MSC_VER < 1800
-/* VS 2013 (_MSC_VER 1800) has inttypes.h */
+#elif defined (_MSC_VER) && _MSC_VER < 1600
+/* VS 2010 (_MSC_VER 1600) has stdint.h */
typedef __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
@@ -59,6 +59,9 @@ typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
+#elif defined (_MSC_VER) && _MSC_VER < 1800
+/* VS 2013 (_MSC_VER 1800) has inttypes.h */
+# include <stdint.h>
#else
# include <inttypes.h>
#endif
diff --git a/gfx/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/gfx/harfbuzz/src/hb-ot-layout-gsubgpos.hh
index 162179d08a..c65ea32b8a 100644
--- a/gfx/harfbuzz/src/hb-ot-layout-gsubgpos.hh
+++ b/gfx/harfbuzz/src/hb-ot-layout-gsubgpos.hh
@@ -723,7 +723,6 @@ struct hb_ot_apply_context_t :
bool auto_zwj = true;
bool per_syllable = false;
bool random = false;
- uint32_t random_state = 1;
unsigned new_syllables = (unsigned) -1;
signed last_base = -1; // GPOS uses
@@ -788,8 +787,8 @@ struct hb_ot_apply_context_t :
uint32_t random_number ()
{
/* http://www.cplusplus.com/reference/random/minstd_rand/ */
- random_state = random_state * 48271 % 2147483647;
- return random_state;
+ buffer->random_state = buffer->random_state * 48271 % 2147483647;
+ return buffer->random_state;
}
bool match_properties_mark (hb_codepoint_t glyph,
diff --git a/gfx/harfbuzz/src/hb-ot-os2-table.hh b/gfx/harfbuzz/src/hb-ot-os2-table.hh
index 8c2e696f56..43b58d9bbf 100644
--- a/gfx/harfbuzz/src/hb-ot-os2-table.hh
+++ b/gfx/harfbuzz/src/hb-ot-os2-table.hh
@@ -223,7 +223,7 @@ struct OS2
}
}
- return num ? (unsigned) roundf (total_width / num) : 0;
+ return num ? (unsigned) roundf ((double) total_width / (double) num) : 0;
}
bool subset (hb_subset_context_t *c) const
@@ -284,12 +284,12 @@ struct OS2
os2_prime->usWidthClass = width_class;
}
- if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES)
- return_trace (true);
-
os2_prime->usFirstCharIndex = hb_min (0xFFFFu, c->plan->unicodes.get_min ());
os2_prime->usLastCharIndex = hb_min (0xFFFFu, c->plan->unicodes.get_max ());
+ if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES)
+ return_trace (true);
+
_update_unicode_ranges (&c->plan->unicodes, os2_prime->ulUnicodeRange);
return_trace (true);
diff --git a/gfx/harfbuzz/src/hb-ot-shape.cc b/gfx/harfbuzz/src/hb-ot-shape.cc
index 90f596ae79..148830022e 100644
--- a/gfx/harfbuzz/src/hb-ot-shape.cc
+++ b/gfx/harfbuzz/src/hb-ot-shape.cc
@@ -155,7 +155,7 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
#endif
bool has_gpos = !disable_gpos && hb_ot_layout_has_positioning (face);
if (false)
- ;
+ {}
#ifndef HB_NO_AAT_SHAPE
/* Prefer GPOS over kerx if GSUB is present;
* https://github.com/harfbuzz/harfbuzz/issues/3008 */
@@ -167,15 +167,16 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
if (!plan.apply_kerx && (!has_gpos_kern || !plan.apply_gpos))
{
+ if (false) {}
#ifndef HB_NO_AAT_SHAPE
- if (has_kerx)
+ else if (has_kerx)
plan.apply_kerx = true;
- else
#endif
#ifndef HB_NO_OT_KERN
- if (hb_ot_layout_has_kerning (face))
+ else if (hb_ot_layout_has_kerning (face))
plan.apply_kern = true;
#endif
+ else {}
}
plan.apply_fallback_kern = !(plan.apply_gpos || plan.apply_kerx || plan.apply_kern);
diff --git a/gfx/harfbuzz/src/hb-serialize.hh b/gfx/harfbuzz/src/hb-serialize.hh
index 73634e6b93..e988451eb3 100644
--- a/gfx/harfbuzz/src/hb-serialize.hh
+++ b/gfx/harfbuzz/src/hb-serialize.hh
@@ -91,6 +91,26 @@ struct hb_serialize_context_t
}
#endif
+ bool add_virtual_link (objidx_t objidx)
+ {
+ if (!objidx)
+ return false;
+
+ auto& link = *virtual_links.push ();
+ if (virtual_links.in_error ())
+ return false;
+
+ link.objidx = objidx;
+ // Remaining fields were previously zero'd by push():
+ // link.width = 0;
+ // link.is_signed = 0;
+ // link.whence = 0;
+ // link.position = 0;
+ // link.bias = 0;
+
+ return true;
+ }
+
friend void swap (object_t& a, object_t& b) noexcept
{
hb_swap (a.head, b.head);
@@ -469,16 +489,40 @@ struct hb_serialize_context_t
assert (current);
- auto& link = *current->virtual_links.push ();
- if (current->virtual_links.in_error ())
+ if (!current->add_virtual_link(objidx))
err (HB_SERIALIZE_ERROR_OTHER);
+ }
- link.width = 0;
- link.objidx = objidx;
- link.is_signed = 0;
- link.whence = 0;
- link.position = 0;
- link.bias = 0;
+ objidx_t last_added_child_index() const {
+ if (unlikely (in_error ())) return (objidx_t) -1;
+
+ assert (current);
+ if (!bool(current->real_links)) {
+ return (objidx_t) -1;
+ }
+
+ return current->real_links[current->real_links.length - 1].objidx;
+ }
+
+ // For the current object ensure that the sub-table bytes for child objidx are always placed
+ // after the subtable bytes for any other existing children. This only ensures that the
+ // repacker will not move the target subtable before the other children
+ // (by adding virtual links). It is up to the caller to ensure the initial serialization
+ // order is correct.
+ void repack_last(objidx_t objidx) {
+ if (unlikely (in_error ())) return;
+
+ if (!objidx)
+ return;
+
+ assert (current);
+ for (auto& l : current->real_links) {
+ if (l.objidx == objidx) {
+ continue;
+ }
+
+ packed[l.objidx]->add_virtual_link(objidx);
+ }
}
template <typename T>
diff --git a/gfx/harfbuzz/src/hb-version.h b/gfx/harfbuzz/src/hb-version.h
index d90e36391c..68681874ca 100644
--- a/gfx/harfbuzz/src/hb-version.h
+++ b/gfx/harfbuzz/src/hb-version.h
@@ -47,20 +47,20 @@ HB_BEGIN_DECLS
*
* The minor component of the library version available at compile-time.
*/
-#define HB_VERSION_MINOR 3
+#define HB_VERSION_MINOR 4
/**
* HB_VERSION_MICRO:
*
* The micro component of the library version available at compile-time.
*/
-#define HB_VERSION_MICRO 1
+#define HB_VERSION_MICRO 0
/**
* HB_VERSION_STRING:
*
* A string literal containing the library version available at compile-time.
*/
-#define HB_VERSION_STRING "8.3.1"
+#define HB_VERSION_STRING "8.4.0"
/**
* HB_VERSION_ATLEAST:
diff --git a/gfx/harfbuzz/src/hb-wasm-shape.cc b/gfx/harfbuzz/src/hb-wasm-shape.cc
index a70b766646..a8b91879a4 100644
--- a/gfx/harfbuzz/src/hb-wasm-shape.cc
+++ b/gfx/harfbuzz/src/hb-wasm-shape.cc
@@ -240,7 +240,7 @@ acquire_shape_plan (hb_face_t *face,
goto fail;
}
- func = wasm_runtime_lookup_function (module_inst, "shape_plan_create", nullptr);
+ func = wasm_runtime_lookup_function (module_inst, "shape_plan_create");
if (func)
{
wasm_val_t results[1];
@@ -297,7 +297,7 @@ release_shape_plan (const hb_wasm_face_data_t *face_data,
if (plan->wasm_shape_planptr)
{
- auto *func = wasm_runtime_lookup_function (module_inst, "shape_plan_destroy", nullptr);
+ auto *func = wasm_runtime_lookup_function (module_inst, "shape_plan_destroy");
if (func)
{
wasm_val_t arguments[1];
@@ -395,7 +395,7 @@ retry:
goto fail;
}
- func = wasm_runtime_lookup_function (module_inst, "shape", nullptr);
+ func = wasm_runtime_lookup_function (module_inst, "shape");
if (unlikely (!func))
{
DEBUG_MSG (WASM, module_inst, "Shape function not found.");