|
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-open-type-private.hh" |
|
28 |
|
29 #include "hb-ot-layout-private.hh" |
|
30 #include "hb-ot-var-avar-table.hh" |
|
31 #include "hb-ot-var-fvar-table.hh" |
|
32 #include "hb-ot-var-mvar-table.hh" |
|
33 #include "hb-ot-var.h" |
|
34 |
|
35 /* |
|
36 * fvar/avar |
|
37 */ |
|
38 |
|
39 static inline const OT::fvar& |
|
40 _get_fvar (hb_face_t *face) |
|
41 { |
|
42 if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::fvar); |
|
43 hb_ot_layout_t * layout = hb_ot_layout_from_face (face); |
|
44 return *(layout->fvar.get ()); |
|
45 } |
|
46 static inline const OT::avar& |
|
47 _get_avar (hb_face_t *face) |
|
48 { |
|
49 if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::avar); |
|
50 hb_ot_layout_t * layout = hb_ot_layout_from_face (face); |
|
51 return *(layout->avar.get ()); |
|
52 } |
|
53 |
|
54 /** |
|
55 * hb_ot_var_has_data: |
|
56 * @face: #hb_face_t to test |
|
57 * |
|
58 * This function allows to verify the presence of OpenType variation data on the face. |
|
59 * Alternatively, use hb_ot_var_get_axis_count(). |
|
60 * |
|
61 * Return value: true if face has a `fvar' table and false otherwise |
|
62 * |
|
63 * Since: 1.4.2 |
|
64 **/ |
|
65 hb_bool_t |
|
66 hb_ot_var_has_data (hb_face_t *face) |
|
67 { |
|
68 return &_get_fvar (face) != &OT::Null(OT::fvar); |
|
69 } |
|
70 |
|
71 /** |
|
72 * hb_ot_var_get_axis_count: |
|
73 * |
|
74 * Since: 1.4.2 |
|
75 **/ |
|
76 unsigned int |
|
77 hb_ot_var_get_axis_count (hb_face_t *face) |
|
78 { |
|
79 const OT::fvar &fvar = _get_fvar (face); |
|
80 return fvar.get_axis_count (); |
|
81 } |
|
82 |
|
83 /** |
|
84 * hb_ot_var_get_axes: |
|
85 * |
|
86 * Since: 1.4.2 |
|
87 **/ |
|
88 unsigned int |
|
89 hb_ot_var_get_axes (hb_face_t *face, |
|
90 unsigned int start_offset, |
|
91 unsigned int *axes_count /* IN/OUT */, |
|
92 hb_ot_var_axis_t *axes_array /* OUT */) |
|
93 { |
|
94 const OT::fvar &fvar = _get_fvar (face); |
|
95 return fvar.get_axis_infos (start_offset, axes_count, axes_array); |
|
96 } |
|
97 |
|
98 /** |
|
99 * hb_ot_var_find_axis: |
|
100 * |
|
101 * Since: 1.4.2 |
|
102 **/ |
|
103 hb_bool_t |
|
104 hb_ot_var_find_axis (hb_face_t *face, |
|
105 hb_tag_t axis_tag, |
|
106 unsigned int *axis_index, |
|
107 hb_ot_var_axis_t *axis_info) |
|
108 { |
|
109 const OT::fvar &fvar = _get_fvar (face); |
|
110 return fvar.find_axis (axis_tag, axis_index, axis_info); |
|
111 } |
|
112 |
|
113 |
|
114 /** |
|
115 * hb_ot_var_normalize_variations: |
|
116 * |
|
117 * Since: 1.4.2 |
|
118 **/ |
|
119 void |
|
120 hb_ot_var_normalize_variations (hb_face_t *face, |
|
121 const hb_variation_t *variations, /* IN */ |
|
122 unsigned int variations_length, |
|
123 int *coords, /* OUT */ |
|
124 unsigned int coords_length) |
|
125 { |
|
126 for (unsigned int i = 0; i < coords_length; i++) |
|
127 coords[i] = 0; |
|
128 |
|
129 const OT::fvar &fvar = _get_fvar (face); |
|
130 for (unsigned int i = 0; i < variations_length; i++) |
|
131 { |
|
132 unsigned int axis_index; |
|
133 if (hb_ot_var_find_axis (face, variations[i].tag, &axis_index, nullptr) && |
|
134 axis_index < coords_length) |
|
135 coords[axis_index] = fvar.normalize_axis_value (axis_index, variations[i].value); |
|
136 } |
|
137 |
|
138 const OT::avar &avar = _get_avar (face); |
|
139 avar.map_coords (coords, coords_length); |
|
140 } |
|
141 |
|
142 /** |
|
143 * hb_ot_var_normalize_coords: |
|
144 * |
|
145 * Since: 1.4.2 |
|
146 **/ |
|
147 void |
|
148 hb_ot_var_normalize_coords (hb_face_t *face, |
|
149 unsigned int coords_length, |
|
150 const float *design_coords, /* IN */ |
|
151 int *normalized_coords /* OUT */) |
|
152 { |
|
153 const OT::fvar &fvar = _get_fvar (face); |
|
154 for (unsigned int i = 0; i < coords_length; i++) |
|
155 normalized_coords[i] = fvar.normalize_axis_value (i, design_coords[i]); |
|
156 |
|
157 const OT::avar &avar = _get_avar (face); |
|
158 avar.map_coords (normalized_coords, coords_length); |
|
159 } |