diff options
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc')
-rw-r--r-- | Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc | 117 |
1 files changed, 114 insertions, 3 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc index 31ddb4f8940..428a9dd1286 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc @@ -78,6 +78,108 @@ using OT::Layout::GSUB::GSUB; * retain glyph ids option and configure the subset to pass through the layout tables untouched. */ +/* + * The list of tables in the open type spec. Used to check for tables that may need handling + * if we are unable to list the tables in a face. + */ +static hb_tag_t known_tables[] { + HB_TAG ('a', 'v', 'a', 'r'), + HB_OT_TAG_BASE, + HB_OT_TAG_CBDT, + HB_OT_TAG_CBLC, + HB_OT_TAG_cff1, + HB_OT_TAG_cff2, + HB_OT_TAG_cmap, + HB_OT_TAG_COLR, + HB_OT_TAG_CPAL, + HB_TAG ('c', 'v', 'a', 'r'), + HB_TAG ('c', 'v', 't', ' '), + HB_TAG ('D', 'S', 'I', 'G'), + HB_TAG ('E', 'B', 'D', 'T'), + HB_TAG ('E', 'B', 'L', 'C'), + HB_TAG ('E', 'B', 'S', 'C'), + HB_TAG ('f', 'p', 'g', 'm'), + HB_TAG ('f', 'v', 'a', 'r'), + HB_TAG ('g', 'a', 's', 'p'), + HB_OT_TAG_GDEF, + HB_OT_TAG_glyf, + HB_OT_TAG_GPOS, + HB_OT_TAG_GSUB, + HB_OT_TAG_gvar, + HB_OT_TAG_hdmx, + HB_OT_TAG_head, + HB_OT_TAG_hhea, + HB_OT_TAG_hmtx, + HB_OT_TAG_HVAR, + HB_OT_TAG_JSTF, + HB_TAG ('k', 'e', 'r', 'n'), + HB_OT_TAG_loca, + HB_TAG ('L', 'T', 'S', 'H'), + HB_OT_TAG_MATH, + HB_OT_TAG_maxp, + HB_TAG ('M', 'E', 'R', 'G'), + HB_TAG ('m', 'e', 't', 'a'), + HB_TAG ('M', 'V', 'A', 'R'), + HB_TAG ('P', 'C', 'L', 'T'), + HB_OT_TAG_post, + HB_TAG ('p', 'r', 'e', 'p'), + HB_OT_TAG_sbix, + HB_TAG ('S', 'T', 'A', 'T'), + HB_TAG ('S', 'V', 'G', ' '), + HB_TAG ('V', 'D', 'M', 'X'), + HB_OT_TAG_vhea, + HB_OT_TAG_vmtx, + HB_OT_TAG_VORG, + HB_OT_TAG_VVAR, + HB_OT_TAG_name, + HB_OT_TAG_OS2 +}; + +static bool _table_is_empty (const hb_face_t *face, hb_tag_t tag) +{ + hb_blob_t* blob = hb_face_reference_table (face, tag); + bool result = (blob == hb_blob_get_empty ()); + hb_blob_destroy (blob); + return result; +} + +static unsigned int +_get_table_tags (const hb_subset_plan_t* plan, + unsigned int start_offset, + unsigned int *table_count, /* IN/OUT */ + hb_tag_t *table_tags /* OUT */) +{ + unsigned num_tables = hb_face_get_table_tags (plan->source, 0, nullptr, nullptr); + if (num_tables) + return hb_face_get_table_tags (plan->source, start_offset, table_count, table_tags); + + // If face has 0 tables associated with it, assume that it was built from + // hb_face_create_tables and thus is unable to list its tables. Fallback to + // checking each table type we can handle for existence instead. + auto it = + hb_concat ( + + hb_array (known_tables) + | hb_filter ([&] (hb_tag_t tag) { + return !_table_is_empty (plan->source, tag) && !plan->no_subset_tables->has (tag); + }) + | hb_map ([] (hb_tag_t tag) -> hb_tag_t { return tag; }), + + plan->no_subset_tables->iter () + | hb_filter([&] (hb_tag_t tag) { + return !_table_is_empty (plan->source, tag); + })); + + it += start_offset; + + unsigned num_written = 0; + while (bool (it) && num_written < *table_count) + table_tags[num_written++] = *it++; + + *table_count = num_written; + return num_written; +} + + static unsigned _plan_estimate_subset_table_size (hb_subset_plan_t *plan, unsigned table_len, @@ -224,9 +326,17 @@ _subset (hb_subset_plan_t *plan, hb_vector_t<char> &buf) static bool _is_table_present (hb_face_t *source, hb_tag_t tag) { + + if (!hb_face_get_table_tags (source, 0, nullptr, nullptr)) { + // If face has 0 tables associated with it, assume that it was built from + // hb_face_create_tables and thus is unable to list its tables. Fallback to + // checking if the blob associated with tag is empty. + return !_table_is_empty (source, tag); + } + hb_tag_t table_tags[32]; unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags); - while ((hb_face_get_table_tags (source, offset, &num_tables, table_tags), num_tables)) + while (((void) hb_face_get_table_tags (source, offset, &num_tables, table_tags), num_tables)) { for (unsigned i = 0; i < num_tables; ++i) if (table_tags[i] == tag) @@ -388,7 +498,8 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan) unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags); hb_vector_t<char> buf; buf.alloc (4096 - 16); - while ((hb_face_get_table_tags (plan->source, offset, &num_tables, table_tags), num_tables)) + + while (((void) _get_table_tags (plan, offset, &num_tables, table_tags), num_tables)) { for (unsigned i = 0; i < num_tables; ++i) { @@ -400,7 +511,7 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan) } offset += num_tables; } -end: +end: return success ? hb_face_reference (plan->dest) : nullptr; } |