Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright © 2018 Google, Inc. |
| 3 | * |
| 4 | * This is part of HarfBuzz, a text shaping library. |
| 5 | * |
| 6 | * Permission is hereby granted, without written agreement and without |
| 7 | * license or royalty fees, to use, copy, modify, and distribute this |
| 8 | * software and its documentation for any purpose, provided that the |
| 9 | * above copyright notice and the following two paragraphs appear in |
| 10 | * all copies of this software. |
| 11 | * |
| 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
| 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
| 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
| 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
| 16 | * DAMAGE. |
| 17 | * |
| 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
| 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
| 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
| 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
| 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
| 23 | * |
Rod Sheeter | d0ce3c6 | 2018-02-06 16:58:35 -0800 | [diff] [blame] | 24 | * Google Author(s): Garret Rieger, Roderick Sheeter |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 25 | */ |
| 26 | |
Behdad Esfahbod | aba0a94 | 2018-08-31 13:25:19 -0700 | [diff] [blame] | 27 | #include "hb-subset-plan.hh" |
Behdad Esfahbod | c77ae40 | 2018-08-25 22:36:36 -0700 | [diff] [blame] | 28 | #include "hb-map.hh" |
Behdad Esfahbod | c77ae40 | 2018-08-25 22:36:36 -0700 | [diff] [blame] | 29 | #include "hb-set.hh" |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 30 | |
Behdad Esfahbod | af02812 | 2018-02-07 13:07:46 -0500 | [diff] [blame] | 31 | #include "hb-ot-cmap-table.hh" |
Garret Rieger | dcac9fe | 2018-02-16 11:27:03 -0700 | [diff] [blame] | 32 | #include "hb-ot-glyf-table.hh" |
Qunxin Liu | d7c012a | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 33 | #include "hb-ot-layout-gdef-table.hh" |
| 34 | #include "hb-ot-layout-gpos-table.hh" |
Qunxin Liu | 973c47f | 2020-06-11 11:27:57 -0700 | [diff] [blame] | 35 | #include "hb-ot-layout-gsub-table.hh" |
Michiharu Ariza | 3787c07 | 2018-11-14 13:38:03 -0800 | [diff] [blame] | 36 | #include "hb-ot-cff1-table.hh" |
ckitagawa | ed857c4 | 2020-01-24 08:52:23 -0500 | [diff] [blame] | 37 | #include "hb-ot-color-colr-table.hh" |
Qunxin Liu | e59ffe5 | 2021-04-01 12:01:19 -0700 | [diff] [blame] | 38 | #include "hb-ot-color-colrv1-closure.hh" |
Qunxin Liu | 02e5e5d | 2019-05-13 09:38:42 -0700 | [diff] [blame] | 39 | #include "hb-ot-var-fvar-table.hh" |
| 40 | #include "hb-ot-stat-table.hh" |
Qunxin Liu | ca7b9da | 2021-09-20 14:42:51 -0700 | [diff] [blame] | 41 | #include "hb-ot-math-table.hh" |
Behdad Esfahbod | af02812 | 2018-02-07 13:07:46 -0500 | [diff] [blame] | 42 | |
Qunxin Liu | 8200e48 | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 43 | |
Qunxin Liu | 56ca435 | 2021-01-28 15:21:26 -0800 | [diff] [blame] | 44 | typedef hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> script_langsys_map; |
Behdad Esfahbod | a20db49 | 2019-05-12 11:08:45 -0700 | [diff] [blame] | 45 | #ifndef HB_NO_SUBSET_CFF |
Behdad Esfahbod | d43af33 | 2019-05-10 23:46:22 -0700 | [diff] [blame] | 46 | static inline void |
Michiharu Ariza | 3787c07 | 2018-11-14 13:38:03 -0800 | [diff] [blame] | 47 | _add_cff_seac_components (const OT::cff1::accelerator_t &cff, |
Ebrahim Byagowi | c7621cf | 2019-10-08 13:24:26 +0330 | [diff] [blame] | 48 | hb_codepoint_t gid, |
| 49 | hb_set_t *gids_to_retain) |
Michiharu Ariza | 3787c07 | 2018-11-14 13:38:03 -0800 | [diff] [blame] | 50 | { |
| 51 | hb_codepoint_t base_gid, accent_gid; |
| 52 | if (cff.get_seac_components (gid, &base_gid, &accent_gid)) |
| 53 | { |
Ebrahim Byagowi | c7621cf | 2019-10-08 13:24:26 +0330 | [diff] [blame] | 54 | gids_to_retain->add (base_gid); |
| 55 | gids_to_retain->add (accent_gid); |
Michiharu Ariza | 3787c07 | 2018-11-14 13:38:03 -0800 | [diff] [blame] | 56 | } |
| 57 | } |
Behdad Esfahbod | a20db49 | 2019-05-12 11:08:45 -0700 | [diff] [blame] | 58 | #endif |
Michiharu Ariza | 3787c07 | 2018-11-14 13:38:03 -0800 | [diff] [blame] | 59 | |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 60 | static void |
Qunxin Liu | f739e1d | 2021-05-11 11:44:32 -0700 | [diff] [blame] | 61 | _remap_palette_indexes (const hb_set_t *palette_indexes, |
Garret Rieger | 9fb3a25 | 2021-06-09 13:46:35 -0700 | [diff] [blame] | 62 | hb_map_t *mapping /* OUT */) |
Qunxin Liu | f739e1d | 2021-05-11 11:44:32 -0700 | [diff] [blame] | 63 | { |
| 64 | unsigned new_idx = 0; |
| 65 | for (unsigned palette_index : palette_indexes->iter ()) |
| 66 | { |
| 67 | if (palette_index == 0xFFFF) |
| 68 | { |
| 69 | mapping->set (palette_index, palette_index); |
| 70 | continue; |
| 71 | } |
| 72 | mapping->set (palette_index, new_idx); |
| 73 | new_idx++; |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | static void |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 78 | _remap_indexes (const hb_set_t *indexes, |
| 79 | hb_map_t *mapping /* OUT */) |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 80 | { |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 81 | unsigned count = indexes->get_population (); |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 82 | |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 83 | for (auto _ : + hb_zip (indexes->iter (), hb_range (count))) |
| 84 | mapping->set (_.first, _.second); |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 85 | |
| 86 | } |
| 87 | |
Dominik Röttsches | 1dffb55 | 2021-05-18 12:31:14 +0300 | [diff] [blame] | 88 | #ifndef HB_NO_SUBSET_LAYOUT |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 89 | typedef void (*layout_collect_func_t) (hb_face_t *face, hb_tag_t table_tag, const hb_tag_t *scripts, const hb_tag_t *languages, const hb_tag_t *features, hb_set_t *lookup_indexes /* OUT */); |
| 90 | |
Garret Rieger | 59deb75 | 2021-08-24 17:06:14 -0700 | [diff] [blame] | 91 | |
Garret Rieger | f2441a4 | 2021-08-24 15:53:32 -0700 | [diff] [blame] | 92 | template <typename T> |
Garret Rieger | 59deb75 | 2021-08-24 17:06:14 -0700 | [diff] [blame] | 93 | static void _collect_layout_indices (hb_face_t *face, |
| 94 | const T& table, |
| 95 | const hb_set_t *layout_features_to_retain, |
| 96 | layout_collect_func_t layout_collect_func, |
Behdad Esfahbod | e9e6d66 | 2021-08-24 23:22:49 -0600 | [diff] [blame] | 97 | hb_set_t *indices /* OUT */) |
Garret Rieger | feb2389 | 2018-06-07 14:32:34 -0700 | [diff] [blame] | 98 | { |
Garret Rieger | f2441a4 | 2021-08-24 15:53:32 -0700 | [diff] [blame] | 99 | hb_vector_t<hb_tag_t> features; |
| 100 | if (!features.alloc (table.get_feature_count () + 1)) |
| 101 | return; |
| 102 | |
| 103 | for (unsigned i = 0; i < table.get_feature_count (); i++) |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 104 | { |
Garret Rieger | f2441a4 | 2021-08-24 15:53:32 -0700 | [diff] [blame] | 105 | hb_tag_t tag = table.get_feature_tag (i); |
| 106 | if (tag && layout_features_to_retain->has (tag)) |
| 107 | features.push (tag); |
| 108 | } |
| 109 | |
| 110 | if (!features) |
| 111 | return; |
| 112 | |
| 113 | // The collect function needs a null element to signal end of the array. |
| 114 | features.push (0); |
| 115 | |
| 116 | if (features.get_size () == table.get_feature_count () + 1) |
| 117 | { |
| 118 | // Looking for all features, trigger the faster collection method. |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 119 | layout_collect_func (face, |
Garret Rieger | f2441a4 | 2021-08-24 15:53:32 -0700 | [diff] [blame] | 120 | T::tableTag, |
| 121 | nullptr, |
| 122 | nullptr, |
| 123 | nullptr, |
Behdad Esfahbod | e9e6d66 | 2021-08-24 23:22:49 -0600 | [diff] [blame] | 124 | indices); |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 125 | return; |
| 126 | } |
| 127 | |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 128 | layout_collect_func (face, |
Garret Rieger | f2441a4 | 2021-08-24 15:53:32 -0700 | [diff] [blame] | 129 | T::tableTag, |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 130 | nullptr, |
| 131 | nullptr, |
Garret Rieger | f2441a4 | 2021-08-24 15:53:32 -0700 | [diff] [blame] | 132 | features.arrayZ, |
Behdad Esfahbod | e9e6d66 | 2021-08-24 23:22:49 -0600 | [diff] [blame] | 133 | indices); |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 134 | } |
| 135 | |
| 136 | template <typename T> |
| 137 | static inline void |
Garret Rieger | 9fb3a25 | 2021-06-09 13:46:35 -0700 | [diff] [blame] | 138 | _closure_glyphs_lookups_features (hb_face_t *face, |
| 139 | hb_set_t *gids_to_retain, |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 140 | const hb_set_t *layout_features_to_retain, |
Garret Rieger | 9fb3a25 | 2021-06-09 13:46:35 -0700 | [diff] [blame] | 141 | hb_map_t *lookups, |
| 142 | hb_map_t *features, |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 143 | script_langsys_map *langsys_map) |
| 144 | { |
| 145 | hb_blob_ptr_t<T> table = hb_sanitize_context_t ().reference_table<T> (face); |
| 146 | hb_tag_t table_tag = table->tableTag; |
Behdad Esfahbod | 3a4e5dd | 2018-10-29 18:05:25 -0700 | [diff] [blame] | 147 | hb_set_t lookup_indices; |
Garret Rieger | 59deb75 | 2021-08-24 17:06:14 -0700 | [diff] [blame] | 148 | _collect_layout_indices<T> (face, |
| 149 | *table, |
| 150 | layout_features_to_retain, |
| 151 | hb_ot_layout_collect_lookups, |
| 152 | &lookup_indices); |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 153 | |
| 154 | if (table_tag == HB_OT_TAG_GSUB) |
| 155 | hb_ot_layout_lookups_substitute_closure (face, |
| 156 | &lookup_indices, |
| 157 | gids_to_retain); |
| 158 | table->closure_lookups (face, |
| 159 | gids_to_retain, |
Qunxin Liu | 973c47f | 2020-06-11 11:27:57 -0700 | [diff] [blame] | 160 | &lookup_indices); |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 161 | _remap_indexes (&lookup_indices, lookups); |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 162 | |
Garret Rieger | 718bf5a | 2020-09-29 13:16:01 -0700 | [diff] [blame] | 163 | // Collect and prune features |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 164 | hb_set_t feature_indices; |
Garret Rieger | 59deb75 | 2021-08-24 17:06:14 -0700 | [diff] [blame] | 165 | _collect_layout_indices<T> (face, |
| 166 | *table, |
| 167 | layout_features_to_retain, |
| 168 | hb_ot_layout_collect_features, |
| 169 | &feature_indices); |
Qunxin Liu | 56ca435 | 2021-01-28 15:21:26 -0800 | [diff] [blame] | 170 | |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 171 | table->prune_features (lookups, &feature_indices); |
Qunxin Liu | 56ca435 | 2021-01-28 15:21:26 -0800 | [diff] [blame] | 172 | hb_map_t duplicate_feature_map; |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 173 | table->find_duplicate_features (lookups, &feature_indices, &duplicate_feature_map); |
Qunxin Liu | 56ca435 | 2021-01-28 15:21:26 -0800 | [diff] [blame] | 174 | |
| 175 | feature_indices.clear (); |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 176 | table->prune_langsys (&duplicate_feature_map, langsys_map, &feature_indices); |
| 177 | _remap_indexes (&feature_indices, features); |
Garret Rieger | 718bf5a | 2020-09-29 13:16:01 -0700 | [diff] [blame] | 178 | |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 179 | table.destroy (); |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 180 | } |
| 181 | |
Dominik Röttsches | c73d7ba | 2019-05-14 13:26:18 +0300 | [diff] [blame] | 182 | #endif |
Garret Rieger | feb2389 | 2018-06-07 14:32:34 -0700 | [diff] [blame] | 183 | |
Qunxin Liu | 8200e48 | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 184 | #ifndef HB_NO_VAR |
| 185 | static inline void |
| 186 | _collect_layout_variation_indices (hb_face_t *face, |
| 187 | const hb_set_t *glyphset, |
| 188 | const hb_map_t *gpos_lookups, |
| 189 | hb_set_t *layout_variation_indices, |
| 190 | hb_map_t *layout_variation_idx_map) |
| 191 | { |
Qunxin Liu | d7c012a | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 192 | hb_blob_ptr_t<OT::GDEF> gdef = hb_sanitize_context_t ().reference_table<OT::GDEF> (face); |
| 193 | hb_blob_ptr_t<OT::GPOS> gpos = hb_sanitize_context_t ().reference_table<OT::GPOS> (face); |
| 194 | |
| 195 | if (!gdef->has_data ()) |
| 196 | { |
| 197 | gdef.destroy (); |
| 198 | gpos.destroy (); |
| 199 | return; |
| 200 | } |
| 201 | OT::hb_collect_variation_indices_context_t c (layout_variation_indices, glyphset, gpos_lookups); |
| 202 | gdef->collect_variation_indices (&c); |
| 203 | |
| 204 | if (hb_ot_layout_has_positioning (face)) |
| 205 | gpos->collect_variation_indices (&c); |
| 206 | |
| 207 | gdef->remap_layout_variation_indices (layout_variation_indices, layout_variation_idx_map); |
Ebrahim Byagowi | 5a7cc7f | 2020-07-29 08:33:32 +0430 | [diff] [blame] | 208 | |
Qunxin Liu | d7c012a | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 209 | gdef.destroy (); |
| 210 | gpos.destroy (); |
Qunxin Liu | 8200e48 | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 211 | } |
| 212 | #endif |
| 213 | |
Behdad Esfahbod | d43af33 | 2019-05-10 23:46:22 -0700 | [diff] [blame] | 214 | static inline void |
Garret Rieger | 9fb3a25 | 2021-06-09 13:46:35 -0700 | [diff] [blame] | 215 | _cmap_closure (hb_face_t *face, |
| 216 | const hb_set_t *unicodes, |
| 217 | hb_set_t *glyphset) |
Qunxin Liu | 078ddbd | 2019-08-07 13:17:26 -0700 | [diff] [blame] | 218 | { |
Behdad Esfahbod | 7152ac3 | 2019-10-28 17:12:55 -0700 | [diff] [blame] | 219 | OT::cmap::accelerator_t cmap; |
| 220 | cmap.init (face); |
| 221 | cmap.table->closure_glyphs (unicodes, glyphset); |
| 222 | cmap.fini (); |
Qunxin Liu | 078ddbd | 2019-08-07 13:17:26 -0700 | [diff] [blame] | 223 | } |
| 224 | |
| 225 | static inline void |
Qunxin Liu | ca7b9da | 2021-09-20 14:42:51 -0700 | [diff] [blame] | 226 | _math_closure (hb_face_t *face, |
| 227 | hb_set_t *glyphset) |
| 228 | { |
| 229 | hb_blob_ptr_t<OT::MATH> math = hb_sanitize_context_t ().reference_table<OT::MATH> (face); |
| 230 | if (math->has_data ()) |
| 231 | math->closure_glyphs (glyphset); |
| 232 | math.destroy (); |
| 233 | } |
| 234 | |
| 235 | |
| 236 | static inline void |
Behdad Esfahbod | 9e9f16c | 2018-11-16 01:48:26 -0500 | [diff] [blame] | 237 | _remove_invalid_gids (hb_set_t *glyphs, |
| 238 | unsigned int num_glyphs) |
| 239 | { |
| 240 | hb_codepoint_t gid = HB_SET_VALUE_INVALID; |
| 241 | while (glyphs->next (&gid)) |
| 242 | { |
| 243 | if (gid >= num_glyphs) |
| 244 | glyphs->del (gid); |
| 245 | } |
| 246 | } |
Garret Rieger | feb2389 | 2018-06-07 14:32:34 -0700 | [diff] [blame] | 247 | |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 248 | static void |
Garret Rieger | 9aa0ece | 2021-07-14 17:27:14 -0700 | [diff] [blame] | 249 | _populate_unicodes_to_retain (const hb_set_t *unicodes, |
| 250 | const hb_set_t *glyphs, |
| 251 | hb_subset_plan_t *plan) |
Garret Rieger | 25e9173 | 2018-02-05 17:26:25 -0800 | [diff] [blame] | 252 | { |
Behdad Esfahbod | af02812 | 2018-02-07 13:07:46 -0500 | [diff] [blame] | 253 | OT::cmap::accelerator_t cmap; |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 254 | cmap.init (plan->source); |
Rod Sheeter | 59c658c | 2018-02-08 19:22:47 -0800 | [diff] [blame] | 255 | |
Behdad Esfahbod | 1620698 | 2021-08-25 16:25:08 -0600 | [diff] [blame] | 256 | constexpr static const int size_threshold = 4096; |
| 257 | |
| 258 | if (glyphs->is_empty () && unicodes->get_population () < size_threshold) |
Behdad Esfahbod | e5ab34f | 2018-02-16 16:58:17 -0800 | [diff] [blame] | 259 | { |
Behdad Esfahbod | 1620698 | 2021-08-25 16:25:08 -0600 | [diff] [blame] | 260 | /* This is the fast path if it's anticipated that size of unicodes |
| 261 | * is << than the number of codepoints in the font. */ |
Garret Rieger | 8f4f47d | 2021-08-25 13:34:05 -0700 | [diff] [blame] | 262 | for (hb_codepoint_t cp : *unicodes) |
Behdad Esfahbod | e5ab34f | 2018-02-16 16:58:17 -0800 | [diff] [blame] | 263 | { |
Garret Rieger | 8f4f47d | 2021-08-25 13:34:05 -0700 | [diff] [blame] | 264 | hb_codepoint_t gid; |
| 265 | if (!cmap.get_nominal_glyph (cp, &gid)) |
| 266 | { |
| 267 | DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp); |
| 268 | continue; |
| 269 | } |
Garret Rieger | cd07070 | 2021-08-25 14:42:00 -0700 | [diff] [blame] | 270 | |
Garret Rieger | 8f4f47d | 2021-08-25 13:34:05 -0700 | [diff] [blame] | 271 | plan->codepoint_to_glyph->set (cp, gid); |
Rod Sheeter | d0ce3c6 | 2018-02-06 16:58:35 -0800 | [diff] [blame] | 272 | } |
Behdad Esfahbod | 1620698 | 2021-08-25 16:25:08 -0600 | [diff] [blame] | 273 | } |
| 274 | else |
| 275 | { |
Garret Rieger | cd07070 | 2021-08-25 14:42:00 -0700 | [diff] [blame] | 276 | hb_map_t unicode_glyphid_map; |
| 277 | cmap.collect_mapping (hb_set_get_empty (), &unicode_glyphid_map); |
Garret Rieger | cd07070 | 2021-08-25 14:42:00 -0700 | [diff] [blame] | 278 | |
| 279 | for (hb_pair_t<hb_codepoint_t, hb_codepoint_t> cp_gid : |
Behdad Esfahbod | 1620698 | 2021-08-25 16:25:08 -0600 | [diff] [blame] | 280 | + unicode_glyphid_map.iter ()) |
Garret Rieger | cd07070 | 2021-08-25 14:42:00 -0700 | [diff] [blame] | 281 | { |
| 282 | if (!unicodes->has (cp_gid.first) && !glyphs->has (cp_gid.second)) |
Behdad Esfahbod | 1620698 | 2021-08-25 16:25:08 -0600 | [diff] [blame] | 283 | continue; |
Garret Rieger | cd07070 | 2021-08-25 14:42:00 -0700 | [diff] [blame] | 284 | |
| 285 | plan->codepoint_to_glyph->set (cp_gid.first, cp_gid.second); |
| 286 | } |
| 287 | |
Behdad Esfahbod | 1620698 | 2021-08-25 16:25:08 -0600 | [diff] [blame] | 288 | /* Add gids which where requested, but not mapped in cmap */ |
| 289 | // TODO(garretrieger): |
| 290 | // Once https://github.com/harfbuzz/harfbuzz/issues/3169 |
| 291 | // is implemented, this can be done with union and del_range |
Garret Rieger | cd07070 | 2021-08-25 14:42:00 -0700 | [diff] [blame] | 292 | for (hb_codepoint_t gid : glyphs->iter ()) |
| 293 | { |
| 294 | if (gid >= plan->source->get_num_glyphs ()) |
Behdad Esfahbod | 1620698 | 2021-08-25 16:25:08 -0600 | [diff] [blame] | 295 | break; |
Garret Rieger | cd07070 | 2021-08-25 14:42:00 -0700 | [diff] [blame] | 296 | plan->_glyphset_gsub->add (gid); |
| 297 | } |
Garret Rieger | 9aa0ece | 2021-07-14 17:27:14 -0700 | [diff] [blame] | 298 | } |
| 299 | |
Behdad Esfahbod | 1620698 | 2021-08-25 16:25:08 -0600 | [diff] [blame] | 300 | + plan->codepoint_to_glyph->keys () | hb_sink (plan->unicodes); |
Garret Rieger | cd07070 | 2021-08-25 14:42:00 -0700 | [diff] [blame] | 301 | + plan->codepoint_to_glyph->values () | hb_sink (plan->_glyphset_gsub); |
Behdad Esfahbod | 1620698 | 2021-08-25 16:25:08 -0600 | [diff] [blame] | 302 | |
| 303 | cmap.fini (); |
Garret Rieger | 9aa0ece | 2021-07-14 17:27:14 -0700 | [diff] [blame] | 304 | } |
| 305 | |
| 306 | static void |
| 307 | _populate_gids_to_retain (hb_subset_plan_t* plan, |
Garret Rieger | 9aa0ece | 2021-07-14 17:27:14 -0700 | [diff] [blame] | 308 | bool close_over_gsub, |
| 309 | bool close_over_gpos, |
| 310 | bool close_over_gdef) |
| 311 | { |
| 312 | OT::glyf::accelerator_t glyf; |
| 313 | #ifndef HB_NO_SUBSET_CFF |
| 314 | OT::cff1::accelerator_t cff; |
| 315 | #endif |
| 316 | OT::COLR::accelerator_t colr; |
| 317 | glyf.init (plan->source); |
| 318 | #ifndef HB_NO_SUBSET_CFF |
| 319 | cff.init (plan->source); |
| 320 | #endif |
| 321 | colr.init (plan->source); |
| 322 | |
| 323 | plan->_glyphset_gsub->add (0); // Not-def |
Garret Rieger | 9aa0ece | 2021-07-14 17:27:14 -0700 | [diff] [blame] | 324 | |
Qunxin Liu | 078ddbd | 2019-08-07 13:17:26 -0700 | [diff] [blame] | 325 | _cmap_closure (plan->source, plan->unicodes, plan->_glyphset_gsub); |
Rod Sheeter | 59c658c | 2018-02-08 19:22:47 -0800 | [diff] [blame] | 326 | |
Behdad Esfahbod | d43af33 | 2019-05-10 23:46:22 -0700 | [diff] [blame] | 327 | #ifndef HB_NO_SUBSET_LAYOUT |
Garret Rieger | feb2389 | 2018-06-07 14:32:34 -0700 | [diff] [blame] | 328 | if (close_over_gsub) |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 329 | // closure all glyphs/lookups/features needed for GSUB substitutions. |
Garret Rieger | 46d4a5e | 2021-07-29 15:07:13 -0700 | [diff] [blame] | 330 | _closure_glyphs_lookups_features<OT::GSUB> ( |
| 331 | plan->source, |
| 332 | plan->_glyphset_gsub, |
| 333 | plan->layout_features, |
Garret Rieger | 46d4a5e | 2021-07-29 15:07:13 -0700 | [diff] [blame] | 334 | plan->gsub_lookups, |
| 335 | plan->gsub_features, |
| 336 | plan->gsub_langsys); |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 337 | |
| 338 | if (close_over_gpos) |
Garret Rieger | 46d4a5e | 2021-07-29 15:07:13 -0700 | [diff] [blame] | 339 | _closure_glyphs_lookups_features<OT::GPOS> ( |
| 340 | plan->source, |
| 341 | plan->_glyphset_gsub, |
| 342 | plan->layout_features, |
Garret Rieger | 46d4a5e | 2021-07-29 15:07:13 -0700 | [diff] [blame] | 343 | plan->gpos_lookups, |
| 344 | plan->gpos_features, |
| 345 | plan->gpos_langsys); |
Behdad Esfahbod | d43af33 | 2019-05-10 23:46:22 -0700 | [diff] [blame] | 346 | #endif |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 347 | _remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ()); |
Garret Rieger | feb2389 | 2018-06-07 14:32:34 -0700 | [diff] [blame] | 348 | |
Qunxin Liu | ca7b9da | 2021-09-20 14:42:51 -0700 | [diff] [blame] | 349 | hb_set_set (plan->_glyphset_mathed, plan->_glyphset_gsub); |
| 350 | _math_closure (plan->source, plan->_glyphset_mathed); |
| 351 | _remove_invalid_gids (plan->_glyphset_mathed, plan->source->get_num_glyphs ()); |
| 352 | |
Garret Rieger | a08900b | 2021-05-04 16:48:41 -0700 | [diff] [blame] | 353 | // Collect all glyphs referenced by COLRv0 |
Qunxin Liu | ca7b9da | 2021-09-20 14:42:51 -0700 | [diff] [blame] | 354 | hb_set_t* cur_glyphset = plan->_glyphset_mathed; |
Garret Rieger | a08900b | 2021-05-04 16:48:41 -0700 | [diff] [blame] | 355 | hb_set_t glyphset_colrv0; |
| 356 | if (colr.is_valid ()) |
| 357 | { |
Behdad Esfahbod | bc33b87 | 2021-06-09 11:51:32 -0600 | [diff] [blame] | 358 | glyphset_colrv0.union_ (*cur_glyphset); |
Garret Rieger | a08900b | 2021-05-04 16:48:41 -0700 | [diff] [blame] | 359 | for (hb_codepoint_t gid : cur_glyphset->iter ()) |
| 360 | colr.closure_glyphs (gid, &glyphset_colrv0); |
| 361 | cur_glyphset = &glyphset_colrv0; |
| 362 | } |
| 363 | |
Garret Rieger | 26c80ad | 2021-06-18 14:14:20 -0700 | [diff] [blame] | 364 | hb_set_t palette_indices; |
| 365 | colr.closure_V0palette_indices (cur_glyphset, &palette_indices); |
| 366 | |
| 367 | hb_set_t layer_indices; |
| 368 | colr.closure_forV1 (cur_glyphset, &layer_indices, &palette_indices); |
| 369 | _remap_indexes (&layer_indices, plan->colrv1_layers); |
| 370 | _remap_palette_indexes (&palette_indices, plan->colr_palettes); |
| 371 | colr.fini (); |
| 372 | _remove_invalid_gids (cur_glyphset, plan->source->get_num_glyphs ()); |
| 373 | |
Garret Rieger | dcac9fe | 2018-02-16 11:27:03 -0700 | [diff] [blame] | 374 | // Populate a full set of glyphs to retain by adding all referenced |
| 375 | // composite glyphs. |
Garret Rieger | a08900b | 2021-05-04 16:48:41 -0700 | [diff] [blame] | 376 | for (hb_codepoint_t gid : cur_glyphset->iter ()) |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 377 | { |
Ebrahim Byagowi | be0eddd | 2019-10-08 13:46:55 +0330 | [diff] [blame] | 378 | glyf.add_gid_and_children (gid, plan->_glyphset); |
Behdad Esfahbod | d43af33 | 2019-05-10 23:46:22 -0700 | [diff] [blame] | 379 | #ifndef HB_NO_SUBSET_CFF |
Michiharu Ariza | 3787c07 | 2018-11-14 13:38:03 -0800 | [diff] [blame] | 380 | if (cff.is_valid ()) |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 381 | _add_cff_seac_components (cff, gid, plan->_glyphset); |
Behdad Esfahbod | d43af33 | 2019-05-10 23:46:22 -0700 | [diff] [blame] | 382 | #endif |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 383 | } |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 384 | |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 385 | _remove_invalid_gids (plan->_glyphset, plan->source->get_num_glyphs ()); |
Qunxin Liu | f739e1d | 2021-05-11 11:44:32 -0700 | [diff] [blame] | 386 | |
Behdad Esfahbod | 9e9f16c | 2018-11-16 01:48:26 -0500 | [diff] [blame] | 387 | |
Qunxin Liu | 8200e48 | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 388 | #ifndef HB_NO_VAR |
| 389 | if (close_over_gdef) |
Garret Rieger | aace09a | 2020-10-06 10:26:17 -0700 | [diff] [blame] | 390 | _collect_layout_variation_indices (plan->source, |
Garret Rieger | 9fb3a25 | 2021-06-09 13:46:35 -0700 | [diff] [blame] | 391 | plan->_glyphset_gsub, |
| 392 | plan->gpos_lookups, |
| 393 | plan->layout_variation_indices, |
| 394 | plan->layout_variation_idx_map); |
Qunxin Liu | 8200e48 | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 395 | #endif |
| 396 | |
blueshade7 | ab525ac | 2019-11-19 20:36:56 -0800 | [diff] [blame] | 397 | #ifndef HB_NO_SUBSET_CFF |
Michiharu Ariza | 3787c07 | 2018-11-14 13:38:03 -0800 | [diff] [blame] | 398 | cff.fini (); |
blueshade7 | ab525ac | 2019-11-19 20:36:56 -0800 | [diff] [blame] | 399 | #endif |
Garret Rieger | dcac9fe | 2018-02-16 11:27:03 -0700 | [diff] [blame] | 400 | glyf.fini (); |
Garret Rieger | 25e9173 | 2018-02-05 17:26:25 -0800 | [diff] [blame] | 401 | } |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 402 | |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 403 | static void |
Garret Rieger | 5e3cbed | 2019-05-08 16:33:03 -0700 | [diff] [blame] | 404 | _create_old_gid_to_new_gid_map (const hb_face_t *face, |
Garret Rieger | 9fb3a25 | 2021-06-09 13:46:35 -0700 | [diff] [blame] | 405 | bool retain_gids, |
| 406 | const hb_set_t *all_gids_to_retain, |
| 407 | hb_map_t *glyph_map, /* OUT */ |
| 408 | hb_map_t *reverse_glyph_map, /* OUT */ |
| 409 | unsigned int *num_glyphs /* OUT */) |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 410 | { |
Garret Rieger | 5e3cbed | 2019-05-08 16:33:03 -0700 | [diff] [blame] | 411 | if (!retain_gids) |
Garret Rieger | 2da1654 | 2019-01-18 17:49:35 -0800 | [diff] [blame] | 412 | { |
Garret Rieger | 5e3cbed | 2019-05-08 16:33:03 -0700 | [diff] [blame] | 413 | + hb_enumerate (hb_iter (all_gids_to_retain), (hb_codepoint_t) 0) |
| 414 | | hb_sink (reverse_glyph_map) |
| 415 | ; |
| 416 | *num_glyphs = reverse_glyph_map->get_population (); |
| 417 | } else { |
| 418 | + hb_iter (all_gids_to_retain) |
Behdad Esfahbod | 78d35f0 | 2019-05-15 18:15:05 -0700 | [diff] [blame] | 419 | | hb_map ([] (hb_codepoint_t _) { |
Garret Rieger | 5e3cbed | 2019-05-08 16:33:03 -0700 | [diff] [blame] | 420 | return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (_, _); |
| 421 | }) |
Behdad Esfahbod | 70fe9e7 | 2019-05-13 17:35:02 -0700 | [diff] [blame] | 422 | | hb_sink (reverse_glyph_map) |
Garret Rieger | 5e3cbed | 2019-05-08 16:33:03 -0700 | [diff] [blame] | 423 | ; |
| 424 | |
Garret Rieger | 6555f20 | 2019-05-15 09:42:38 -0700 | [diff] [blame] | 425 | unsigned max_glyph = |
| 426 | + hb_iter (all_gids_to_retain) |
Behdad Esfahbod | 6157bbe | 2019-07-17 11:20:08 -0700 | [diff] [blame] | 427 | | hb_reduce (hb_max, 0u) |
Garret Rieger | 6555f20 | 2019-05-15 09:42:38 -0700 | [diff] [blame] | 428 | ; |
| 429 | *num_glyphs = max_glyph + 1; |
Garret Rieger | 2da1654 | 2019-01-18 17:49:35 -0800 | [diff] [blame] | 430 | } |
Garret Rieger | 5e3cbed | 2019-05-08 16:33:03 -0700 | [diff] [blame] | 431 | |
| 432 | + reverse_glyph_map->iter () |
| 433 | | hb_map (&hb_pair_t<hb_codepoint_t, hb_codepoint_t>::reverse) |
| 434 | | hb_sink (glyph_map) |
| 435 | ; |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 436 | } |
| 437 | |
Qunxin Liu | 02e5e5d | 2019-05-13 09:38:42 -0700 | [diff] [blame] | 438 | static void |
Ebrahim Byagowi | a0b4ac4 | 2019-08-24 17:57:14 +0430 | [diff] [blame] | 439 | _nameid_closure (hb_face_t *face, |
| 440 | hb_set_t *nameids) |
Qunxin Liu | 02e5e5d | 2019-05-13 09:38:42 -0700 | [diff] [blame] | 441 | { |
Ebrahim Byagowi | 2203749 | 2019-08-04 11:31:31 +0430 | [diff] [blame] | 442 | #ifndef HB_NO_STYLE |
Behdad Esfahbod | b0debc3 | 2019-06-19 18:42:39 -0700 | [diff] [blame] | 443 | face->table.STAT->collect_name_ids (nameids); |
Behdad Esfahbod | a589746 | 2019-06-19 18:36:35 -0700 | [diff] [blame] | 444 | #endif |
Behdad Esfahbod | a849873 | 2019-06-19 19:26:22 -0700 | [diff] [blame] | 445 | #ifndef HB_NO_VAR |
Behdad Esfahbod | b0debc3 | 2019-06-19 18:42:39 -0700 | [diff] [blame] | 446 | face->table.fvar->collect_name_ids (nameids); |
Behdad Esfahbod | a849873 | 2019-06-19 19:26:22 -0700 | [diff] [blame] | 447 | #endif |
Qunxin Liu | 02e5e5d | 2019-05-13 09:38:42 -0700 | [diff] [blame] | 448 | } |
| 449 | |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 450 | /** |
| 451 | * hb_subset_plan_create: |
Garret Rieger | 1b6c1aa | 2021-06-28 12:57:39 -0700 | [diff] [blame] | 452 | * @face: font face to create the plan for. |
Khaled Hosny | acc7100 | 2021-07-26 02:13:49 +0200 | [diff] [blame] | 453 | * @input: a #hb_subset_input_t input. |
Garret Rieger | 1b6c1aa | 2021-06-28 12:57:39 -0700 | [diff] [blame] | 454 | * |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 455 | * Computes a plan for subsetting the supplied face according |
Behdad Esfahbod | f39166f | 2018-08-29 18:09:55 -0700 | [diff] [blame] | 456 | * to a provided input. The plan describes |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 457 | * which tables and glyphs should be retained. |
| 458 | * |
Khaled Hosny | acc7100 | 2021-07-26 02:13:49 +0200 | [diff] [blame] | 459 | * Return value: (transfer full): New subset plan. Destroy with |
| 460 | * hb_subset_plan_destroy(). |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 461 | * |
| 462 | * Since: 1.7.5 |
| 463 | **/ |
| 464 | hb_subset_plan_t * |
Garret Rieger | 9fb3a25 | 2021-06-09 13:46:35 -0700 | [diff] [blame] | 465 | hb_subset_plan_create (hb_face_t *face, |
Garret Rieger | edb57a8 | 2021-06-09 10:42:48 -0700 | [diff] [blame] | 466 | const hb_subset_input_t *input) |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 467 | { |
Garret Rieger | dae32b4 | 2020-07-28 18:31:46 -0700 | [diff] [blame] | 468 | hb_subset_plan_t *plan; |
Ebrahim Byagowi | 5a7cc7f | 2020-07-29 08:33:32 +0430 | [diff] [blame] | 469 | if (unlikely (!(plan = hb_object_create<hb_subset_plan_t> ()))) |
Garret Rieger | dae32b4 | 2020-07-28 18:31:46 -0700 | [diff] [blame] | 470 | return const_cast<hb_subset_plan_t *> (&Null (hb_subset_plan_t)); |
Behdad Esfahbod | c31fcf4 | 2018-02-10 14:20:10 -0600 | [diff] [blame] | 471 | |
Garret Rieger | dae32b4 | 2020-07-28 18:31:46 -0700 | [diff] [blame] | 472 | plan->successful = true; |
Garret Rieger | 46d4a5e | 2021-07-29 15:07:13 -0700 | [diff] [blame] | 473 | plan->flags = input->flags; |
Qunxin Liu | e501ea1 | 2019-04-05 10:05:55 -0700 | [diff] [blame] | 474 | plan->unicodes = hb_set_create (); |
Garret Rieger | 3844e58 | 2021-08-30 11:16:51 -0700 | [diff] [blame] | 475 | plan->name_ids = hb_set_copy (input->sets.name_ids); |
Qunxin Liu | 02e5e5d | 2019-05-13 09:38:42 -0700 | [diff] [blame] | 476 | _nameid_closure (face, plan->name_ids); |
Garret Rieger | 3844e58 | 2021-08-30 11:16:51 -0700 | [diff] [blame] | 477 | plan->name_languages = hb_set_copy (input->sets.name_languages); |
| 478 | plan->layout_features = hb_set_copy (input->sets.layout_features); |
| 479 | plan->glyphs_requested = hb_set_copy (input->sets.glyphs); |
| 480 | plan->drop_tables = hb_set_copy (input->sets.drop_tables); |
| 481 | plan->no_subset_tables = hb_set_copy (input->sets.no_subset_tables); |
Garret Rieger | b56c938 | 2018-02-14 16:05:39 -0800 | [diff] [blame] | 482 | plan->source = hb_face_reference (face); |
Behdad Esfahbod | aadb2a9 | 2018-08-25 08:18:53 -0700 | [diff] [blame] | 483 | plan->dest = hb_face_builder_create (); |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 484 | |
| 485 | plan->_glyphset = hb_set_create (); |
| 486 | plan->_glyphset_gsub = hb_set_create (); |
Qunxin Liu | ca7b9da | 2021-09-20 14:42:51 -0700 | [diff] [blame] | 487 | plan->_glyphset_mathed = hb_set_create (); |
Qunxin Liu | e501ea1 | 2019-04-05 10:05:55 -0700 | [diff] [blame] | 488 | plan->codepoint_to_glyph = hb_map_create (); |
| 489 | plan->glyph_map = hb_map_create (); |
| 490 | plan->reverse_glyph_map = hb_map_create (); |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 491 | plan->gsub_lookups = hb_map_create (); |
| 492 | plan->gpos_lookups = hb_map_create (); |
Qunxin Liu | 56ca435 | 2021-01-28 15:21:26 -0800 | [diff] [blame] | 493 | |
Garret Rieger | 3c8273a | 2021-03-25 11:39:57 -0700 | [diff] [blame] | 494 | if (plan->check_success (plan->gsub_langsys = hb_object_create<script_langsys_map> ())) |
| 495 | plan->gsub_langsys->init_shallow (); |
| 496 | if (plan->check_success (plan->gpos_langsys = hb_object_create<script_langsys_map> ())) |
| 497 | plan->gpos_langsys->init_shallow (); |
| 498 | |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 499 | plan->gsub_features = hb_map_create (); |
| 500 | plan->gpos_features = hb_map_create (); |
Qunxin Liu | e59ffe5 | 2021-04-01 12:01:19 -0700 | [diff] [blame] | 501 | plan->colrv1_layers = hb_map_create (); |
Qunxin Liu | f739e1d | 2021-05-11 11:44:32 -0700 | [diff] [blame] | 502 | plan->colr_palettes = hb_map_create (); |
Qunxin Liu | 8200e48 | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 503 | plan->layout_variation_indices = hb_set_create (); |
| 504 | plan->layout_variation_idx_map = hb_map_create (); |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 505 | |
Garret Rieger | 3c8273a | 2021-03-25 11:39:57 -0700 | [diff] [blame] | 506 | if (plan->in_error ()) { |
| 507 | return plan; |
| 508 | } |
| 509 | |
Garret Rieger | 3844e58 | 2021-08-30 11:16:51 -0700 | [diff] [blame] | 510 | _populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, plan); |
Garret Rieger | 9aa0ece | 2021-07-14 17:27:14 -0700 | [diff] [blame] | 511 | |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 512 | _populate_gids_to_retain (plan, |
Garret Rieger | 3844e58 | 2021-08-30 11:16:51 -0700 | [diff] [blame] | 513 | !input->sets.drop_tables->has (HB_OT_TAG_GSUB), |
| 514 | !input->sets.drop_tables->has (HB_OT_TAG_GPOS), |
| 515 | !input->sets.drop_tables->has (HB_OT_TAG_GDEF)); |
Garret Rieger | b7f9718 | 2019-01-17 18:55:56 -0800 | [diff] [blame] | 516 | |
Garret Rieger | 198859b | 2019-01-28 18:10:56 -0800 | [diff] [blame] | 517 | _create_old_gid_to_new_gid_map (face, |
Garret Rieger | 3d534b1 | 2021-07-29 11:52:14 -0700 | [diff] [blame] | 518 | input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS, |
Qunxin Liu | 3147133 | 2019-03-26 09:15:56 -0700 | [diff] [blame] | 519 | plan->_glyphset, |
Garret Rieger | 2da1654 | 2019-01-18 17:49:35 -0800 | [diff] [blame] | 520 | plan->glyph_map, |
Ebrahim Byagowi | a0b4ac4 | 2019-08-24 17:57:14 +0430 | [diff] [blame] | 521 | plan->reverse_glyph_map, |
| 522 | &plan->_num_output_glyphs); |
Rod Sheeter | fa87770 | 2018-02-14 14:16:25 -0800 | [diff] [blame] | 523 | |
Garret Rieger | 25e9173 | 2018-02-05 17:26:25 -0800 | [diff] [blame] | 524 | return plan; |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 525 | } |
| 526 | |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 527 | /** |
| 528 | * hb_subset_plan_destroy: |
Khaled Hosny | acc7100 | 2021-07-26 02:13:49 +0200 | [diff] [blame] | 529 | * @plan: a #hb_subset_plan_t |
| 530 | * |
| 531 | * Decreases the reference count on @plan, and if it reaches zero, destroys |
| 532 | * @plan, freeing all memory. |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 533 | * |
| 534 | * Since: 1.7.5 |
| 535 | **/ |
| 536 | void |
| 537 | hb_subset_plan_destroy (hb_subset_plan_t *plan) |
| 538 | { |
| 539 | if (!hb_object_destroy (plan)) return; |
| 540 | |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 541 | hb_set_destroy (plan->unicodes); |
Qunxin Liu | e501ea1 | 2019-04-05 10:05:55 -0700 | [diff] [blame] | 542 | hb_set_destroy (plan->name_ids); |
Qunxin Liu | 36a5c04 | 2020-01-21 13:37:28 -0800 | [diff] [blame] | 543 | hb_set_destroy (plan->name_languages); |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 544 | hb_set_destroy (plan->layout_features); |
Qunxin Liu | b2a965d | 2020-04-22 15:58:41 -0700 | [diff] [blame] | 545 | hb_set_destroy (plan->glyphs_requested); |
Garret Rieger | 3be0ffe | 2019-05-16 11:29:15 -0700 | [diff] [blame] | 546 | hb_set_destroy (plan->drop_tables); |
Garret Rieger | 2b9cb29 | 2021-07-22 13:26:03 -0700 | [diff] [blame] | 547 | hb_set_destroy (plan->no_subset_tables); |
Garret Rieger | b56c938 | 2018-02-14 16:05:39 -0800 | [diff] [blame] | 548 | hb_face_destroy (plan->source); |
| 549 | hb_face_destroy (plan->dest); |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 550 | hb_map_destroy (plan->codepoint_to_glyph); |
| 551 | hb_map_destroy (plan->glyph_map); |
Garret Rieger | 23f3644 | 2019-01-18 18:33:21 -0800 | [diff] [blame] | 552 | hb_map_destroy (plan->reverse_glyph_map); |
Garret Rieger | bdbe047 | 2019-01-28 16:59:15 -0800 | [diff] [blame] | 553 | hb_set_destroy (plan->_glyphset); |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 554 | hb_set_destroy (plan->_glyphset_gsub); |
Qunxin Liu | ca7b9da | 2021-09-20 14:42:51 -0700 | [diff] [blame] | 555 | hb_set_destroy (plan->_glyphset_mathed); |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 556 | hb_map_destroy (plan->gsub_lookups); |
| 557 | hb_map_destroy (plan->gpos_lookups); |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 558 | hb_map_destroy (plan->gsub_features); |
| 559 | hb_map_destroy (plan->gpos_features); |
Qunxin Liu | e59ffe5 | 2021-04-01 12:01:19 -0700 | [diff] [blame] | 560 | hb_map_destroy (plan->colrv1_layers); |
Qunxin Liu | f739e1d | 2021-05-11 11:44:32 -0700 | [diff] [blame] | 561 | hb_map_destroy (plan->colr_palettes); |
Qunxin Liu | 8200e48 | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 562 | hb_set_destroy (plan->layout_variation_indices); |
| 563 | hb_map_destroy (plan->layout_variation_idx_map); |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 564 | |
Garret Rieger | 3c8273a | 2021-03-25 11:39:57 -0700 | [diff] [blame] | 565 | if (plan->gsub_langsys) |
| 566 | { |
| 567 | for (auto _ : plan->gsub_langsys->iter ()) |
| 568 | hb_set_destroy (_.second); |
Qunxin Liu | 56ca435 | 2021-01-28 15:21:26 -0800 | [diff] [blame] | 569 | |
Garret Rieger | 3c8273a | 2021-03-25 11:39:57 -0700 | [diff] [blame] | 570 | hb_object_destroy (plan->gsub_langsys); |
| 571 | plan->gsub_langsys->fini_shallow (); |
Behdad Esfahbod | 2337f0d | 2021-07-08 10:58:50 -0600 | [diff] [blame] | 572 | hb_free (plan->gsub_langsys); |
Garret Rieger | 3c8273a | 2021-03-25 11:39:57 -0700 | [diff] [blame] | 573 | } |
| 574 | |
| 575 | if (plan->gpos_langsys) |
| 576 | { |
| 577 | for (auto _ : plan->gpos_langsys->iter ()) |
| 578 | hb_set_destroy (_.second); |
| 579 | |
| 580 | hb_object_destroy (plan->gpos_langsys); |
| 581 | plan->gpos_langsys->fini_shallow (); |
Behdad Esfahbod | 2337f0d | 2021-07-08 10:58:50 -0600 | [diff] [blame] | 582 | hb_free (plan->gpos_langsys); |
Garret Rieger | 3c8273a | 2021-03-25 11:39:57 -0700 | [diff] [blame] | 583 | } |
Garret Rieger | b56c938 | 2018-02-14 16:05:39 -0800 | [diff] [blame] | 584 | |
Behdad Esfahbod | 2337f0d | 2021-07-08 10:58:50 -0600 | [diff] [blame] | 585 | hb_free (plan); |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 586 | } |