1 | /* |
2 | * Copyright © 2017 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): Behdad Esfahbod |
25 | */ |
26 | |
27 | #include "hb.hh" |
28 | |
29 | #ifndef HB_NO_VAR |
30 | |
31 | #include "hb-ot-var.h" |
32 | |
33 | #include "hb-ot-var-avar-table.hh" |
34 | #include "hb-ot-var-fvar-table.hh" |
35 | #include "hb-ot-var-mvar-table.hh" |
36 | |
37 | |
38 | /** |
39 | * SECTION:hb-ot-var |
40 | * @title: hb-ot-var |
41 | * @short_description: OpenType Font Variations |
42 | * @include: hb-ot.h |
43 | * |
44 | * Functions for fetching information about OpenType Variable Fonts. |
45 | **/ |
46 | |
47 | |
48 | /* |
49 | * fvar/avar |
50 | */ |
51 | |
52 | |
53 | /** |
54 | * hb_ot_var_has_data: |
55 | * @face: The #hb_face_t to work on |
56 | * |
57 | * Tests whether a face includes any OpenType variation data in the `fvar` table. |
58 | * |
59 | * Return value: `true` if data found, `false` otherwise |
60 | * |
61 | * Since: 1.4.2 |
62 | **/ |
63 | hb_bool_t |
64 | hb_ot_var_has_data (hb_face_t *face) |
65 | { |
66 | return face->table.fvar->has_data (); |
67 | } |
68 | |
69 | /** |
70 | * hb_ot_var_get_axis_count: |
71 | * @face: The #hb_face_t to work on |
72 | * |
73 | * Fetches the number of OpenType variation axes included in the face. |
74 | * |
75 | * Return value: the number of variation axes defined |
76 | * |
77 | * Since: 1.4.2 |
78 | **/ |
79 | unsigned int |
80 | hb_ot_var_get_axis_count (hb_face_t *face) |
81 | { |
82 | return face->table.fvar->get_axis_count (); |
83 | } |
84 | |
85 | #ifndef HB_DISABLE_DEPRECATED |
86 | /** |
87 | * hb_ot_var_get_axes: |
88 | * @face: #hb_face_t to work upon |
89 | * @start_offset: offset of the first lookup to retrieve |
90 | * @axes_count: (inout) (optional): Input = the maximum number of variation axes to return; |
91 | * Output = the actual number of variation axes returned (may be zero) |
92 | * @axes_array: (out caller-allocates) (array length=axes_count): The array of variation axes found |
93 | * |
94 | * Fetches a list of all variation axes in the specified face. The list returned will begin |
95 | * at the offset provided. |
96 | * |
97 | * Since: 1.4.2 |
98 | * Deprecated: 2.2.0: use hb_ot_var_get_axis_infos() instead |
99 | **/ |
100 | unsigned int |
101 | hb_ot_var_get_axes (hb_face_t *face, |
102 | unsigned int start_offset, |
103 | unsigned int *axes_count /* IN/OUT */, |
104 | hb_ot_var_axis_t *axes_array /* OUT */) |
105 | { |
106 | return face->table.fvar->get_axes_deprecated (start_offset, axes_count, axes_array); |
107 | } |
108 | |
109 | /** |
110 | * hb_ot_var_find_axis: |
111 | * @face: #hb_face_t to work upon |
112 | * @axis_tag: The #hb_tag_t of the variation axis to query |
113 | * @axis_index: The index of the variation axis |
114 | * @axis_info: (out): The #hb_ot_var_axis_info_t of the axis tag queried |
115 | * |
116 | * Fetches the variation-axis information corresponding to the specified axis tag |
117 | * in the specified face. |
118 | * |
119 | * Since: 1.4.2 |
120 | * Deprecated: 2.2.0 - use hb_ot_var_find_axis_info() instead |
121 | **/ |
122 | hb_bool_t |
123 | hb_ot_var_find_axis (hb_face_t *face, |
124 | hb_tag_t axis_tag, |
125 | unsigned int *axis_index, |
126 | hb_ot_var_axis_t *axis_info) |
127 | { |
128 | return face->table.fvar->find_axis_deprecated (axis_tag, axis_index, axis_info); |
129 | } |
130 | #endif |
131 | |
132 | /** |
133 | * hb_ot_var_get_axis_infos: |
134 | * @face: #hb_face_t to work upon |
135 | * @start_offset: offset of the first lookup to retrieve |
136 | * @axes_count: (inout) (optional): Input = the maximum number of variation axes to return; |
137 | * Output = the actual number of variation axes returned (may be zero) |
138 | * @axes_array: (out caller-allocates) (array length=axes_count): The array of variation axes found |
139 | * |
140 | * Fetches a list of all variation axes in the specified face. The list returned will begin |
141 | * at the offset provided. |
142 | * |
143 | * Return value: the number of variation axes in the face |
144 | * |
145 | * Since: 2.2.0 |
146 | **/ |
147 | HB_EXTERN unsigned int |
148 | hb_ot_var_get_axis_infos (hb_face_t *face, |
149 | unsigned int start_offset, |
150 | unsigned int *axes_count /* IN/OUT */, |
151 | hb_ot_var_axis_info_t *axes_array /* OUT */) |
152 | { |
153 | return face->table.fvar->get_axis_infos (start_offset, axes_count, axes_array); |
154 | } |
155 | |
156 | /** |
157 | * hb_ot_var_find_axis_info: |
158 | * @face: #hb_face_t to work upon |
159 | * @axis_tag: The #hb_tag_t of the variation axis to query |
160 | * @axis_info: (out): The #hb_ot_var_axis_info_t of the axis tag queried |
161 | * |
162 | * Fetches the variation-axis information corresponding to the specified axis tag |
163 | * in the specified face. |
164 | * |
165 | * Return value: `true` if data found, `false` otherwise |
166 | * |
167 | * Since: 2.2.0 |
168 | **/ |
169 | HB_EXTERN hb_bool_t |
170 | hb_ot_var_find_axis_info (hb_face_t *face, |
171 | hb_tag_t axis_tag, |
172 | hb_ot_var_axis_info_t *axis_info) |
173 | { |
174 | return face->table.fvar->find_axis_info (axis_tag, axis_info); |
175 | } |
176 | |
177 | |
178 | /* |
179 | * Named instances. |
180 | */ |
181 | |
182 | /** |
183 | * hb_ot_var_get_named_instance_count: |
184 | * @face: The #hb_face_t to work on |
185 | * |
186 | * Fetches the number of named instances included in the face. |
187 | * |
188 | * Return value: the number of named instances defined |
189 | * |
190 | * Since: 2.2.0 |
191 | **/ |
192 | unsigned int |
193 | hb_ot_var_get_named_instance_count (hb_face_t *face) |
194 | { |
195 | return face->table.fvar->get_instance_count (); |
196 | } |
197 | |
198 | /** |
199 | * hb_ot_var_named_instance_get_subfamily_name_id: |
200 | * @face: The #hb_face_t to work on |
201 | * @instance_index: The index of the named instance to query |
202 | * |
203 | * Fetches the `name` table Name ID that provides display names for |
204 | * the "Subfamily name" defined for the given named instance in the face. |
205 | * |
206 | * Return value: the Name ID found for the Subfamily name |
207 | * |
208 | * Since: 2.2.0 |
209 | **/ |
210 | hb_ot_name_id_t |
211 | hb_ot_var_named_instance_get_subfamily_name_id (hb_face_t *face, |
212 | unsigned int instance_index) |
213 | { |
214 | return face->table.fvar->get_instance_subfamily_name_id (instance_index); |
215 | } |
216 | |
217 | /** |
218 | * hb_ot_var_named_instance_get_postscript_name_id: |
219 | * @face: The #hb_face_t to work on |
220 | * @instance_index: The index of the named instance to query |
221 | * |
222 | * Fetches the `name` table Name ID that provides display names for |
223 | * the "PostScript name" defined for the given named instance in the face. |
224 | * |
225 | * Return value: the Name ID found for the PostScript name |
226 | * |
227 | * Since: 2.2.0 |
228 | **/ |
229 | hb_ot_name_id_t |
230 | hb_ot_var_named_instance_get_postscript_name_id (hb_face_t *face, |
231 | unsigned int instance_index) |
232 | { |
233 | return face->table.fvar->get_instance_postscript_name_id (instance_index); |
234 | } |
235 | |
236 | /** |
237 | * hb_ot_var_named_instance_get_design_coords: |
238 | * @face: The #hb_face_t to work on |
239 | * @instance_index: The index of the named instance to query |
240 | * @coords_length: (inout) (optional): Input = the maximum number of coordinates to return; |
241 | * Output = the actual number of coordinates returned (may be zero) |
242 | * @coords: (out) (array length=coords_length): The array of coordinates found for the query |
243 | * |
244 | * Fetches the design-space coordinates corresponding to the given |
245 | * named instance in the face. |
246 | * |
247 | * Return value: the number of variation axes in the face |
248 | * |
249 | * Since: 2.2.0 |
250 | **/ |
251 | unsigned int |
252 | hb_ot_var_named_instance_get_design_coords (hb_face_t *face, |
253 | unsigned int instance_index, |
254 | unsigned int *coords_length, /* IN/OUT */ |
255 | float *coords /* OUT */) |
256 | { |
257 | return face->table.fvar->get_instance_coords (instance_index, coords_length, coords); |
258 | } |
259 | |
260 | |
261 | /** |
262 | * hb_ot_var_normalize_variations: |
263 | * @face: The #hb_face_t to work on |
264 | * @variations: The array of variations to normalize |
265 | * @variations_length: The number of variations to normalize |
266 | * @coords: (out) (array length=coords_length): The array of normalized coordinates |
267 | * @coords_length: The length of the coordinate array |
268 | * |
269 | * Normalizes all of the coordinates in the given list of variation axes. |
270 | * |
271 | * Since: 1.4.2 |
272 | **/ |
273 | void |
274 | hb_ot_var_normalize_variations (hb_face_t *face, |
275 | const hb_variation_t *variations, /* IN */ |
276 | unsigned int variations_length, |
277 | int *coords, /* OUT */ |
278 | unsigned int coords_length) |
279 | { |
280 | for (unsigned int i = 0; i < coords_length; i++) |
281 | coords[i] = 0; |
282 | |
283 | const OT::fvar &fvar = *face->table.fvar; |
284 | for (unsigned int i = 0; i < variations_length; i++) |
285 | { |
286 | hb_ot_var_axis_info_t info; |
287 | if (hb_ot_var_find_axis_info (face, variations[i].tag, &info) && |
288 | info.axis_index < coords_length) |
289 | coords[info.axis_index] = fvar.normalize_axis_value (info.axis_index, variations[i].value); |
290 | } |
291 | |
292 | face->table.avar->map_coords (coords, coords_length); |
293 | } |
294 | |
295 | /** |
296 | * hb_ot_var_normalize_coords: |
297 | * @face: The #hb_face_t to work on |
298 | * @coords_length: The length of the coordinate array |
299 | * @design_coords: The design-space coordinates to normalize |
300 | * @normalized_coords: (out): The normalized coordinates |
301 | * |
302 | * Normalizes the given design-space coordinates. The minimum and maximum |
303 | * values for the axis are mapped to the interval [-1,1], with the default |
304 | * axis value mapped to 0. |
305 | * |
306 | * The normalized values have 14 bits of fixed-point sub-integer precision as per |
307 | * OpenType specification. |
308 | * |
309 | * Any additional scaling defined in the face's `avar` table is also |
310 | * applied, as described at https://docs.microsoft.com/en-us/typography/opentype/spec/avar |
311 | * |
312 | * Since: 1.4.2 |
313 | **/ |
314 | void |
315 | hb_ot_var_normalize_coords (hb_face_t *face, |
316 | unsigned int coords_length, |
317 | const float *design_coords, /* IN */ |
318 | int *normalized_coords /* OUT */) |
319 | { |
320 | const OT::fvar &fvar = *face->table.fvar; |
321 | for (unsigned int i = 0; i < coords_length; i++) |
322 | normalized_coords[i] = fvar.normalize_axis_value (i, design_coords[i]); |
323 | |
324 | face->table.avar->map_coords (normalized_coords, coords_length); |
325 | } |
326 | |
327 | |
328 | #endif |
329 | |