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" |
Behdad Esfahbod | af02812 | 2018-02-07 13:07:46 -0500 | [diff] [blame] | 41 | |
Qunxin Liu | 8200e48 | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 42 | |
Qunxin Liu | 56ca435 | 2021-01-28 15:21:26 -0800 | [diff] [blame] | 43 | 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] | 44 | #ifndef HB_NO_SUBSET_CFF |
Behdad Esfahbod | d43af33 | 2019-05-10 23:46:22 -0700 | [diff] [blame] | 45 | static inline void |
Michiharu Ariza | 3787c07 | 2018-11-14 13:38:03 -0800 | [diff] [blame] | 46 | _add_cff_seac_components (const OT::cff1::accelerator_t &cff, |
Ebrahim Byagowi | c7621cf | 2019-10-08 13:24:26 +0330 | [diff] [blame] | 47 | hb_codepoint_t gid, |
| 48 | hb_set_t *gids_to_retain) |
Michiharu Ariza | 3787c07 | 2018-11-14 13:38:03 -0800 | [diff] [blame] | 49 | { |
| 50 | hb_codepoint_t base_gid, accent_gid; |
| 51 | if (cff.get_seac_components (gid, &base_gid, &accent_gid)) |
| 52 | { |
Ebrahim Byagowi | c7621cf | 2019-10-08 13:24:26 +0330 | [diff] [blame] | 53 | gids_to_retain->add (base_gid); |
| 54 | gids_to_retain->add (accent_gid); |
Michiharu Ariza | 3787c07 | 2018-11-14 13:38:03 -0800 | [diff] [blame] | 55 | } |
| 56 | } |
Behdad Esfahbod | a20db49 | 2019-05-12 11:08:45 -0700 | [diff] [blame] | 57 | #endif |
Michiharu Ariza | 3787c07 | 2018-11-14 13:38:03 -0800 | [diff] [blame] | 58 | |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 59 | static void |
Qunxin Liu | f739e1d | 2021-05-11 11:44:32 -0700 | [diff] [blame] | 60 | _remap_palette_indexes (const hb_set_t *palette_indexes, |
| 61 | hb_map_t *mapping /* OUT */) |
| 62 | { |
| 63 | unsigned new_idx = 0; |
| 64 | for (unsigned palette_index : palette_indexes->iter ()) |
| 65 | { |
| 66 | if (palette_index == 0xFFFF) |
| 67 | { |
| 68 | mapping->set (palette_index, palette_index); |
| 69 | continue; |
| 70 | } |
| 71 | mapping->set (palette_index, new_idx); |
| 72 | new_idx++; |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | static void |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 77 | _remap_indexes (const hb_set_t *indexes, |
| 78 | hb_map_t *mapping /* OUT */) |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 79 | { |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 80 | unsigned count = indexes->get_population (); |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 81 | |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 82 | for (auto _ : + hb_zip (indexes->iter (), hb_range (count))) |
| 83 | mapping->set (_.first, _.second); |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 84 | |
| 85 | } |
| 86 | |
Dominik Röttsches | 1dffb55 | 2021-05-18 12:31:14 +0300 | [diff] [blame] | 87 | #ifndef HB_NO_SUBSET_LAYOUT |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 88 | 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 */); |
| 89 | |
| 90 | static void _collect_subset_layout (hb_face_t *face, |
| 91 | hb_tag_t table_tag, |
| 92 | const hb_set_t *layout_features_to_retain, |
| 93 | bool retain_all_features, |
| 94 | layout_collect_func_t layout_collect_func, |
| 95 | hb_set_t *lookup_indices /* OUT */) |
Garret Rieger | feb2389 | 2018-06-07 14:32:34 -0700 | [diff] [blame] | 96 | { |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 97 | if (retain_all_features) |
| 98 | { |
| 99 | layout_collect_func (face, |
| 100 | table_tag, |
| 101 | nullptr, |
| 102 | nullptr, |
| 103 | nullptr, |
| 104 | lookup_indices); |
| 105 | return; |
| 106 | } |
| 107 | |
| 108 | if (hb_set_is_empty (layout_features_to_retain)) return; |
| 109 | unsigned num = layout_features_to_retain->get_population () + 1; |
| 110 | hb_tag_t *features = (hb_tag_t *) malloc (num * sizeof (hb_tag_t)); |
| 111 | if (!features) return; |
| 112 | |
| 113 | unsigned i = 0; |
| 114 | for (hb_tag_t f : layout_features_to_retain->iter ()) |
| 115 | features[i++] = f; |
| 116 | |
| 117 | features[i] = 0; |
Garret Rieger | 26c80ad | 2021-06-18 14:14:20 -0700 | [diff] [blame] | 118 | |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 119 | layout_collect_func (face, |
| 120 | table_tag, |
| 121 | nullptr, |
| 122 | nullptr, |
| 123 | features, |
| 124 | lookup_indices); |
| 125 | |
| 126 | free (features); |
| 127 | } |
| 128 | |
| 129 | template <typename T> |
| 130 | static inline void |
| 131 | _closure_glyphs_lookups_features (hb_face_t *face, |
| 132 | hb_set_t *gids_to_retain, |
| 133 | const hb_set_t *layout_features_to_retain, |
| 134 | bool retain_all_features, |
| 135 | hb_map_t *lookups, |
| 136 | hb_map_t *features, |
| 137 | script_langsys_map *langsys_map) |
| 138 | { |
| 139 | hb_blob_ptr_t<T> table = hb_sanitize_context_t ().reference_table<T> (face); |
| 140 | hb_tag_t table_tag = table->tableTag; |
Behdad Esfahbod | 3a4e5dd | 2018-10-29 18:05:25 -0700 | [diff] [blame] | 141 | hb_set_t lookup_indices; |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 142 | _collect_subset_layout (face, |
| 143 | table_tag, |
| 144 | layout_features_to_retain, |
| 145 | retain_all_features, |
| 146 | hb_ot_layout_collect_lookups, |
| 147 | &lookup_indices); |
| 148 | |
| 149 | if (table_tag == HB_OT_TAG_GSUB) |
| 150 | hb_ot_layout_lookups_substitute_closure (face, |
| 151 | &lookup_indices, |
| 152 | gids_to_retain); |
| 153 | table->closure_lookups (face, |
| 154 | gids_to_retain, |
Qunxin Liu | 973c47f | 2020-06-11 11:27:57 -0700 | [diff] [blame] | 155 | &lookup_indices); |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 156 | _remap_indexes (&lookup_indices, lookups); |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 157 | |
Garret Rieger | 718bf5a | 2020-09-29 13:16:01 -0700 | [diff] [blame] | 158 | // Collect and prune features |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 159 | hb_set_t feature_indices; |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 160 | _collect_subset_layout (face, |
| 161 | table_tag, |
| 162 | layout_features_to_retain, |
| 163 | retain_all_features, |
| 164 | hb_ot_layout_collect_features, |
| 165 | &feature_indices); |
Qunxin Liu | 56ca435 | 2021-01-28 15:21:26 -0800 | [diff] [blame] | 166 | |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 167 | table->prune_features (lookups, &feature_indices); |
Qunxin Liu | 56ca435 | 2021-01-28 15:21:26 -0800 | [diff] [blame] | 168 | hb_map_t duplicate_feature_map; |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 169 | table->find_duplicate_features (lookups, &feature_indices, &duplicate_feature_map); |
Qunxin Liu | 56ca435 | 2021-01-28 15:21:26 -0800 | [diff] [blame] | 170 | |
| 171 | feature_indices.clear (); |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 172 | table->prune_langsys (&duplicate_feature_map, langsys_map, &feature_indices); |
| 173 | _remap_indexes (&feature_indices, features); |
Garret Rieger | 718bf5a | 2020-09-29 13:16:01 -0700 | [diff] [blame] | 174 | |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 175 | table.destroy (); |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 176 | } |
| 177 | |
Dominik Röttsches | c73d7ba | 2019-05-14 13:26:18 +0300 | [diff] [blame] | 178 | #endif |
Garret Rieger | feb2389 | 2018-06-07 14:32:34 -0700 | [diff] [blame] | 179 | |
Qunxin Liu | 8200e48 | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 180 | #ifndef HB_NO_VAR |
| 181 | static inline void |
| 182 | _collect_layout_variation_indices (hb_face_t *face, |
| 183 | const hb_set_t *glyphset, |
| 184 | const hb_map_t *gpos_lookups, |
| 185 | hb_set_t *layout_variation_indices, |
| 186 | hb_map_t *layout_variation_idx_map) |
| 187 | { |
Qunxin Liu | d7c012a | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 188 | hb_blob_ptr_t<OT::GDEF> gdef = hb_sanitize_context_t ().reference_table<OT::GDEF> (face); |
| 189 | hb_blob_ptr_t<OT::GPOS> gpos = hb_sanitize_context_t ().reference_table<OT::GPOS> (face); |
| 190 | |
| 191 | if (!gdef->has_data ()) |
| 192 | { |
| 193 | gdef.destroy (); |
| 194 | gpos.destroy (); |
| 195 | return; |
| 196 | } |
| 197 | OT::hb_collect_variation_indices_context_t c (layout_variation_indices, glyphset, gpos_lookups); |
| 198 | gdef->collect_variation_indices (&c); |
| 199 | |
| 200 | if (hb_ot_layout_has_positioning (face)) |
| 201 | gpos->collect_variation_indices (&c); |
| 202 | |
| 203 | gdef->remap_layout_variation_indices (layout_variation_indices, layout_variation_idx_map); |
Ebrahim Byagowi | 5a7cc7f | 2020-07-29 08:33:32 +0430 | [diff] [blame] | 204 | |
Qunxin Liu | d7c012a | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 205 | gdef.destroy (); |
| 206 | gpos.destroy (); |
Qunxin Liu | 8200e48 | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 207 | } |
| 208 | #endif |
| 209 | |
Behdad Esfahbod | d43af33 | 2019-05-10 23:46:22 -0700 | [diff] [blame] | 210 | static inline void |
Qunxin Liu | 078ddbd | 2019-08-07 13:17:26 -0700 | [diff] [blame] | 211 | _cmap_closure (hb_face_t *face, |
Ebrahim Byagowi | d8af4e7 | 2019-09-21 14:19:14 +0430 | [diff] [blame] | 212 | const hb_set_t *unicodes, |
| 213 | hb_set_t *glyphset) |
Qunxin Liu | 078ddbd | 2019-08-07 13:17:26 -0700 | [diff] [blame] | 214 | { |
Behdad Esfahbod | 7152ac3 | 2019-10-28 17:12:55 -0700 | [diff] [blame] | 215 | OT::cmap::accelerator_t cmap; |
| 216 | cmap.init (face); |
| 217 | cmap.table->closure_glyphs (unicodes, glyphset); |
| 218 | cmap.fini (); |
Qunxin Liu | 078ddbd | 2019-08-07 13:17:26 -0700 | [diff] [blame] | 219 | } |
| 220 | |
| 221 | static inline void |
Behdad Esfahbod | 9e9f16c | 2018-11-16 01:48:26 -0500 | [diff] [blame] | 222 | _remove_invalid_gids (hb_set_t *glyphs, |
| 223 | unsigned int num_glyphs) |
| 224 | { |
| 225 | hb_codepoint_t gid = HB_SET_VALUE_INVALID; |
| 226 | while (glyphs->next (&gid)) |
| 227 | { |
| 228 | if (gid >= num_glyphs) |
| 229 | glyphs->del (gid); |
| 230 | } |
| 231 | } |
Garret Rieger | feb2389 | 2018-06-07 14:32:34 -0700 | [diff] [blame] | 232 | |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 233 | static void |
| 234 | _populate_gids_to_retain (hb_subset_plan_t* plan, |
Ebrahim Byagowi | 11aa046 | 2018-11-15 23:10:56 +0330 | [diff] [blame] | 235 | const hb_set_t *unicodes, |
Ebrahim Byagowi | a0b4ac4 | 2019-08-24 17:57:14 +0430 | [diff] [blame] | 236 | const hb_set_t *input_glyphs_to_retain, |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 237 | bool close_over_gsub, |
Qunxin Liu | 8200e48 | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 238 | bool close_over_gpos, |
Ebrahim Byagowi | 58a5961 | 2020-07-29 08:44:23 +0430 | [diff] [blame] | 239 | bool close_over_gdef) |
Garret Rieger | 25e9173 | 2018-02-05 17:26:25 -0800 | [diff] [blame] | 240 | { |
Behdad Esfahbod | af02812 | 2018-02-07 13:07:46 -0500 | [diff] [blame] | 241 | OT::cmap::accelerator_t cmap; |
Garret Rieger | dcac9fe | 2018-02-16 11:27:03 -0700 | [diff] [blame] | 242 | OT::glyf::accelerator_t glyf; |
blueshade7 | ab525ac | 2019-11-19 20:36:56 -0800 | [diff] [blame] | 243 | #ifndef HB_NO_SUBSET_CFF |
Michiharu Ariza | 3787c07 | 2018-11-14 13:38:03 -0800 | [diff] [blame] | 244 | OT::cff1::accelerator_t cff; |
blueshade7 | ab525ac | 2019-11-19 20:36:56 -0800 | [diff] [blame] | 245 | #endif |
ckitagawa | ed857c4 | 2020-01-24 08:52:23 -0500 | [diff] [blame] | 246 | OT::COLR::accelerator_t colr; |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 247 | cmap.init (plan->source); |
| 248 | glyf.init (plan->source); |
blueshade7 | ab525ac | 2019-11-19 20:36:56 -0800 | [diff] [blame] | 249 | #ifndef HB_NO_SUBSET_CFF |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 250 | cff.init (plan->source); |
blueshade7 | ab525ac | 2019-11-19 20:36:56 -0800 | [diff] [blame] | 251 | #endif |
ckitagawa | ed857c4 | 2020-01-24 08:52:23 -0500 | [diff] [blame] | 252 | colr.init (plan->source); |
Rod Sheeter | 59c658c | 2018-02-08 19:22:47 -0800 | [diff] [blame] | 253 | |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 254 | plan->_glyphset_gsub->add (0); // Not-def |
| 255 | hb_set_union (plan->_glyphset_gsub, input_glyphs_to_retain); |
Rod Sheeter | 59c658c | 2018-02-08 19:22:47 -0800 | [diff] [blame] | 256 | |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 257 | hb_codepoint_t cp = HB_SET_VALUE_INVALID; |
| 258 | while (unicodes->next (&cp)) |
Behdad Esfahbod | e5ab34f | 2018-02-16 16:58:17 -0800 | [diff] [blame] | 259 | { |
Rod Sheeter | d0ce3c6 | 2018-02-06 16:58:35 -0800 | [diff] [blame] | 260 | hb_codepoint_t gid; |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 261 | if (!cmap.get_nominal_glyph (cp, &gid)) |
Behdad Esfahbod | e5ab34f | 2018-02-16 16:58:17 -0800 | [diff] [blame] | 262 | { |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 263 | DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp); |
| 264 | continue; |
Rod Sheeter | d0ce3c6 | 2018-02-06 16:58:35 -0800 | [diff] [blame] | 265 | } |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 266 | plan->unicodes->add (cp); |
| 267 | plan->codepoint_to_glyph->set (cp, gid); |
| 268 | plan->_glyphset_gsub->add (gid); |
Rod Sheeter | 59c658c | 2018-02-08 19:22:47 -0800 | [diff] [blame] | 269 | } |
Ebrahim Byagowi | d8af4e7 | 2019-09-21 14:19:14 +0430 | [diff] [blame] | 270 | |
Qunxin Liu | 078ddbd | 2019-08-07 13:17:26 -0700 | [diff] [blame] | 271 | _cmap_closure (plan->source, plan->unicodes, plan->_glyphset_gsub); |
Rod Sheeter | 59c658c | 2018-02-08 19:22:47 -0800 | [diff] [blame] | 272 | |
Behdad Esfahbod | d43af33 | 2019-05-10 23:46:22 -0700 | [diff] [blame] | 273 | #ifndef HB_NO_SUBSET_LAYOUT |
Garret Rieger | feb2389 | 2018-06-07 14:32:34 -0700 | [diff] [blame] | 274 | if (close_over_gsub) |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 275 | // closure all glyphs/lookups/features needed for GSUB substitutions. |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 276 | _closure_glyphs_lookups_features<OT::GSUB> (plan->source, plan->_glyphset_gsub, plan->layout_features, plan->retain_all_layout_features, plan->gsub_lookups, plan->gsub_features, plan->gsub_langsys); |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 277 | |
| 278 | if (close_over_gpos) |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 279 | _closure_glyphs_lookups_features<OT::GPOS> (plan->source, plan->_glyphset_gsub, plan->layout_features, plan->retain_all_layout_features, plan->gpos_lookups, plan->gpos_features, plan->gpos_langsys); |
Behdad Esfahbod | d43af33 | 2019-05-10 23:46:22 -0700 | [diff] [blame] | 280 | #endif |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 281 | _remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ()); |
Garret Rieger | feb2389 | 2018-06-07 14:32:34 -0700 | [diff] [blame] | 282 | |
Garret Rieger | a08900b | 2021-05-04 16:48:41 -0700 | [diff] [blame] | 283 | // Collect all glyphs referenced by COLRv0 |
| 284 | hb_set_t* cur_glyphset = plan->_glyphset_gsub; |
| 285 | hb_set_t glyphset_colrv0; |
| 286 | if (colr.is_valid ()) |
| 287 | { |
Behdad Esfahbod | bc33b87 | 2021-06-09 11:51:32 -0600 | [diff] [blame] | 288 | glyphset_colrv0.union_ (*cur_glyphset); |
Garret Rieger | a08900b | 2021-05-04 16:48:41 -0700 | [diff] [blame] | 289 | for (hb_codepoint_t gid : cur_glyphset->iter ()) |
| 290 | colr.closure_glyphs (gid, &glyphset_colrv0); |
| 291 | cur_glyphset = &glyphset_colrv0; |
| 292 | } |
| 293 | |
Garret Rieger | 26c80ad | 2021-06-18 14:14:20 -0700 | [diff] [blame] | 294 | hb_set_t palette_indices; |
| 295 | colr.closure_V0palette_indices (cur_glyphset, &palette_indices); |
| 296 | |
| 297 | hb_set_t layer_indices; |
| 298 | colr.closure_forV1 (cur_glyphset, &layer_indices, &palette_indices); |
| 299 | _remap_indexes (&layer_indices, plan->colrv1_layers); |
| 300 | _remap_palette_indexes (&palette_indices, plan->colr_palettes); |
| 301 | colr.fini (); |
| 302 | _remove_invalid_gids (cur_glyphset, plan->source->get_num_glyphs ()); |
| 303 | |
Garret Rieger | dcac9fe | 2018-02-16 11:27:03 -0700 | [diff] [blame] | 304 | // Populate a full set of glyphs to retain by adding all referenced |
| 305 | // composite glyphs. |
Garret Rieger | a08900b | 2021-05-04 16:48:41 -0700 | [diff] [blame] | 306 | for (hb_codepoint_t gid : cur_glyphset->iter ()) |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 307 | { |
Ebrahim Byagowi | be0eddd | 2019-10-08 13:46:55 +0330 | [diff] [blame] | 308 | glyf.add_gid_and_children (gid, plan->_glyphset); |
Behdad Esfahbod | d43af33 | 2019-05-10 23:46:22 -0700 | [diff] [blame] | 309 | #ifndef HB_NO_SUBSET_CFF |
Michiharu Ariza | 3787c07 | 2018-11-14 13:38:03 -0800 | [diff] [blame] | 310 | if (cff.is_valid ()) |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 311 | _add_cff_seac_components (cff, gid, plan->_glyphset); |
Behdad Esfahbod | d43af33 | 2019-05-10 23:46:22 -0700 | [diff] [blame] | 312 | #endif |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 313 | } |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 314 | |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 315 | _remove_invalid_gids (plan->_glyphset, plan->source->get_num_glyphs ()); |
Qunxin Liu | f739e1d | 2021-05-11 11:44:32 -0700 | [diff] [blame] | 316 | |
Behdad Esfahbod | 9e9f16c | 2018-11-16 01:48:26 -0500 | [diff] [blame] | 317 | |
Qunxin Liu | 8200e48 | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 318 | #ifndef HB_NO_VAR |
| 319 | if (close_over_gdef) |
Garret Rieger | aace09a | 2020-10-06 10:26:17 -0700 | [diff] [blame] | 320 | _collect_layout_variation_indices (plan->source, |
| 321 | plan->_glyphset_gsub, |
| 322 | plan->gpos_lookups, |
| 323 | plan->layout_variation_indices, |
| 324 | plan->layout_variation_idx_map); |
Qunxin Liu | 8200e48 | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 325 | #endif |
| 326 | |
blueshade7 | ab525ac | 2019-11-19 20:36:56 -0800 | [diff] [blame] | 327 | #ifndef HB_NO_SUBSET_CFF |
Michiharu Ariza | 3787c07 | 2018-11-14 13:38:03 -0800 | [diff] [blame] | 328 | cff.fini (); |
blueshade7 | ab525ac | 2019-11-19 20:36:56 -0800 | [diff] [blame] | 329 | #endif |
Garret Rieger | dcac9fe | 2018-02-16 11:27:03 -0700 | [diff] [blame] | 330 | glyf.fini (); |
Behdad Esfahbod | af02812 | 2018-02-07 13:07:46 -0500 | [diff] [blame] | 331 | cmap.fini (); |
Garret Rieger | 25e9173 | 2018-02-05 17:26:25 -0800 | [diff] [blame] | 332 | } |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 333 | |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 334 | static void |
Garret Rieger | 5e3cbed | 2019-05-08 16:33:03 -0700 | [diff] [blame] | 335 | _create_old_gid_to_new_gid_map (const hb_face_t *face, |
Ebrahim Byagowi | a0b4ac4 | 2019-08-24 17:57:14 +0430 | [diff] [blame] | 336 | bool retain_gids, |
Garret Rieger | 5e3cbed | 2019-05-08 16:33:03 -0700 | [diff] [blame] | 337 | const hb_set_t *all_gids_to_retain, |
Ebrahim Byagowi | a0b4ac4 | 2019-08-24 17:57:14 +0430 | [diff] [blame] | 338 | hb_map_t *glyph_map, /* OUT */ |
| 339 | hb_map_t *reverse_glyph_map, /* OUT */ |
| 340 | unsigned int *num_glyphs /* OUT */) |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 341 | { |
Garret Rieger | 5e3cbed | 2019-05-08 16:33:03 -0700 | [diff] [blame] | 342 | if (!retain_gids) |
Garret Rieger | 2da1654 | 2019-01-18 17:49:35 -0800 | [diff] [blame] | 343 | { |
Garret Rieger | 5e3cbed | 2019-05-08 16:33:03 -0700 | [diff] [blame] | 344 | + hb_enumerate (hb_iter (all_gids_to_retain), (hb_codepoint_t) 0) |
| 345 | | hb_sink (reverse_glyph_map) |
| 346 | ; |
| 347 | *num_glyphs = reverse_glyph_map->get_population (); |
| 348 | } else { |
| 349 | + hb_iter (all_gids_to_retain) |
Behdad Esfahbod | 78d35f0 | 2019-05-15 18:15:05 -0700 | [diff] [blame] | 350 | | hb_map ([] (hb_codepoint_t _) { |
Garret Rieger | 5e3cbed | 2019-05-08 16:33:03 -0700 | [diff] [blame] | 351 | return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (_, _); |
| 352 | }) |
Behdad Esfahbod | 70fe9e7 | 2019-05-13 17:35:02 -0700 | [diff] [blame] | 353 | | hb_sink (reverse_glyph_map) |
Garret Rieger | 5e3cbed | 2019-05-08 16:33:03 -0700 | [diff] [blame] | 354 | ; |
| 355 | |
Garret Rieger | 6555f20 | 2019-05-15 09:42:38 -0700 | [diff] [blame] | 356 | unsigned max_glyph = |
| 357 | + hb_iter (all_gids_to_retain) |
Behdad Esfahbod | 6157bbe | 2019-07-17 11:20:08 -0700 | [diff] [blame] | 358 | | hb_reduce (hb_max, 0u) |
Garret Rieger | 6555f20 | 2019-05-15 09:42:38 -0700 | [diff] [blame] | 359 | ; |
| 360 | *num_glyphs = max_glyph + 1; |
Garret Rieger | 2da1654 | 2019-01-18 17:49:35 -0800 | [diff] [blame] | 361 | } |
Garret Rieger | 5e3cbed | 2019-05-08 16:33:03 -0700 | [diff] [blame] | 362 | |
| 363 | + reverse_glyph_map->iter () |
| 364 | | hb_map (&hb_pair_t<hb_codepoint_t, hb_codepoint_t>::reverse) |
| 365 | | hb_sink (glyph_map) |
| 366 | ; |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 367 | } |
| 368 | |
Qunxin Liu | 02e5e5d | 2019-05-13 09:38:42 -0700 | [diff] [blame] | 369 | static void |
Ebrahim Byagowi | a0b4ac4 | 2019-08-24 17:57:14 +0430 | [diff] [blame] | 370 | _nameid_closure (hb_face_t *face, |
| 371 | hb_set_t *nameids) |
Qunxin Liu | 02e5e5d | 2019-05-13 09:38:42 -0700 | [diff] [blame] | 372 | { |
Ebrahim Byagowi | 2203749 | 2019-08-04 11:31:31 +0430 | [diff] [blame] | 373 | #ifndef HB_NO_STYLE |
Behdad Esfahbod | b0debc3 | 2019-06-19 18:42:39 -0700 | [diff] [blame] | 374 | face->table.STAT->collect_name_ids (nameids); |
Behdad Esfahbod | a589746 | 2019-06-19 18:36:35 -0700 | [diff] [blame] | 375 | #endif |
Behdad Esfahbod | a849873 | 2019-06-19 19:26:22 -0700 | [diff] [blame] | 376 | #ifndef HB_NO_VAR |
Behdad Esfahbod | b0debc3 | 2019-06-19 18:42:39 -0700 | [diff] [blame] | 377 | face->table.fvar->collect_name_ids (nameids); |
Behdad Esfahbod | a849873 | 2019-06-19 19:26:22 -0700 | [diff] [blame] | 378 | #endif |
Qunxin Liu | 02e5e5d | 2019-05-13 09:38:42 -0700 | [diff] [blame] | 379 | } |
| 380 | |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 381 | /** |
| 382 | * hb_subset_plan_create: |
| 383 | * Computes a plan for subsetting the supplied face according |
Behdad Esfahbod | f39166f | 2018-08-29 18:09:55 -0700 | [diff] [blame] | 384 | * to a provided input. The plan describes |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 385 | * which tables and glyphs should be retained. |
| 386 | * |
Garret Rieger | af46a4d | 2018-02-05 17:14:46 -0800 | [diff] [blame] | 387 | * Return value: New subset plan. |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 388 | * |
| 389 | * Since: 1.7.5 |
| 390 | **/ |
| 391 | hb_subset_plan_t * |
Ebrahim Byagowi | a0b4ac4 | 2019-08-24 17:57:14 +0430 | [diff] [blame] | 392 | hb_subset_plan_create (hb_face_t *face, |
| 393 | hb_subset_input_t *input) |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 394 | { |
Garret Rieger | dae32b4 | 2020-07-28 18:31:46 -0700 | [diff] [blame] | 395 | hb_subset_plan_t *plan; |
Ebrahim Byagowi | 5a7cc7f | 2020-07-29 08:33:32 +0430 | [diff] [blame] | 396 | if (unlikely (!(plan = hb_object_create<hb_subset_plan_t> ()))) |
Garret Rieger | dae32b4 | 2020-07-28 18:31:46 -0700 | [diff] [blame] | 397 | return const_cast<hb_subset_plan_t *> (&Null (hb_subset_plan_t)); |
Behdad Esfahbod | c31fcf4 | 2018-02-10 14:20:10 -0600 | [diff] [blame] | 398 | |
Garret Rieger | dae32b4 | 2020-07-28 18:31:46 -0700 | [diff] [blame] | 399 | plan->successful = true; |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 400 | plan->drop_hints = input->drop_hints; |
Michiharu Ariza | d56e338 | 2018-10-31 22:30:34 -0700 | [diff] [blame] | 401 | plan->desubroutinize = input->desubroutinize; |
Michiharu Ariza | 474f358 | 2019-04-26 10:12:38 -0700 | [diff] [blame] | 402 | plan->retain_gids = input->retain_gids; |
Qunxin Liu | 36a5c04 | 2020-01-21 13:37:28 -0800 | [diff] [blame] | 403 | plan->name_legacy = input->name_legacy; |
Garret Rieger | 73ff04a | 2021-05-18 16:54:01 -0700 | [diff] [blame] | 404 | plan->overlaps_flag = input->overlaps_flag; |
Qunxin Liu | d07f789 | 2021-06-09 15:36:40 -0700 | [diff] [blame] | 405 | plan->notdef_outline = input->notdef_outline; |
Qunxin Liu | eee7b45 | 2021-06-24 10:17:46 -0700 | [diff] [blame^] | 406 | plan->prune_unicode_ranges = !input->no_prune_unicode_ranges; |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 407 | plan->retain_all_layout_features = input->retain_all_layout_features; |
Qunxin Liu | e501ea1 | 2019-04-05 10:05:55 -0700 | [diff] [blame] | 408 | plan->unicodes = hb_set_create (); |
| 409 | plan->name_ids = hb_set_reference (input->name_ids); |
Qunxin Liu | 02e5e5d | 2019-05-13 09:38:42 -0700 | [diff] [blame] | 410 | _nameid_closure (face, plan->name_ids); |
Qunxin Liu | 36a5c04 | 2020-01-21 13:37:28 -0800 | [diff] [blame] | 411 | plan->name_languages = hb_set_reference (input->name_languages); |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 412 | plan->layout_features = hb_set_reference (input->layout_features); |
Qunxin Liu | b2a965d | 2020-04-22 15:58:41 -0700 | [diff] [blame] | 413 | plan->glyphs_requested = hb_set_reference (input->glyphs); |
Qunxin Liu | 993d81b | 2019-05-14 13:55:11 -0700 | [diff] [blame] | 414 | plan->drop_tables = hb_set_reference (input->drop_tables); |
Garret Rieger | b56c938 | 2018-02-14 16:05:39 -0800 | [diff] [blame] | 415 | plan->source = hb_face_reference (face); |
Behdad Esfahbod | aadb2a9 | 2018-08-25 08:18:53 -0700 | [diff] [blame] | 416 | plan->dest = hb_face_builder_create (); |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 417 | |
| 418 | plan->_glyphset = hb_set_create (); |
| 419 | plan->_glyphset_gsub = hb_set_create (); |
Qunxin Liu | e501ea1 | 2019-04-05 10:05:55 -0700 | [diff] [blame] | 420 | plan->codepoint_to_glyph = hb_map_create (); |
| 421 | plan->glyph_map = hb_map_create (); |
| 422 | plan->reverse_glyph_map = hb_map_create (); |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 423 | plan->gsub_lookups = hb_map_create (); |
| 424 | plan->gpos_lookups = hb_map_create (); |
Qunxin Liu | 56ca435 | 2021-01-28 15:21:26 -0800 | [diff] [blame] | 425 | |
Garret Rieger | 3c8273a | 2021-03-25 11:39:57 -0700 | [diff] [blame] | 426 | if (plan->check_success (plan->gsub_langsys = hb_object_create<script_langsys_map> ())) |
| 427 | plan->gsub_langsys->init_shallow (); |
| 428 | if (plan->check_success (plan->gpos_langsys = hb_object_create<script_langsys_map> ())) |
| 429 | plan->gpos_langsys->init_shallow (); |
| 430 | |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 431 | plan->gsub_features = hb_map_create (); |
| 432 | plan->gpos_features = hb_map_create (); |
Qunxin Liu | e59ffe5 | 2021-04-01 12:01:19 -0700 | [diff] [blame] | 433 | plan->colrv1_layers = hb_map_create (); |
Qunxin Liu | f739e1d | 2021-05-11 11:44:32 -0700 | [diff] [blame] | 434 | plan->colr_palettes = hb_map_create (); |
Qunxin Liu | 8200e48 | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 435 | plan->layout_variation_indices = hb_set_create (); |
| 436 | plan->layout_variation_idx_map = hb_map_create (); |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 437 | |
Garret Rieger | 3c8273a | 2021-03-25 11:39:57 -0700 | [diff] [blame] | 438 | if (plan->in_error ()) { |
| 439 | return plan; |
| 440 | } |
| 441 | |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 442 | _populate_gids_to_retain (plan, |
Ebrahim Byagowi | a0b4ac4 | 2019-08-24 17:57:14 +0430 | [diff] [blame] | 443 | input->unicodes, |
| 444 | input->glyphs, |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 445 | !input->drop_tables->has (HB_OT_TAG_GSUB), |
Qunxin Liu | 8200e48 | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 446 | !input->drop_tables->has (HB_OT_TAG_GPOS), |
Ebrahim Byagowi | 58a5961 | 2020-07-29 08:44:23 +0430 | [diff] [blame] | 447 | !input->drop_tables->has (HB_OT_TAG_GDEF)); |
Garret Rieger | b7f9718 | 2019-01-17 18:55:56 -0800 | [diff] [blame] | 448 | |
Garret Rieger | 198859b | 2019-01-28 18:10:56 -0800 | [diff] [blame] | 449 | _create_old_gid_to_new_gid_map (face, |
Ebrahim Byagowi | a0b4ac4 | 2019-08-24 17:57:14 +0430 | [diff] [blame] | 450 | input->retain_gids, |
Qunxin Liu | 3147133 | 2019-03-26 09:15:56 -0700 | [diff] [blame] | 451 | plan->_glyphset, |
Garret Rieger | 2da1654 | 2019-01-18 17:49:35 -0800 | [diff] [blame] | 452 | plan->glyph_map, |
Ebrahim Byagowi | a0b4ac4 | 2019-08-24 17:57:14 +0430 | [diff] [blame] | 453 | plan->reverse_glyph_map, |
| 454 | &plan->_num_output_glyphs); |
Rod Sheeter | fa87770 | 2018-02-14 14:16:25 -0800 | [diff] [blame] | 455 | |
Garret Rieger | 25e9173 | 2018-02-05 17:26:25 -0800 | [diff] [blame] | 456 | return plan; |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 457 | } |
| 458 | |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 459 | /** |
| 460 | * hb_subset_plan_destroy: |
| 461 | * |
| 462 | * Since: 1.7.5 |
| 463 | **/ |
| 464 | void |
| 465 | hb_subset_plan_destroy (hb_subset_plan_t *plan) |
| 466 | { |
| 467 | if (!hb_object_destroy (plan)) return; |
| 468 | |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 469 | hb_set_destroy (plan->unicodes); |
Qunxin Liu | e501ea1 | 2019-04-05 10:05:55 -0700 | [diff] [blame] | 470 | hb_set_destroy (plan->name_ids); |
Qunxin Liu | 36a5c04 | 2020-01-21 13:37:28 -0800 | [diff] [blame] | 471 | hb_set_destroy (plan->name_languages); |
Qunxin Liu | cb5a6b5 | 2021-05-19 17:33:46 -0700 | [diff] [blame] | 472 | hb_set_destroy (plan->layout_features); |
Qunxin Liu | b2a965d | 2020-04-22 15:58:41 -0700 | [diff] [blame] | 473 | hb_set_destroy (plan->glyphs_requested); |
Garret Rieger | 3be0ffe | 2019-05-16 11:29:15 -0700 | [diff] [blame] | 474 | hb_set_destroy (plan->drop_tables); |
Garret Rieger | b56c938 | 2018-02-14 16:05:39 -0800 | [diff] [blame] | 475 | hb_face_destroy (plan->source); |
| 476 | hb_face_destroy (plan->dest); |
Garret Rieger | 251cc97 | 2018-05-30 12:23:51 -0700 | [diff] [blame] | 477 | hb_map_destroy (plan->codepoint_to_glyph); |
| 478 | hb_map_destroy (plan->glyph_map); |
Garret Rieger | 23f3644 | 2019-01-18 18:33:21 -0800 | [diff] [blame] | 479 | hb_map_destroy (plan->reverse_glyph_map); |
Garret Rieger | bdbe047 | 2019-01-28 16:59:15 -0800 | [diff] [blame] | 480 | hb_set_destroy (plan->_glyphset); |
Garret Rieger | 0af9de1 | 2019-05-20 15:04:20 -0700 | [diff] [blame] | 481 | hb_set_destroy (plan->_glyphset_gsub); |
Qunxin Liu | 0b39c48 | 2019-10-22 16:00:43 -0700 | [diff] [blame] | 482 | hb_map_destroy (plan->gsub_lookups); |
| 483 | hb_map_destroy (plan->gpos_lookups); |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 484 | hb_map_destroy (plan->gsub_features); |
| 485 | hb_map_destroy (plan->gpos_features); |
Qunxin Liu | e59ffe5 | 2021-04-01 12:01:19 -0700 | [diff] [blame] | 486 | hb_map_destroy (plan->colrv1_layers); |
Qunxin Liu | f739e1d | 2021-05-11 11:44:32 -0700 | [diff] [blame] | 487 | hb_map_destroy (plan->colr_palettes); |
Qunxin Liu | 8200e48 | 2020-02-26 13:11:42 -0800 | [diff] [blame] | 488 | hb_set_destroy (plan->layout_variation_indices); |
| 489 | hb_map_destroy (plan->layout_variation_idx_map); |
Qunxin Liu | 8ffc9ad | 2019-10-31 15:59:02 -0700 | [diff] [blame] | 490 | |
Garret Rieger | 3c8273a | 2021-03-25 11:39:57 -0700 | [diff] [blame] | 491 | if (plan->gsub_langsys) |
| 492 | { |
| 493 | for (auto _ : plan->gsub_langsys->iter ()) |
| 494 | hb_set_destroy (_.second); |
Qunxin Liu | 56ca435 | 2021-01-28 15:21:26 -0800 | [diff] [blame] | 495 | |
Garret Rieger | 3c8273a | 2021-03-25 11:39:57 -0700 | [diff] [blame] | 496 | hb_object_destroy (plan->gsub_langsys); |
| 497 | plan->gsub_langsys->fini_shallow (); |
| 498 | free (plan->gsub_langsys); |
| 499 | } |
| 500 | |
| 501 | if (plan->gpos_langsys) |
| 502 | { |
| 503 | for (auto _ : plan->gpos_langsys->iter ()) |
| 504 | hb_set_destroy (_.second); |
| 505 | |
| 506 | hb_object_destroy (plan->gpos_langsys); |
| 507 | plan->gpos_langsys->fini_shallow (); |
| 508 | free (plan->gpos_langsys); |
| 509 | } |
Garret Rieger | b56c938 | 2018-02-14 16:05:39 -0800 | [diff] [blame] | 510 | |
Garret Rieger | 1cfe650 | 2018-02-05 15:22:30 -0800 | [diff] [blame] | 511 | free (plan); |
| 512 | } |