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 | * |
24 | * Google Author(s): Garret Rieger, Roderick Sheeter |
25 | */ |
26 | |
27 | #ifndef HB_SUBSET_PLAN_HH |
28 | #define HB_SUBSET_PLAN_HH |
29 | |
30 | #include "hb.hh" |
31 | |
32 | #include "hb-subset.h" |
33 | #include "hb-subset-input.hh" |
34 | |
35 | #include "hb-map.hh" |
36 | #include "hb-set.hh" |
37 | |
38 | struct hb_subset_plan_t |
39 | { |
40 | hb_object_header_t ; |
41 | |
42 | bool drop_hints : 1; |
43 | bool desubroutinize : 1; |
44 | bool retain_gids : 1; |
45 | bool name_legacy : 1; |
46 | |
47 | // For each cp that we'd like to retain maps to the corresponding gid. |
48 | hb_set_t *unicodes; |
49 | |
50 | // name_ids we would like to retain |
51 | hb_set_t *name_ids; |
52 | |
53 | // name_languages we would like to retain |
54 | hb_set_t *name_languages; |
55 | |
56 | //glyph ids requested to retain |
57 | hb_set_t *glyphs_requested; |
58 | |
59 | // Tables which should be dropped. |
60 | hb_set_t *drop_tables; |
61 | |
62 | // The glyph subset |
63 | hb_map_t *codepoint_to_glyph; |
64 | |
65 | // Old -> New glyph id mapping |
66 | hb_map_t *glyph_map; |
67 | hb_map_t *reverse_glyph_map; |
68 | |
69 | // Plan is only good for a specific source/dest so keep them with it |
70 | hb_face_t *source; |
71 | hb_face_t *dest; |
72 | |
73 | unsigned int _num_output_glyphs; |
74 | hb_set_t *_glyphset; |
75 | hb_set_t *_glyphset_gsub; |
76 | |
77 | //active lookups we'd like to retain |
78 | hb_map_t *gsub_lookups; |
79 | hb_map_t *gpos_lookups; |
80 | |
81 | //active features we'd like to retain |
82 | hb_map_t *gsub_features; |
83 | hb_map_t *gpos_features; |
84 | |
85 | //The set of layout item variation store delta set indices to be retained |
86 | hb_set_t *layout_variation_indices; |
87 | //Old -> New layout item variation store delta set index mapping |
88 | hb_map_t *layout_variation_idx_map; |
89 | |
90 | public: |
91 | |
92 | /* |
93 | * The set of input glyph ids which will be retained in the subset. |
94 | * Does NOT include ids kept due to retain_gids. You probably want to use |
95 | * glyph_map/reverse_glyph_map. |
96 | */ |
97 | inline const hb_set_t * |
98 | glyphset () const |
99 | { |
100 | return _glyphset; |
101 | } |
102 | |
103 | /* |
104 | * The set of input glyph ids which will be retained in the subset. |
105 | */ |
106 | inline const hb_set_t * |
107 | glyphset_gsub () const |
108 | { |
109 | return _glyphset_gsub; |
110 | } |
111 | |
112 | /* |
113 | * The total number of output glyphs in the final subset. |
114 | */ |
115 | inline unsigned int |
116 | num_output_glyphs () const |
117 | { |
118 | return _num_output_glyphs; |
119 | } |
120 | |
121 | /* |
122 | * Given an output gid , returns true if that glyph id is an empty |
123 | * glyph (ie. it's a gid that we are dropping all data for). |
124 | */ |
125 | inline bool is_empty_glyph (hb_codepoint_t gid) const |
126 | { |
127 | return !_glyphset->has (gid); |
128 | } |
129 | |
130 | inline bool new_gid_for_codepoint (hb_codepoint_t codepoint, |
131 | hb_codepoint_t *new_gid) const |
132 | { |
133 | hb_codepoint_t old_gid = codepoint_to_glyph->get (codepoint); |
134 | if (old_gid == HB_MAP_VALUE_INVALID) |
135 | return false; |
136 | |
137 | return new_gid_for_old_gid (old_gid, new_gid); |
138 | } |
139 | |
140 | inline bool new_gid_for_old_gid (hb_codepoint_t old_gid, |
141 | hb_codepoint_t *new_gid) const |
142 | { |
143 | hb_codepoint_t gid = glyph_map->get (old_gid); |
144 | if (gid == HB_MAP_VALUE_INVALID) |
145 | return false; |
146 | |
147 | *new_gid = gid; |
148 | return true; |
149 | } |
150 | |
151 | inline bool old_gid_for_new_gid (hb_codepoint_t new_gid, |
152 | hb_codepoint_t *old_gid) const |
153 | { |
154 | hb_codepoint_t gid = reverse_glyph_map->get (new_gid); |
155 | if (gid == HB_MAP_VALUE_INVALID) |
156 | return false; |
157 | |
158 | *old_gid = gid; |
159 | return true; |
160 | } |
161 | |
162 | inline bool |
163 | add_table (hb_tag_t tag, |
164 | hb_blob_t *contents) |
165 | { |
166 | hb_blob_t *source_blob = source->reference_table (tag); |
167 | DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes" , |
168 | HB_UNTAG(tag), |
169 | hb_blob_get_length (contents), |
170 | hb_blob_get_length (source_blob)); |
171 | hb_blob_destroy (source_blob); |
172 | return hb_face_builder_add_table (dest, tag, contents); |
173 | } |
174 | }; |
175 | |
176 | typedef struct hb_subset_plan_t hb_subset_plan_t; |
177 | |
178 | HB_INTERNAL hb_subset_plan_t * |
179 | hb_subset_plan_create (hb_face_t *face, |
180 | hb_subset_input_t *input); |
181 | |
182 | HB_INTERNAL void |
183 | hb_subset_plan_destroy (hb_subset_plan_t *plan); |
184 | |
185 | #endif /* HB_SUBSET_PLAN_HH */ |
186 | |