summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc')
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc634
1 files changed, 413 insertions, 221 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc
index e2e325f12b..68a3e77788 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc
@@ -24,38 +24,24 @@
* Google Author(s): Garret Rieger, Rod Sheeter, Behdad Esfahbod
*/
+#include "hb-subset-instancer-solver.hh"
#include "hb-subset.hh"
#include "hb-set.hh"
+#include "hb-utf.hh"
-/**
- * hb_subset_input_create_or_fail:
- *
- * Creates a new subset input object.
- *
- * Return value: (transfer full): New subset input, or %NULL if failed. Destroy
- * with hb_subset_input_destroy().
- *
- * Since: 1.8.0
- **/
-hb_subset_input_t *
-hb_subset_input_create_or_fail (void)
+
+hb_subset_input_t::hb_subset_input_t ()
{
- hb_subset_input_t *input = hb_object_create<hb_subset_input_t>();
+ for (auto& set : sets_iter ())
+ set = hb::shared_ptr<hb_set_t> (hb_set_create ());
- if (unlikely (!input))
- return nullptr;
+ if (in_error ())
+ return;
- input->unicodes = hb_set_create ();
- input->glyphs = hb_set_create ();
- input->name_ids = hb_set_create ();
- hb_set_add_range (input->name_ids, 0, 6);
- input->name_languages = hb_set_create ();
- hb_set_add (input->name_languages, 0x0409);
- input->layout_features = hb_set_create ();
- input->drop_tables = hb_set_create ();
- input->no_subset_tables = hb_set_create ();
+ flags = HB_SUBSET_FLAGS_DEFAULT;
- input->flags = HB_SUBSET_FLAGS_DEFAULT;
+ hb_set_add_range (sets.name_ids, 0, 6);
+ hb_set_add (sets.name_languages, 0x0409);
hb_tag_t default_drop_tables[] = {
// Layout disabled by default
@@ -65,7 +51,6 @@ hb_subset_input_create_or_fail (void)
HB_TAG ('k', 'e', 'r', 'n'),
// Copied from fontTools:
- HB_TAG ('B', 'A', 'S', 'E'),
HB_TAG ('J', 'S', 'T', 'F'),
HB_TAG ('D', 'S', 'I', 'G'),
HB_TAG ('E', 'B', 'D', 'T'),
@@ -81,23 +66,17 @@ hb_subset_input_create_or_fail (void)
HB_TAG ('S', 'i', 'l', 'f'),
HB_TAG ('S', 'i', 'l', 'l'),
};
- input->drop_tables->add_array (default_drop_tables, ARRAY_LENGTH (default_drop_tables));
+ sets.drop_tables->add_array (default_drop_tables, ARRAY_LENGTH (default_drop_tables));
hb_tag_t default_no_subset_tables[] = {
- HB_TAG ('a', 'v', 'a', 'r'),
- HB_TAG ('f', 'v', 'a', 'r'),
HB_TAG ('g', 'a', 's', 'p'),
- HB_TAG ('c', 'v', 't', ' '),
HB_TAG ('f', 'p', 'g', 'm'),
HB_TAG ('p', 'r', 'e', 'p'),
HB_TAG ('V', 'D', 'M', 'X'),
HB_TAG ('D', 'S', 'I', 'G'),
- HB_TAG ('M', 'V', 'A', 'R'),
- HB_TAG ('c', 'v', 'a', 'r'),
- HB_TAG ('S', 'T', 'A', 'T'),
};
- input->no_subset_tables->add_array (default_no_subset_tables,
- ARRAY_LENGTH (default_no_subset_tables));
+ sets.no_subset_tables->add_array (default_no_subset_tables,
+ ARRAY_LENGTH (default_no_subset_tables));
//copied from _layout_features_groups in fonttools
hb_tag_t default_layout_features[] = {
@@ -138,7 +117,26 @@ hb_subset_input_create_or_fail (void)
HB_TAG ('r', 't', 'l', 'a'),
HB_TAG ('r', 't', 'l', 'm'),
- //Complex shapers
+ //random
+ HB_TAG ('r', 'a', 'n', 'd'),
+
+ //justify
+ HB_TAG ('j', 'a', 'l', 't'), // HarfBuzz doesn't use; others might
+
+ //East Asian spacing
+ HB_TAG ('c', 'h', 'w', 's'),
+ HB_TAG ('v', 'c', 'h', 'w'),
+ HB_TAG ('h', 'a', 'l', 't'),
+ HB_TAG ('v', 'h', 'a', 'l'),
+
+ //private
+ HB_TAG ('H', 'a', 'r', 'f'),
+ HB_TAG ('H', 'A', 'R', 'F'),
+ HB_TAG ('B', 'u', 'z', 'z'),
+ HB_TAG ('B', 'U', 'Z', 'Z'),
+
+ //shapers
+
//arabic
HB_TAG ('i', 'n', 'i', 't'),
HB_TAG ('m', 'e', 'd', 'i'),
@@ -186,7 +184,35 @@ hb_subset_input_create_or_fail (void)
HB_TAG ('b', 'l', 'w', 'm'),
};
- input->layout_features->add_array (default_layout_features, ARRAY_LENGTH (default_layout_features));
+ sets.layout_features->add_array (default_layout_features, ARRAY_LENGTH (default_layout_features));
+
+ sets.layout_scripts->invert (); // Default to all scripts.
+}
+
+/**
+ * hb_subset_input_create_or_fail:
+ *
+ * Creates a new subset input object.
+ *
+ * Return value: (transfer full): New subset input, or `NULL` if failed. Destroy
+ * with hb_subset_input_destroy().
+ *
+ * Since: 1.8.0
+ **/
+hb_subset_input_t *
+hb_subset_input_create_or_fail (void)
+{
+ hb_subset_input_t *input = hb_object_create<hb_subset_input_t>();
+
+ if (unlikely (!input))
+ return nullptr;
+
+ if (input->in_error ())
+ {
+ hb_subset_input_destroy (input);
+ return nullptr;
+ }
+
return input;
}
@@ -220,14 +246,6 @@ hb_subset_input_destroy (hb_subset_input_t *input)
{
if (!hb_object_destroy (input)) return;
- hb_set_destroy (input->unicodes);
- hb_set_destroy (input->glyphs);
- hb_set_destroy (input->name_ids);
- hb_set_destroy (input->name_languages);
- hb_set_destroy (input->drop_tables);
- hb_set_destroy (input->layout_features);
- hb_set_destroy (input->no_subset_tables);
-
hb_free (input);
}
@@ -246,7 +264,7 @@ hb_subset_input_destroy (hb_subset_input_t *input)
HB_EXTERN hb_set_t *
hb_subset_input_unicode_set (hb_subset_input_t *input)
{
- return input->unicodes;
+ return input->sets.unicodes;
}
/**
@@ -263,100 +281,32 @@ hb_subset_input_unicode_set (hb_subset_input_t *input)
HB_EXTERN hb_set_t *
hb_subset_input_glyph_set (hb_subset_input_t *input)
{
- return input->glyphs;
+ return input->sets.glyphs;
}
/**
- * hb_subset_input_nameid_set:
+ * hb_subset_input_set:
* @input: a #hb_subset_input_t object.
+ * @set_type: a #hb_subset_sets_t set type.
*
- * Gets the set of name table name IDs to retain, the caller should modify the
- * set as needed.
+ * Gets the set of the specified type.
*
- * Return value: (transfer none): pointer to the #hb_set_t of name IDs.
+ * Return value: (transfer none): pointer to the #hb_set_t of the specified type.
*
- * Since: 2.9.0
+ * Since: 2.9.1
**/
HB_EXTERN hb_set_t *
-hb_subset_input_nameid_set (hb_subset_input_t *input)
+hb_subset_input_set (hb_subset_input_t *input, hb_subset_sets_t set_type)
{
- return input->name_ids;
+ return input->sets_iter () [set_type];
}
/**
- * hb_subset_input_namelangid_set:
- * @input: a #hb_subset_input_t object.
- *
- * Gets the set of name table language IDs to retain, the caller should modify
- * the set as needed.
- *
- * Return value: (transfer none): pointer to the #hb_set_t of language IDs.
- *
- * Since: 2.9.0
- **/
-HB_EXTERN hb_set_t *
-hb_subset_input_namelangid_set (hb_subset_input_t *input)
-{
- return input->name_languages;
-}
-
-
-/**
- * hb_subset_input_layout_features_set:
- * @input: a #hb_subset_input_t object.
- *
- * Gets the set of layout feature tags to retain, the caller should modify the
- * set as needed.
- *
- * Return value: (transfer none): pointer to the #hb_set_t of feature tags.
- *
- * Since: 2.9.0
- **/
-HB_EXTERN hb_set_t *
-hb_subset_input_layout_features_set (hb_subset_input_t *input)
-{
- return input->layout_features;
-}
-
-/**
- * hb_subset_input_drop_tables_set:
- * @input: a #hb_subset_input_t object.
- *
- * Gets the set of table tags to drop, the caller should modify the set as
- * needed.
- *
- * Return value: (transfer none): pointer to the #hb_set_t of table tags.
- *
- * Since: 2.9.0
- **/
-HB_EXTERN hb_set_t *
-hb_subset_input_drop_tables_set (hb_subset_input_t *input)
-{
- return input->drop_tables;
-}
-
-/**
- * hb_subset_input_no_subset_tables_set:
- * @input: a #hb_subset_input_t object.
- *
- * Gets the set of table tags which specifies tables that should not be
- * subsetted, the caller should modify the set as needed.
- *
- * Return value: (transfer none): pointer to the #hb_set_t of table tags.
- *
- * Since: 2.9.0
- **/
-HB_EXTERN hb_set_t *
-hb_subset_input_no_subset_tables_set (hb_subset_input_t *input)
-{
- return input->no_subset_tables;
-}
-
-
-/**
* hb_subset_input_get_flags:
* @input: a #hb_subset_input_t object.
*
+ * Gets all of the subsetting flags in the input object.
+ *
* Return value: the subsetting flags bit field.
*
* Since: 2.9.0
@@ -372,8 +322,8 @@ hb_subset_input_get_flags (hb_subset_input_t *input)
* @input: a #hb_subset_input_t object.
* @value: bit field of flags
*
- * Set all of the flags in the input object to the values
- * specified by the bit field.
+ * Sets all of the flags in the input object to the values specified by the bit
+ * field.
*
* Since: 2.9.0
**/
@@ -394,7 +344,7 @@ hb_subset_input_set_flags (hb_subset_input_t *input,
*
* Attaches a user-data key/data pair to the given subset input object.
*
- * Return value: %true if success, %false otherwise
+ * Return value: `true` if success, `false` otherwise
*
* Since: 2.9.0
**/
@@ -427,132 +377,374 @@ hb_subset_input_get_user_data (const hb_subset_input_t *input,
return hb_object_get_user_data (input, key);
}
-
-static void set_flag_value (hb_subset_input_t *input, hb_subset_flags_t flag, hb_bool_t value)
+/**
+ * hb_subset_input_keep_everything:
+ * @input: a #hb_subset_input_t object
+ *
+ * Configure input object to keep everything in the font face.
+ * That is, all Unicodes, glyphs, names, layout items,
+ * glyph names, etc.
+ *
+ * The input can be tailored afterwards by the caller.
+ *
+ * Since: 7.0.0
+ */
+void
+hb_subset_input_keep_everything (hb_subset_input_t *input)
{
+ const hb_subset_sets_t indices[] = {HB_SUBSET_SETS_UNICODE,
+ HB_SUBSET_SETS_GLYPH_INDEX,
+ HB_SUBSET_SETS_NAME_ID,
+ HB_SUBSET_SETS_NAME_LANG_ID,
+ HB_SUBSET_SETS_LAYOUT_FEATURE_TAG,
+ HB_SUBSET_SETS_LAYOUT_SCRIPT_TAG};
+
+ for (auto idx : hb_iter (indices))
+ {
+ hb_set_t *set = hb_subset_input_set (input, idx);
+ hb_set_clear (set);
+ hb_set_invert (set);
+ }
+
+ // Don't drop any tables
+ hb_set_clear (hb_subset_input_set (input, HB_SUBSET_SETS_DROP_TABLE_TAG));
+
hb_subset_input_set_flags (input,
- value
- ? hb_subset_input_get_flags (input) | flag
- : hb_subset_input_get_flags (input) & ~flag);
+ HB_SUBSET_FLAGS_NOTDEF_OUTLINE |
+ HB_SUBSET_FLAGS_GLYPH_NAMES |
+ HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES |
+ HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED);
}
-void
-hb_subset_input_set_retain_all_features (hb_subset_input_t *subset_input,
- hb_bool_t value)
+#ifndef HB_NO_VAR
+/**
+ * hb_subset_input_pin_all_axes_to_default: (skip)
+ * @input: a #hb_subset_input_t object.
+ * @face: a #hb_face_t object.
+ *
+ * Pin all axes to default locations in the given subset input object.
+ *
+ * All axes in a font must be pinned. Additionally, `CFF2` table, if present,
+ * will be de-subroutinized.
+ *
+ * Return value: `true` if success, `false` otherwise
+ *
+ * Since: 8.3.1
+ **/
+HB_EXTERN hb_bool_t
+hb_subset_input_pin_all_axes_to_default (hb_subset_input_t *input,
+ hb_face_t *face)
{
- return set_flag_value (subset_input,
- HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES,
- value);
+ unsigned axis_count = hb_ot_var_get_axis_count (face);
+ if (!axis_count) return false;
+
+ hb_ot_var_axis_info_t *axis_infos = (hb_ot_var_axis_info_t *) hb_calloc (axis_count, sizeof (hb_ot_var_axis_info_t));
+ if (unlikely (!axis_infos)) return false;
+
+ (void) hb_ot_var_get_axis_infos (face, 0, &axis_count, axis_infos);
+
+ for (unsigned i = 0; i < axis_count; i++)
+ {
+ hb_tag_t axis_tag = axis_infos[i].tag;
+ float default_val = axis_infos[i].default_value;
+ if (!input->axes_location.set (axis_tag, Triple (default_val, default_val, default_val)))
+ {
+ hb_free (axis_infos);
+ return false;
+ }
+ }
+ hb_free (axis_infos);
+ return true;
}
-hb_bool_t
-hb_subset_input_get_retain_all_features (hb_subset_input_t *subset_input)
+/**
+ * hb_subset_input_pin_axis_to_default: (skip)
+ * @input: a #hb_subset_input_t object.
+ * @face: a #hb_face_t object.
+ * @axis_tag: Tag of the axis to be pinned
+ *
+ * Pin an axis to its default location in the given subset input object.
+ *
+ * All axes in a font must be pinned. Additionally, `CFF2` table, if present,
+ * will be de-subroutinized.
+ *
+ * Return value: `true` if success, `false` otherwise
+ *
+ * Since: 6.0.0
+ **/
+HB_EXTERN hb_bool_t
+hb_subset_input_pin_axis_to_default (hb_subset_input_t *input,
+ hb_face_t *face,
+ hb_tag_t axis_tag)
{
- return (bool) (hb_subset_input_get_flags (subset_input) & HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES);
-}
+ hb_ot_var_axis_info_t axis_info;
+ if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info))
+ return false;
-void
-hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input,
- hb_bool_t drop_hints)
-{
- return set_flag_value (subset_input,
- HB_SUBSET_FLAGS_NO_HINTING,
- drop_hints);
+ float default_val = axis_info.default_value;
+ return input->axes_location.set (axis_tag, Triple (default_val, default_val, default_val));
}
-hb_bool_t
-hb_subset_input_get_drop_hints (hb_subset_input_t *subset_input)
+/**
+ * hb_subset_input_pin_axis_location: (skip)
+ * @input: a #hb_subset_input_t object.
+ * @face: a #hb_face_t object.
+ * @axis_tag: Tag of the axis to be pinned
+ * @axis_value: Location on the axis to be pinned at
+ *
+ * Pin an axis to a fixed location in the given subset input object.
+ *
+ * All axes in a font must be pinned. Additionally, `CFF2` table, if present,
+ * will be de-subroutinized.
+ *
+ * Return value: `true` if success, `false` otherwise
+ *
+ * Since: 6.0.0
+ **/
+HB_EXTERN hb_bool_t
+hb_subset_input_pin_axis_location (hb_subset_input_t *input,
+ hb_face_t *face,
+ hb_tag_t axis_tag,
+ float axis_value)
{
- return (bool) (hb_subset_input_get_flags (subset_input) & HB_SUBSET_FLAGS_NO_HINTING);
-}
+ hb_ot_var_axis_info_t axis_info;
+ if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info))
+ return false;
-void
-hb_subset_input_set_desubroutinize (hb_subset_input_t *subset_input,
- hb_bool_t desubroutinize)
-{
- return set_flag_value (subset_input,
- HB_SUBSET_FLAGS_DESUBROUTINIZE,
- desubroutinize);
+ float val = hb_clamp(axis_value, axis_info.min_value, axis_info.max_value);
+ return input->axes_location.set (axis_tag, Triple (val, val, val));
}
-hb_bool_t
-hb_subset_input_get_desubroutinize (hb_subset_input_t *subset_input)
+#ifdef HB_EXPERIMENTAL_API
+/**
+ * hb_subset_input_set_axis_range: (skip)
+ * @input: a #hb_subset_input_t object.
+ * @face: a #hb_face_t object.
+ * @axis_tag: Tag of the axis
+ * @axis_min_value: Minimum value of the axis variation range to set, if NaN the existing min will be used.
+ * @axis_max_value: Maximum value of the axis variation range to set if NaN the existing max will be used.
+ * @axis_def_value: Default value of the axis variation range to set, if NaN the existing default will be used.
+ *
+ * Restricting the range of variation on an axis in the given subset input object.
+ * New min/default/max values will be clamped if they're not within the fvar axis range.
+ *
+ * If the fvar axis default value is not within the new range, the new default
+ * value will be changed to the new min or max value, whichever is closer to the fvar
+ * axis default.
+ *
+ * Note: input min value can not be bigger than input max value. If the input
+ * default value is not within the new min/max range, it'll be clamped.
+ * Note: currently it supports gvar and cvar tables only.
+ *
+ * Return value: `true` if success, `false` otherwise
+ *
+ * XSince: EXPERIMENTAL
+ **/
+HB_EXTERN hb_bool_t
+hb_subset_input_set_axis_range (hb_subset_input_t *input,
+ hb_face_t *face,
+ hb_tag_t axis_tag,
+ float axis_min_value,
+ float axis_max_value,
+ float axis_def_value)
{
- return (bool) (hb_subset_input_get_flags (subset_input) & HB_SUBSET_FLAGS_DESUBROUTINIZE);
-}
+ hb_ot_var_axis_info_t axis_info;
+ if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info))
+ return false;
-void
-hb_subset_input_set_retain_gids (hb_subset_input_t *subset_input,
- hb_bool_t retain_gids)
-{
- return set_flag_value (subset_input,
- HB_SUBSET_FLAGS_RETAIN_GIDS,
- retain_gids);
-}
+ float min = !std::isnan(axis_min_value) ? axis_min_value : axis_info.min_value;
+ float max = !std::isnan(axis_max_value) ? axis_max_value : axis_info.max_value;
+ float def = !std::isnan(axis_def_value) ? axis_def_value : axis_info.default_value;
-hb_bool_t
-hb_subset_input_get_retain_gids (hb_subset_input_t *subset_input)
-{
- return (bool) (hb_subset_input_get_flags (subset_input) & HB_SUBSET_FLAGS_RETAIN_GIDS);
-}
+ if (min > max)
+ return false;
-void
-hb_subset_input_set_name_legacy (hb_subset_input_t *subset_input,
- hb_bool_t name_legacy)
-{
- return set_flag_value (subset_input,
- HB_SUBSET_FLAGS_NAME_LEGACY,
- name_legacy);
+ float new_min_val = hb_clamp(min, axis_info.min_value, axis_info.max_value);
+ float new_max_val = hb_clamp(max, axis_info.min_value, axis_info.max_value);
+ float new_default_val = hb_clamp(def, new_min_val, new_max_val);
+ return input->axes_location.set (axis_tag, Triple (new_min_val, new_default_val, new_max_val));
}
-hb_bool_t
-hb_subset_input_get_name_legacy (hb_subset_input_t *subset_input)
-{
- return (bool) (hb_subset_input_get_flags (subset_input) & HB_SUBSET_FLAGS_NAME_LEGACY);
-}
+/**
+ * hb_subset_input_get_axis_range: (skip)
+ * @input: a #hb_subset_input_t object.
+ * @axis_tag: Tag of the axis
+ * @axis_min_value: Set to the previously configured minimum value of the axis variation range.
+ * @axis_max_value: Set to the previously configured maximum value of the axis variation range.
+ * @axis_def_value: Set to the previously configured default value of the axis variation range.
+ *
+ * Gets the axis range assigned by previous calls to hb_subset_input_set_axis_range.
+ *
+ * Return value: `true` if a range has been set for this axis tag, `false` otherwise.
+ *
+ * XSince: EXPERIMENTAL
+ **/
+HB_EXTERN hb_bool_t
+hb_subset_input_get_axis_range (hb_subset_input_t *input,
+ hb_tag_t axis_tag,
+ float *axis_min_value,
+ float *axis_max_value,
+ float *axis_def_value)
-void
-hb_subset_input_set_overlaps_flag (hb_subset_input_t *subset_input,
- hb_bool_t overlaps_flag)
{
- return set_flag_value (subset_input,
- HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG,
- overlaps_flag);
+ Triple* triple;
+ if (!input->axes_location.has(axis_tag, &triple)) {
+ return false;
+ }
+
+ *axis_min_value = triple->minimum;
+ *axis_def_value = triple->middle;
+ *axis_max_value = triple->maximum;
+ return true;
}
+#endif
+#endif
-hb_bool_t
-hb_subset_input_get_overlaps_flag (hb_subset_input_t *subset_input)
-{
- return (bool) (hb_subset_input_get_flags (subset_input) & HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG);
-}
+/**
+ * hb_subset_preprocess:
+ * @source: a #hb_face_t object.
+ *
+ * Preprocesses the face and attaches data that will be needed by the
+ * subsetter. Future subsetting operations can then use the precomputed data
+ * to speed up the subsetting operation.
+ *
+ * See [subset-preprocessing](https://github.com/harfbuzz/harfbuzz/blob/main/docs/subset-preprocessing.md)
+ * for more information.
+ *
+ * Note: the preprocessed face may contain sub-blobs that reference the memory
+ * backing the source #hb_face_t. Therefore in the case that this memory is not
+ * owned by the source face you will need to ensure that memory lives
+ * as long as the returned #hb_face_t.
+ *
+ * Returns: a new #hb_face_t.
+ *
+ * Since: 6.0.0
+ **/
-void
-hb_subset_input_set_notdef_outline (hb_subset_input_t *subset_input,
- hb_bool_t notdef_outline)
+HB_EXTERN hb_face_t *
+hb_subset_preprocess (hb_face_t *source)
{
- return set_flag_value (subset_input,
- HB_SUBSET_FLAGS_NOTDEF_OUTLINE,
- notdef_outline);
-}
+ hb_subset_input_t* input = hb_subset_input_create_or_fail ();
+ if (!input)
+ return hb_face_reference (source);
-hb_bool_t
-hb_subset_input_get_notdef_outline (hb_subset_input_t *subset_input)
-{
- return (bool) (hb_subset_input_get_flags (subset_input) & HB_SUBSET_FLAGS_NOTDEF_OUTLINE);
+ hb_subset_input_keep_everything (input);
+
+ input->attach_accelerator_data = true;
+
+ // Always use long loca in the preprocessed version. This allows
+ // us to store the glyph bytes unpadded which allows the future subset
+ // operation to run faster by skipping the trim padding step.
+ input->force_long_loca = true;
+
+ hb_face_t* new_source = hb_subset_or_fail (source, input);
+ hb_subset_input_destroy (input);
+
+ if (!new_source) {
+ DEBUG_MSG (SUBSET, nullptr, "Preprocessing failed due to subset failure.");
+ return hb_face_reference (source);
+ }
+
+ return new_source;
}
-void
-hb_subset_input_set_no_prune_unicode_ranges (hb_subset_input_t *subset_input,
- hb_bool_t no_prune_unicode_ranges)
+/**
+ * hb_subset_input_old_to_new_glyph_mapping:
+ * @input: a #hb_subset_input_t object.
+ *
+ * Returns a map which can be used to provide an explicit mapping from old to new glyph
+ * id's in the produced subset. The caller should populate the map as desired.
+ * If this map is left empty then glyph ids will be automatically mapped to new
+ * values by the subsetter. If populated, the mapping must be unique. That
+ * is no two original glyph ids can be mapped to the same new id.
+ * Additionally, if a mapping is provided then the retain gids option cannot
+ * be enabled.
+ *
+ * Any glyphs that are retained in the subset which are not specified
+ * in this mapping will be assigned glyph ids after the highest glyph
+ * id in the mapping.
+ *
+ * Note: this will accept and apply non-monotonic mappings, however this
+ * may result in unsorted Coverage tables. Such fonts may not work for all
+ * use cases (for example ots will reject unsorted coverage tables). So it's
+ * recommended, if possible, to supply a monotonic mapping.
+ *
+ * Return value: (transfer none): pointer to the #hb_map_t of the custom glyphs ID map.
+ *
+ * Since: 7.3.0
+ **/
+HB_EXTERN hb_map_t*
+hb_subset_input_old_to_new_glyph_mapping (hb_subset_input_t *input)
{
- return set_flag_value (subset_input,
- HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES,
- no_prune_unicode_ranges);
+ return &input->glyph_map;
}
-
-hb_bool_t
-hb_subset_input_get_no_prune_unicode_ranges (hb_subset_input_t *subset_input)
+#ifdef HB_EXPERIMENTAL_API
+/**
+ * hb_subset_input_override_name_table:
+ * @input: a #hb_subset_input_t object.
+ * @name_id: name_id of a nameRecord
+ * @platform_id: platform ID of a nameRecord
+ * @encoding_id: encoding ID of a nameRecord
+ * @language_id: language ID of a nameRecord
+ * @name_str: pointer to name string new value or null to indicate should remove
+ * @str_len: the size of @name_str, or -1 if it is `NULL`-terminated
+ *
+ * Override the name string of the NameRecord identified by name_id,
+ * platform_id, encoding_id and language_id. If a record with that name_id
+ * doesn't exist, create it and insert to the name table.
+ *
+ * Note: for mac platform, we only support name_str with all ascii characters,
+ * name_str with non-ascii characters will be ignored.
+ *
+ * XSince: EXPERIMENTAL
+ **/
+HB_EXTERN hb_bool_t
+hb_subset_input_override_name_table (hb_subset_input_t *input,
+ hb_ot_name_id_t name_id,
+ unsigned platform_id,
+ unsigned encoding_id,
+ unsigned language_id,
+ const char *name_str,
+ int str_len /* -1 means nul-terminated */)
{
- return (bool) (hb_subset_input_get_flags (subset_input) & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES);
+ if (!name_str)
+ {
+ str_len = 0;
+ }
+ else if (str_len == -1)
+ {
+ str_len = strlen (name_str);
+ }
+
+ hb_bytes_t name_bytes (nullptr, 0);
+ if (str_len)
+ {
+ if (platform_id == 1)
+ {
+ const uint8_t *src = reinterpret_cast<const uint8_t*> (name_str);
+ const uint8_t *src_end = src + str_len;
+
+ hb_codepoint_t unicode;
+ const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
+ while (src < src_end)
+ {
+ src = hb_utf8_t::next (src, src_end, &unicode, replacement);
+ if (unicode >= 0x0080u)
+ {
+ printf ("Non-ascii character detected, ignored...This API supports acsii characters only for mac platform\n");
+ return false;
+ }
+ }
+ }
+ char *override_name = (char *) hb_malloc (str_len);
+ if (unlikely (!override_name)) return false;
+
+ hb_memcpy (override_name, name_str, str_len);
+ name_bytes = hb_bytes_t (override_name, str_len);
+ }
+ input->name_table_overrides.set (hb_ot_name_record_ids_t (platform_id, encoding_id, language_id, name_id), name_bytes);
+ return true;
}
+
+#endif