Bug 1888698 - Update harfbuzz to 8.4.0 r=jfkthame

Differential Revision: https://phabricator.services.mozilla.com/D206139
This commit is contained in:
Updatebot 2024-04-15 12:39:32 +00:00
parent 37d28f9cf5
commit af7a80a012
15 changed files with 181 additions and 52 deletions

View file

@ -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
====================================

View file

@ -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
aint 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:

View file

@ -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])

View file

@ -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/

View file

@ -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 ())

View file

@ -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:

View file

@ -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.

View file

@ -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. */

View file

@ -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

View file

@ -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,

View file

@ -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);

View file

@ -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);

View file

@ -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>

View file

@ -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:

View file

@ -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.");