/* * Copyright © 2018 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * * 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_t::hb_subset_input_t () { … } /** * 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_reference: (skip) * @input: a #hb_subset_input_t object. * * Increases the reference count on @input. * * Return value: @input. * * Since: 1.8.0 **/ hb_subset_input_t * hb_subset_input_reference (hb_subset_input_t *input) { … } /** * hb_subset_input_destroy: * @input: a #hb_subset_input_t object. * * Decreases the reference count on @input, and if it reaches zero, destroys * @input, freeing all memory. * * Since: 1.8.0 **/ void hb_subset_input_destroy (hb_subset_input_t *input) { … } /** * hb_subset_input_unicode_set: * @input: a #hb_subset_input_t object. * * Gets the set of Unicode code points to retain, the caller should modify the * set as needed. * * Return value: (transfer none): pointer to the #hb_set_t of Unicode code * points. * * Since: 1.8.0 **/ HB_EXTERN hb_set_t * hb_subset_input_unicode_set (hb_subset_input_t *input) { … } /** * hb_subset_input_glyph_set: * @input: a #hb_subset_input_t object. * * Gets the set of glyph IDs to retain, the caller should modify the set as * needed. * * Return value: (transfer none): pointer to the #hb_set_t of glyph IDs. * * Since: 1.8.0 **/ HB_EXTERN hb_set_t * hb_subset_input_glyph_set (hb_subset_input_t *input) { … } /** * hb_subset_input_set: * @input: a #hb_subset_input_t object. * @set_type: a #hb_subset_sets_t set type. * * Gets the set of the specified type. * * Return value: (transfer none): pointer to the #hb_set_t of the specified type. * * Since: 2.9.1 **/ HB_EXTERN hb_set_t * hb_subset_input_set (hb_subset_input_t *input, hb_subset_sets_t set_type) { … } /** * 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 **/ HB_EXTERN hb_subset_flags_t hb_subset_input_get_flags (hb_subset_input_t *input) { … } /** * hb_subset_input_set_flags: * @input: a #hb_subset_input_t object. * @value: bit field of flags * * Sets all of the flags in the input object to the values specified by the bit * field. * * Since: 2.9.0 **/ HB_EXTERN void hb_subset_input_set_flags (hb_subset_input_t *input, unsigned value) { … } /** * hb_subset_input_set_user_data: (skip) * @input: a #hb_subset_input_t object. * @key: The user-data key to set * @data: A pointer to the user data * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * * Attaches a user-data key/data pair to the given subset input object. * * Return value: `true` if success, `false` otherwise * * Since: 2.9.0 **/ hb_bool_t hb_subset_input_set_user_data (hb_subset_input_t *input, hb_user_data_key_t *key, void * data, hb_destroy_func_t destroy, hb_bool_t replace) { … } /** * hb_subset_input_get_user_data: (skip) * @input: a #hb_subset_input_t object. * @key: The user-data key to query * * Fetches the user data associated with the specified key, * attached to the specified subset input object. * * Return value: (transfer none): A pointer to the user data * * Since: 2.9.0 **/ void * hb_subset_input_get_user_data (const hb_subset_input_t *input, hb_user_data_key_t *key) { … } /** * 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) { … } #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) { … } /** * 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) { … } /** * 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) { … } /** * 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 * * Since: 8.5.0 **/ 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) { … } /** * 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. * * Since: 8.5.0 **/ 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) { … } #endif /** * 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 **/ HB_EXTERN hb_face_t * hb_subset_preprocess (hb_face_t *source) { … } /** * 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) { … } #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 */) { 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 ascii 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