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 **/
63hb_bool_t
64hb_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 **/
79unsigned int
80hb_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 **/
100unsigned int
101hb_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 **/
122hb_bool_t
123hb_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 **/
147HB_EXTERN unsigned int
148hb_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 **/
169HB_EXTERN hb_bool_t
170hb_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 **/
192unsigned int
193hb_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 **/
210hb_ot_name_id_t
211hb_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 **/
229hb_ot_name_id_t
230hb_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 **/
251unsigned int
252hb_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 **/
273void
274hb_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 **/
314void
315hb_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