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
hb_ot_var_has_data(hb_face_t * face)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
hb_ot_var_get_axis_count(hb_face_t * face)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
hb_ot_var_get_axes(hb_face_t * face,unsigned int start_offset,unsigned int * axes_count,hb_ot_var_axis_t * axes_array)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
hb_ot_var_find_axis(hb_face_t * face,hb_tag_t axis_tag,unsigned int * axis_index,hb_ot_var_axis_t * axis_info)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
hb_ot_var_get_axis_infos(hb_face_t * face,unsigned int start_offset,unsigned int * axes_count,hb_ot_var_axis_info_t * axes_array)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
hb_ot_var_find_axis_info(hb_face_t * face,hb_tag_t axis_tag,hb_ot_var_axis_info_t * axis_info)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
hb_ot_var_get_named_instance_count(hb_face_t * face)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
hb_ot_var_named_instance_get_subfamily_name_id(hb_face_t * face,unsigned int instance_index)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
hb_ot_var_named_instance_get_postscript_name_id(hb_face_t * face,unsigned int instance_index)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
hb_ot_var_named_instance_get_design_coords(hb_face_t * face,unsigned int instance_index,unsigned int * coords_length,float * coords)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
hb_ot_var_normalize_variations(hb_face_t * face,const hb_variation_t * variations,unsigned int variations_length,int * coords,unsigned int coords_length)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 * Any additional scaling defined in the face's `avar` table is also
307 * applied, as described at https://docs.microsoft.com/en-us/typography/opentype/spec/avar
308 *
309 * Since: 1.4.2
310 **/
311 void
hb_ot_var_normalize_coords(hb_face_t * face,unsigned int coords_length,const float * design_coords,int * normalized_coords)312 hb_ot_var_normalize_coords (hb_face_t *face,
313 unsigned int coords_length,
314 const float *design_coords, /* IN */
315 int *normalized_coords /* OUT */)
316 {
317 const OT::fvar &fvar = *face->table.fvar;
318 for (unsigned int i = 0; i < coords_length; i++)
319 normalized_coords[i] = fvar.normalize_axis_value (i, design_coords[i]);
320
321 face->table.avar->map_coords (normalized_coords, coords_length);
322 }
323
324
325 #endif
326