OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009 Red Hat, Inc. | 2 * Copyright © 2009 Red Hat, Inc. |
3 * | 3 * |
4 * This is part of HarfBuzz, a text shaping library. | 4 * This is part of HarfBuzz, a text shaping library. |
5 * | 5 * |
6 * Permission is hereby granted, without written agreement and without | 6 * Permission is hereby granted, without written agreement and without |
7 * license or royalty fees, to use, copy, modify, and distribute this | 7 * license or royalty fees, to use, copy, modify, and distribute this |
8 * software and its documentation for any purpose, provided that the | 8 * software and its documentation for any purpose, provided that the |
9 * above copyright notice and the following two paragraphs appear in | 9 * above copyright notice and the following two paragraphs appear in |
10 * all copies of this software. | 10 * all copies of this software. |
11 * | 11 * |
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR | 12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES | 13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN | 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 | 15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
16 * DAMAGE. | 16 * DAMAGE. |
17 * | 17 * |
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, | 18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | 19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS | 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 | 21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | 22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
23 * | 23 * |
24 * Red Hat Author(s): Behdad Esfahbod | 24 * Red Hat Author(s): Behdad Esfahbod |
25 */ | 25 */ |
26 | 26 |
27 #include "hb-private.h" | 27 #include "hb-private.hh" |
28 | 28 |
29 #include "hb-font-private.h" | 29 #include "hb-ot-layout-private.hh" |
30 #include "hb-blob-private.h" | 30 |
| 31 #include "hb-font-private.hh" |
| 32 #include "hb-blob.h" |
31 #include "hb-open-file-private.hh" | 33 #include "hb-open-file-private.hh" |
32 | 34 #include "hb-ot-head-table.hh" |
33 #include "hb-ot-layout-private.hh" | |
34 | 35 |
35 #include <string.h> | 36 #include <string.h> |
36 | 37 |
37 HB_BEGIN_DECLS | |
38 | 38 |
39 | 39 |
40 /* | 40 /* |
41 * hb_font_funcs_t | 41 * hb_font_funcs_t |
42 */ | 42 */ |
43 | 43 |
44 static hb_codepoint_t | 44 static hb_bool_t |
45 hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED, | 45 hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED, |
46 » » hb_face_t *face HB_UNUSED, | 46 » » void *font_data HB_UNUSED, |
47 » » const void *user_data HB_UNUSED, | 47 » » hb_codepoint_t unicode, |
48 » » hb_codepoint_t unicode HB_UNUSED, | 48 » » hb_codepoint_t variation_selector, |
49 » » hb_codepoint_t variation_selector HB_UNUSED) | 49 » » hb_codepoint_t *glyph, |
50 { return 0; } | 50 » » void *user_data HB_UNUSED) |
51 | 51 { |
52 static void | 52 if (font->parent) |
53 hb_font_get_glyph_advance_nil (hb_font_t *font HB_UNUSED, | 53 return hb_font_get_glyph (font->parent, unicode, variation_selector, glyph); |
54 » » » hb_face_t *face HB_UNUSED, | 54 |
55 » » » const void *user_data HB_UNUSED, | 55 *glyph = 0; |
56 » » » hb_codepoint_t glyph HB_UNUSED, | 56 return FALSE; |
57 » » » hb_position_t *x_advance HB_UNUSED, | 57 } |
58 » » » hb_position_t *y_advance HB_UNUSED) | 58 |
59 { } | 59 static hb_position_t |
60 | 60 hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED, |
61 static void | 61 » » » » void *font_data HB_UNUSED, |
| 62 » » » » hb_codepoint_t glyph, |
| 63 » » » » void *user_data HB_UNUSED) |
| 64 { |
| 65 if (font->parent) |
| 66 return font->parent_scale_x_distance (hb_font_get_glyph_h_advance (font->par
ent, glyph)); |
| 67 |
| 68 return font->x_scale; |
| 69 } |
| 70 |
| 71 static hb_position_t |
| 72 hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED, |
| 73 » » » » void *font_data HB_UNUSED, |
| 74 » » » » hb_codepoint_t glyph, |
| 75 » » » » void *user_data HB_UNUSED) |
| 76 { |
| 77 if (font->parent) |
| 78 return font->parent_scale_y_distance (hb_font_get_glyph_v_advance (font->par
ent, glyph)); |
| 79 |
| 80 return font->y_scale; |
| 81 } |
| 82 |
| 83 static hb_bool_t |
| 84 hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED, |
| 85 » » » » void *font_data HB_UNUSED, |
| 86 » » » » hb_codepoint_t glyph, |
| 87 » » » » hb_position_t *x, |
| 88 » » » » hb_position_t *y, |
| 89 » » » » void *user_data HB_UNUSED) |
| 90 { |
| 91 if (font->parent) { |
| 92 hb_bool_t ret = hb_font_get_glyph_h_origin (font->parent, |
| 93 » » » » » » glyph, |
| 94 » » » » » » x, y); |
| 95 if (ret) |
| 96 font->parent_scale_position (x, y); |
| 97 return ret; |
| 98 } |
| 99 |
| 100 *x = *y = 0; |
| 101 return FALSE; |
| 102 } |
| 103 |
| 104 static hb_bool_t |
| 105 hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED, |
| 106 » » » » void *font_data HB_UNUSED, |
| 107 » » » » hb_codepoint_t glyph, |
| 108 » » » » hb_position_t *x, |
| 109 » » » » hb_position_t *y, |
| 110 » » » » void *user_data HB_UNUSED) |
| 111 { |
| 112 if (font->parent) { |
| 113 hb_bool_t ret = hb_font_get_glyph_v_origin (font->parent, |
| 114 » » » » » » glyph, |
| 115 » » » » » » x, y); |
| 116 if (ret) |
| 117 font->parent_scale_position (x, y); |
| 118 return ret; |
| 119 } |
| 120 |
| 121 *x = *y = 0; |
| 122 return FALSE; |
| 123 } |
| 124 |
| 125 static hb_position_t |
| 126 hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED, |
| 127 » » » » void *font_data HB_UNUSED, |
| 128 » » » » hb_codepoint_t left_glyph, |
| 129 » » » » hb_codepoint_t right_glyph, |
| 130 » » » » void *user_data HB_UNUSED) |
| 131 { |
| 132 if (font->parent) |
| 133 return font->parent_scale_x_distance (hb_font_get_glyph_h_kerning (font->par
ent, left_glyph, right_glyph)); |
| 134 |
| 135 return 0; |
| 136 } |
| 137 |
| 138 static hb_position_t |
| 139 hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED, |
| 140 » » » » void *font_data HB_UNUSED, |
| 141 » » » » hb_codepoint_t top_glyph, |
| 142 » » » » hb_codepoint_t bottom_glyph, |
| 143 » » » » void *user_data HB_UNUSED) |
| 144 { |
| 145 if (font->parent) |
| 146 return font->parent_scale_y_distance (hb_font_get_glyph_v_kerning (font->par
ent, top_glyph, bottom_glyph)); |
| 147 |
| 148 return 0; |
| 149 } |
| 150 |
| 151 static hb_bool_t |
62 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED, | 152 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED, |
63 » » » hb_face_t *face HB_UNUSED, | 153 » » » void *font_data HB_UNUSED, |
64 » » » const void *user_data HB_UNUSED, | 154 » » » hb_codepoint_t glyph, |
65 » » » hb_codepoint_t glyph HB_UNUSED, | 155 » » » hb_glyph_extents_t *extents, |
66 » » » hb_glyph_extents_t *extents HB_UNUSED) | 156 » » » void *user_data HB_UNUSED) |
67 { } | 157 { |
68 | 158 if (font->parent) { |
69 static hb_bool_t | 159 hb_bool_t ret = hb_font_get_glyph_extents (font->parent, |
70 hb_font_get_contour_point_nil (hb_font_t *font HB_UNUSED, | 160 » » » » » glyph, |
71 » » » hb_face_t *face HB_UNUSED, | 161 » » » » » extents); |
72 » » » const void *user_data HB_UNUSED, | 162 if (ret) { |
73 » » » unsigned int point_index HB_UNUSED, | 163 font->parent_scale_position (&extents->x_bearing, &extents->y_bearing); |
74 » » » hb_codepoint_t glyph HB_UNUSED, | 164 font->parent_scale_distance (&extents->width, &extents->height); |
75 » » » hb_position_t *x HB_UNUSED, | 165 } |
76 » » » hb_position_t *y HB_UNUSED) | 166 return ret; |
77 { return false; } | 167 } |
78 | 168 |
79 static hb_position_t | 169 memset (extents, 0, sizeof (*extents)); |
80 hb_font_get_kerning_nil (hb_font_t *font HB_UNUSED, | 170 return FALSE; |
81 » » » hb_face_t *face HB_UNUSED, | 171 } |
82 » » » const void *user_data HB_UNUSED, | 172 |
83 » » » hb_codepoint_t first_glyph HB_UNUSED, | 173 static hb_bool_t |
84 » » » hb_codepoint_t second_glyph HB_UNUSED) | 174 hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED, |
85 { return 0; } | 175 » » » » void *font_data HB_UNUSED, |
86 | 176 » » » » hb_codepoint_t glyph, |
87 hb_font_funcs_t _hb_font_funcs_nil = { | 177 » » » » unsigned int point_index, |
88 HB_REFERENCE_COUNT_INVALID, /* ref_count */ | 178 » » » » hb_position_t *x, |
89 TRUE, /* immutable */ | 179 » » » » hb_position_t *y, |
| 180 » » » » void *user_data HB_UNUSED) |
| 181 { |
| 182 if (font->parent) { |
| 183 hb_bool_t ret = hb_font_get_glyph_contour_point (font->parent, |
| 184 » » » » » » glyph, point_index, |
| 185 » » » » » » x, y); |
| 186 if (ret) |
| 187 font->parent_scale_position (x, y); |
| 188 return ret; |
| 189 } |
| 190 |
| 191 *x = *y = 0; |
| 192 return FALSE; |
| 193 } |
| 194 |
| 195 |
| 196 static hb_font_funcs_t _hb_font_funcs_nil = { |
| 197 HB_OBJECT_HEADER_STATIC, |
| 198 |
| 199 TRUE, /* immutable */ |
| 200 |
90 { | 201 { |
91 hb_font_get_glyph_nil, | 202 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil, |
92 hb_font_get_glyph_advance_nil, | 203 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS |
93 hb_font_get_glyph_extents_nil, | 204 #undef HB_FONT_FUNC_IMPLEMENT |
94 hb_font_get_contour_point_nil, | |
95 hb_font_get_kerning_nil | |
96 } | 205 } |
97 }; | 206 }; |
98 | 207 |
| 208 |
99 hb_font_funcs_t * | 209 hb_font_funcs_t * |
100 hb_font_funcs_create (void) | 210 hb_font_funcs_create (void) |
101 { | 211 { |
102 hb_font_funcs_t *ffuncs; | 212 hb_font_funcs_t *ffuncs; |
103 | 213 |
104 if (!HB_OBJECT_DO_CREATE (hb_font_funcs_t, ffuncs)) | 214 if (!(ffuncs = hb_object_create<hb_font_funcs_t> ())) |
105 return &_hb_font_funcs_nil; | 215 return &_hb_font_funcs_nil; |
106 | 216 |
107 ffuncs->v = _hb_font_funcs_nil.v; | 217 ffuncs->get = _hb_font_funcs_nil.get; |
108 | 218 |
109 return ffuncs; | 219 return ffuncs; |
110 } | 220 } |
111 | 221 |
112 hb_font_funcs_t * | 222 hb_font_funcs_t * |
| 223 hb_font_funcs_get_empty (void) |
| 224 { |
| 225 return &_hb_font_funcs_nil; |
| 226 } |
| 227 |
| 228 hb_font_funcs_t * |
113 hb_font_funcs_reference (hb_font_funcs_t *ffuncs) | 229 hb_font_funcs_reference (hb_font_funcs_t *ffuncs) |
114 { | 230 { |
115 HB_OBJECT_DO_REFERENCE (ffuncs); | 231 return hb_object_reference (ffuncs); |
116 } | |
117 | |
118 unsigned int | |
119 hb_font_funcs_get_reference_count (hb_font_funcs_t *ffuncs) | |
120 { | |
121 HB_OBJECT_DO_GET_REFERENCE_COUNT (ffuncs); | |
122 } | 232 } |
123 | 233 |
124 void | 234 void |
125 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) | 235 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) |
126 { | 236 { |
127 HB_OBJECT_DO_DESTROY (ffuncs); | 237 if (!hb_object_destroy (ffuncs)) return; |
| 238 |
| 239 #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \ |
| 240 ffuncs->destroy.name (ffuncs->user_data.name); |
| 241 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS |
| 242 #undef HB_FONT_FUNC_IMPLEMENT |
128 | 243 |
129 free (ffuncs); | 244 free (ffuncs); |
130 } | 245 } |
131 | 246 |
132 hb_font_funcs_t * | 247 hb_bool_t |
133 hb_font_funcs_copy (hb_font_funcs_t *other_ffuncs) | 248 hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, |
134 { | 249 » » » hb_user_data_key_t *key, |
135 hb_font_funcs_t *ffuncs; | 250 » » » void * data, |
136 | 251 » » » hb_destroy_func_t destroy, |
137 if (!HB_OBJECT_DO_CREATE (hb_font_funcs_t, ffuncs)) | 252 » » » hb_bool_t replace) |
138 return &_hb_font_funcs_nil; | 253 { |
139 | 254 return hb_object_set_user_data (ffuncs, key, data, destroy, replace); |
140 ffuncs->v = other_ffuncs->v; | 255 } |
141 | 256 |
142 return ffuncs; | 257 void * |
143 } | 258 hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, |
| 259 » » » hb_user_data_key_t *key) |
| 260 { |
| 261 return hb_object_get_user_data (ffuncs, key); |
| 262 } |
| 263 |
144 | 264 |
145 void | 265 void |
146 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) | 266 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) |
147 { | 267 { |
148 if (HB_OBJECT_IS_INERT (ffuncs)) | 268 if (hb_object_is_inert (ffuncs)) |
149 return; | 269 return; |
150 | 270 |
151 ffuncs->immutable = TRUE; | 271 ffuncs->immutable = TRUE; |
152 } | 272 } |
153 | 273 |
154 hb_bool_t | 274 hb_bool_t |
155 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) | 275 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) |
156 { | 276 { |
157 return ffuncs->immutable; | 277 return ffuncs->immutable; |
158 } | 278 } |
159 | 279 |
160 | 280 |
161 void | 281 #define HB_FONT_FUNC_IMPLEMENT(name) \ |
162 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, | 282 \ |
163 » » » hb_font_get_glyph_func_t glyph_func) | 283 void \ |
164 { | 284 hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ |
165 if (ffuncs->immutable) | 285 hb_font_get_##name##_func_t func, \ |
166 return; | 286 void *user_data, \ |
167 | 287 hb_destroy_func_t destroy) \ |
168 ffuncs->v.get_glyph = glyph_func ? glyph_func : hb_font_get_glyph_nil; | 288 { \ |
169 } | 289 if (ffuncs->immutable) { \ |
170 | 290 if (destroy) \ |
171 void | 291 destroy (user_data); \ |
172 hb_font_funcs_set_glyph_advance_func (hb_font_funcs_t *ffuncs, | 292 return; \ |
173 » » » » hb_font_get_glyph_advance_func_t glyph_adv
ance_func) | 293 } \ |
174 { | 294 \ |
175 if (ffuncs->immutable) | 295 if (ffuncs->destroy.name) \ |
176 return; | 296 ffuncs->destroy.name (ffuncs->user_data.name); \ |
177 | 297 \ |
178 ffuncs->v.get_glyph_advance = glyph_advance_func ? glyph_advance_func : hb_fon
t_get_glyph_advance_nil; | 298 if (func) { \ |
179 } | 299 ffuncs->get.name = func; \ |
180 | 300 ffuncs->user_data.name = user_data; \ |
181 void | 301 ffuncs->destroy.name = destroy; \ |
182 hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs, | 302 } else { \ |
183 » » » » hb_font_get_glyph_extents_func_t glyph_ext
ents_func) | 303 ffuncs->get.name = hb_font_get_##name##_nil; \ |
184 { | 304 ffuncs->user_data.name = NULL; \ |
185 if (ffuncs->immutable) | 305 ffuncs->destroy.name = NULL; \ |
186 return; | 306 } \ |
187 | 307 } |
188 ffuncs->v.get_glyph_extents = glyph_extents_func ? glyph_extents_func : hb_fon
t_get_glyph_extents_nil; | 308 |
189 } | 309 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS |
190 | 310 #undef HB_FONT_FUNC_IMPLEMENT |
191 void | 311 |
192 hb_font_funcs_set_contour_point_func (hb_font_funcs_t *ffuncs, | 312 |
193 » » » » hb_font_get_contour_point_func_t contour_p
oint_func) | 313 hb_bool_t |
194 { | 314 hb_font_get_glyph (hb_font_t *font, |
195 if (ffuncs->immutable) | 315 » » hb_codepoint_t unicode, hb_codepoint_t variation_selector, |
196 return; | 316 » » hb_codepoint_t *glyph) |
197 | 317 { |
198 ffuncs->v.get_contour_point = contour_point_func ? contour_point_func : hb_fon
t_get_contour_point_nil; | 318 *glyph = 0; |
199 } | 319 return font->klass->get.glyph (font, font->user_data, |
200 | 320 » » » » unicode, variation_selector, glyph, |
201 void | 321 » » » » font->klass->user_data.glyph); |
202 hb_font_funcs_set_kerning_func (hb_font_funcs_t *ffuncs, | 322 } |
203 » » » » hb_font_get_kerning_func_t kerning_func) | 323 |
204 { | 324 hb_position_t |
205 if (ffuncs->immutable) | 325 hb_font_get_glyph_h_advance (hb_font_t *font, |
206 return; | 326 » » » hb_codepoint_t glyph) |
207 | 327 { |
208 ffuncs->v.get_kerning = kerning_func ? kerning_func : hb_font_get_kerning_nil; | 328 return font->klass->get.glyph_h_advance (font, font->user_data, |
209 } | 329 » » » » » glyph, |
210 | 330 » » » » » font->klass->user_data.glyph_h_advanc
e); |
211 | 331 } |
212 hb_font_get_glyph_func_t | 332 |
213 hb_font_funcs_get_glyph_func (hb_font_funcs_t *ffuncs) | 333 hb_position_t |
214 { | 334 hb_font_get_glyph_v_advance (hb_font_t *font, |
215 return ffuncs->v.get_glyph; | 335 » » » hb_codepoint_t glyph) |
216 } | 336 { |
217 | 337 return font->klass->get.glyph_v_advance (font, font->user_data, |
218 hb_font_get_glyph_advance_func_t | 338 » » » » » glyph, |
219 hb_font_funcs_get_glyph_advance_func (hb_font_funcs_t *ffuncs) | 339 » » » » » font->klass->user_data.glyph_v_advanc
e); |
220 { | 340 } |
221 return ffuncs->v.get_glyph_advance; | 341 |
222 } | 342 hb_bool_t |
223 | 343 hb_font_get_glyph_h_origin (hb_font_t *font, |
224 hb_font_get_glyph_extents_func_t | 344 » » » hb_codepoint_t glyph, |
225 hb_font_funcs_get_glyph_extents_func (hb_font_funcs_t *ffuncs) | 345 » » » hb_position_t *x, hb_position_t *y) |
226 { | 346 { |
227 return ffuncs->v.get_glyph_extents; | 347 *x = *y = 0; |
228 } | 348 return font->klass->get.glyph_h_origin (font, font->user_data, |
229 | 349 » » » » » glyph, x, y, |
230 hb_font_get_contour_point_func_t | 350 » » » » » font->klass->user_data.glyph_h_origin
); |
231 hb_font_funcs_get_contour_point_func (hb_font_funcs_t *ffuncs) | 351 } |
232 { | 352 |
233 return ffuncs->v.get_contour_point; | 353 hb_bool_t |
234 } | 354 hb_font_get_glyph_v_origin (hb_font_t *font, |
235 | 355 » » » hb_codepoint_t glyph, |
236 hb_font_get_kerning_func_t | 356 » » » hb_position_t *x, hb_position_t *y) |
237 hb_font_funcs_get_kerning_func (hb_font_funcs_t *ffuncs) | 357 { |
238 { | 358 *x = *y = 0; |
239 return ffuncs->v.get_kerning; | 359 return font->klass->get.glyph_v_origin (font, font->user_data, |
240 } | 360 » » » » » glyph, x, y, |
241 | 361 » » » » » font->klass->user_data.glyph_v_origin
); |
242 | 362 } |
243 | 363 |
244 hb_codepoint_t | 364 hb_position_t |
245 hb_font_get_glyph (hb_font_t *font, hb_face_t *face, | 365 hb_font_get_glyph_h_kerning (hb_font_t *font, |
246 » » hb_codepoint_t unicode, hb_codepoint_t variation_selector) | 366 » » » hb_codepoint_t left_glyph, hb_codepoint_t right_gly
ph) |
247 { | 367 { |
248 return font->klass->v.get_glyph (font, face, font->user_data, | 368 return font->klass->get.glyph_h_kerning (font, font->user_data, |
249 » » » » unicode, variation_selector); | 369 » » » » » left_glyph, right_glyph, |
250 } | 370 » » » » » font->klass->user_data.glyph_h_kernin
g); |
251 | 371 } |
252 void | 372 |
253 hb_font_get_glyph_advance (hb_font_t *font, hb_face_t *face, | 373 hb_position_t |
| 374 hb_font_get_glyph_v_kerning (hb_font_t *font, |
| 375 » » » hb_codepoint_t left_glyph, hb_codepoint_t right_gly
ph) |
| 376 { |
| 377 return font->klass->get.glyph_v_kerning (font, font->user_data, |
| 378 » » » » left_glyph, right_glyph, |
| 379 » » » » font->klass->user_data.glyph_v_kerning); |
| 380 } |
| 381 |
| 382 hb_bool_t |
| 383 hb_font_get_glyph_extents (hb_font_t *font, |
254 hb_codepoint_t glyph, | 384 hb_codepoint_t glyph, |
255 » » » hb_position_t *x_advance, hb_position_t *y_advance) | 385 » » » hb_glyph_extents_t *extents) |
256 { | |
257 *x_advance = *y_advance = 0; | |
258 return font->klass->v.get_glyph_advance (font, face, font->user_data, | |
259 » » » » » glyph, x_advance, y_advance); | |
260 } | |
261 | |
262 void | |
263 hb_font_get_glyph_extents (hb_font_t *font, hb_face_t *face, | |
264 » » » hb_codepoint_t glyph, hb_glyph_extents_t *extents) | |
265 { | 386 { |
266 memset (extents, 0, sizeof (*extents)); | 387 memset (extents, 0, sizeof (*extents)); |
267 return font->klass->v.get_glyph_extents (font, face, font->user_data, | 388 return font->klass->get.glyph_extents (font, font->user_data, |
268 » » » » » glyph, extents); | 389 » » » » » glyph, |
269 } | 390 » » » » » extents, |
270 | 391 » » » » » font->klass->user_data.glyph_extents); |
271 hb_bool_t | 392 } |
272 hb_font_get_contour_point (hb_font_t *font, hb_face_t *face, | 393 |
273 » » » unsigned int point_index, | 394 hb_bool_t |
274 » » » hb_codepoint_t glyph, hb_position_t *x, hb_position_t
*y) | 395 hb_font_get_glyph_contour_point (hb_font_t *font, |
275 { | 396 » » » » hb_codepoint_t glyph, unsigned int point_index, |
276 *x = 0; *y = 0; | 397 » » » » hb_position_t *x, hb_position_t *y) |
277 return font->klass->v.get_contour_point (font, face, font->user_data, | 398 { |
278 » » » » » point_index, | 399 *x = *y = 0; |
279 » » » » » glyph, x, y); | 400 return font->klass->get.glyph_contour_point (font, font->user_data, |
280 } | 401 » » » » » glyph, point_index, |
281 | 402 » » » » » x, y, |
282 hb_position_t | 403 » » » » » font->klass->user_data.glyph_cont
our_point); |
283 hb_font_get_kerning (hb_font_t *font, hb_face_t *face, | 404 } |
284 » » hb_codepoint_t first_glyph, hb_codepoint_t second_glyph) | 405 |
285 { | 406 |
286 return font->klass->v.get_kerning (font, face, font->user_data, | 407 /* A bit higher-level, and with fallback */ |
287 » » » » first_glyph, second_glyph); | 408 |
288 } | 409 void |
289 | 410 hb_font_get_glyph_advance_for_direction (hb_font_t *font, |
290 | 411 » » » » » hb_codepoint_t glyph, |
| 412 » » » » » hb_direction_t direction, |
| 413 » » » » » hb_position_t *x, hb_position_t *y) |
| 414 { |
| 415 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { |
| 416 *x = hb_font_get_glyph_h_advance (font, glyph); |
| 417 *y = 0; |
| 418 } else { |
| 419 *x = 0; |
| 420 *y = hb_font_get_glyph_v_advance (font, glyph); |
| 421 } |
| 422 } |
| 423 |
| 424 static void |
| 425 guess_v_origin_minus_h_origin (hb_font_t *font, |
| 426 » » » hb_codepoint_t glyph, |
| 427 » » » hb_position_t *x, hb_position_t *y) |
| 428 { |
| 429 *x = hb_font_get_glyph_h_advance (font, glyph) / 2; |
| 430 |
| 431 /* TODO use font_metics.ascent */ |
| 432 *y = font->y_scale; |
| 433 } |
| 434 |
| 435 |
| 436 void |
| 437 hb_font_get_glyph_origin_for_direction (hb_font_t *font, |
| 438 » » » » » hb_codepoint_t glyph, |
| 439 » » » » » hb_direction_t direction, |
| 440 » » » » » hb_position_t *x, hb_position_t *y) |
| 441 { |
| 442 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { |
| 443 hb_bool_t ret = hb_font_get_glyph_h_origin (font, glyph, x, y); |
| 444 if (!ret && (ret = hb_font_get_glyph_v_origin (font, glyph, x, y))) { |
| 445 hb_position_t dx, dy; |
| 446 guess_v_origin_minus_h_origin (font, glyph, &dx, &dy); |
| 447 *x -= dx; *y -= dy; |
| 448 } |
| 449 } else { |
| 450 hb_bool_t ret = hb_font_get_glyph_v_origin (font, glyph, x, y); |
| 451 if (!ret && (ret = hb_font_get_glyph_h_origin (font, glyph, x, y))) { |
| 452 hb_position_t dx, dy; |
| 453 guess_v_origin_minus_h_origin (font, glyph, &dx, &dy); |
| 454 *x += dx; *y += dy; |
| 455 } |
| 456 } |
| 457 } |
| 458 |
| 459 void |
| 460 hb_font_add_glyph_origin_for_direction (hb_font_t *font, |
| 461 » » » » » hb_codepoint_t glyph, |
| 462 » » » » » hb_direction_t direction, |
| 463 » » » » » hb_position_t *x, hb_position_t *y) |
| 464 { |
| 465 hb_position_t origin_x, origin_y; |
| 466 |
| 467 hb_font_get_glyph_origin_for_direction (font, glyph, direction, &origin_x, &or
igin_y); |
| 468 |
| 469 *x += origin_x; |
| 470 *y += origin_y; |
| 471 } |
| 472 |
| 473 void |
| 474 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, |
| 475 » » » » » hb_codepoint_t glyph, |
| 476 » » » » » hb_direction_t direction, |
| 477 » » » » » hb_position_t *x, hb_position_t *y) |
| 478 { |
| 479 hb_position_t origin_x, origin_y; |
| 480 |
| 481 hb_font_get_glyph_origin_for_direction (font, glyph, direction, &origin_x, &or
igin_y); |
| 482 |
| 483 *x -= origin_x; |
| 484 *y -= origin_y; |
| 485 } |
| 486 |
| 487 void |
| 488 hb_font_get_glyph_kerning_for_direction (hb_font_t *font, |
| 489 » » » » » hb_codepoint_t first_glyph, hb_codepoin
t_t second_glyph, |
| 490 » » » » » hb_direction_t direction, |
| 491 » » » » » hb_position_t *x, hb_position_t *y) |
| 492 { |
| 493 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { |
| 494 *x = hb_font_get_glyph_h_kerning (font, first_glyph, second_glyph); |
| 495 *y = 0; |
| 496 } else { |
| 497 *x = 0; |
| 498 *y = hb_font_get_glyph_v_kerning (font, first_glyph, second_glyph); |
| 499 } |
| 500 } |
| 501 |
| 502 hb_bool_t |
| 503 hb_font_get_glyph_extents_for_origin (hb_font_t *font, |
| 504 » » » » hb_codepoint_t glyph, |
| 505 » » » » hb_direction_t direction, |
| 506 » » » » hb_glyph_extents_t *extents) |
| 507 { |
| 508 hb_bool_t ret = hb_font_get_glyph_extents (font, glyph, extents); |
| 509 |
| 510 if (ret) |
| 511 hb_font_subtract_glyph_origin_for_direction (font, glyph, direction, &extent
s->x_bearing, &extents->y_bearing); |
| 512 |
| 513 return ret; |
| 514 } |
| 515 |
| 516 hb_bool_t |
| 517 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, |
| 518 » » » » » hb_codepoint_t glyph, unsigned int p
oint_index, |
| 519 » » » » » hb_direction_t direction, |
| 520 » » » » » hb_position_t *x, hb_position_t *y) |
| 521 { |
| 522 hb_bool_t ret = hb_font_get_glyph_contour_point (font, glyph, point_index, x,
y); |
| 523 |
| 524 if (ret) |
| 525 hb_font_subtract_glyph_origin_for_direction (font, glyph, direction, x, y); |
| 526 |
| 527 return ret; |
| 528 } |
| 529 |
| 530 |
291 /* | 531 /* |
292 * hb_face_t | 532 * hb_face_t |
293 */ | 533 */ |
294 | 534 |
295 static hb_face_t _hb_face_nil = { | 535 static hb_face_t _hb_face_nil = { |
296 HB_REFERENCE_COUNT_INVALID, /* ref_count */ | 536 HB_OBJECT_HEADER_STATIC, |
297 | 537 |
298 NULL, /* get_table */ | 538 TRUE, /* immutable */ |
| 539 |
| 540 NULL, /* reference_table */ |
| 541 NULL, /* user_data */ |
299 NULL, /* destroy */ | 542 NULL, /* destroy */ |
300 NULL, /* user_data */ | |
301 | 543 |
302 NULL, /* head_blob */ | 544 NULL, /* ot_layout */ |
303 NULL, /* head_table */ | |
304 | 545 |
305 NULL /* ot_layout */ | 546 0, /* index */ |
| 547 1000 /* upem */ |
306 }; | 548 }; |
307 | 549 |
308 | 550 |
309 hb_face_t * | 551 hb_face_t * |
310 hb_face_create_for_tables (hb_get_table_func_t get_table, | 552 hb_face_create_for_tables (hb_reference_table_func_t reference_table, |
311 » » » hb_destroy_func_t destroy, | 553 » » » void *user_data, |
312 » » » void *user_data) | 554 » » » hb_destroy_func_t destroy) |
313 { | 555 { |
314 hb_face_t *face; | 556 hb_face_t *face; |
315 | 557 |
316 if (!HB_OBJECT_DO_CREATE (hb_face_t, face)) { | 558 if (!reference_table || !(face = hb_object_create<hb_face_t> ())) { |
317 if (destroy) | 559 if (destroy) |
318 destroy (user_data); | 560 destroy (user_data); |
319 return &_hb_face_nil; | 561 return &_hb_face_nil; |
320 } | 562 } |
321 | 563 |
322 face->get_table = get_table; | 564 face->reference_table = reference_table; |
| 565 face->user_data = user_data; |
323 face->destroy = destroy; | 566 face->destroy = destroy; |
324 face->user_data = user_data; | |
325 | 567 |
326 face->ot_layout = _hb_ot_layout_new (face); | 568 face->ot_layout = _hb_ot_layout_create (face); |
327 | 569 |
328 face->head_blob = Sanitizer<head>::sanitize (hb_face_get_table (face, HB_OT_TA
G_head)); | 570 face->upem = 0; |
329 face->head_table = Sanitizer<head>::lock_instance (face->head_blob); | |
330 | 571 |
331 return face; | 572 return face; |
332 } | 573 } |
333 | 574 |
334 | 575 |
335 typedef struct _hb_face_for_data_closure_t { | 576 typedef struct _hb_face_for_data_closure_t { |
336 hb_blob_t *blob; | 577 hb_blob_t *blob; |
337 unsigned int index; | 578 unsigned int index; |
338 } hb_face_for_data_closure_t; | 579 } hb_face_for_data_closure_t; |
339 | 580 |
(...skipping 13 matching lines...) Expand all Loading... |
353 } | 594 } |
354 | 595 |
355 static void | 596 static void |
356 _hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure) | 597 _hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure) |
357 { | 598 { |
358 hb_blob_destroy (closure->blob); | 599 hb_blob_destroy (closure->blob); |
359 free (closure); | 600 free (closure); |
360 } | 601 } |
361 | 602 |
362 static hb_blob_t * | 603 static hb_blob_t * |
363 _hb_face_for_data_get_table (hb_tag_t tag, void *user_data) | 604 _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
*user_data) |
364 { | 605 { |
365 hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; | 606 hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; |
366 | 607 |
| 608 if (tag == HB_TAG_NONE) |
| 609 return hb_blob_reference (data->blob); |
| 610 |
367 const OpenTypeFontFile &ot_file = *Sanitizer<OpenTypeFontFile>::lock_instance
(data->blob); | 611 const OpenTypeFontFile &ot_file = *Sanitizer<OpenTypeFontFile>::lock_instance
(data->blob); |
368 const OpenTypeFontFace &ot_face = ot_file.get_face (data->index); | 612 const OpenTypeFontFace &ot_face = ot_file.get_face (data->index); |
369 | 613 |
370 const OpenTypeTable &table = ot_face.get_table_by_tag (tag); | 614 const OpenTypeTable &table = ot_face.get_table_by_tag (tag); |
371 | 615 |
372 hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.len
gth); | 616 hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.len
gth); |
373 | 617 |
374 hb_blob_unlock (data->blob); | |
375 | |
376 return blob; | 618 return blob; |
377 } | 619 } |
378 | 620 |
379 hb_face_t * | 621 hb_face_t * |
380 hb_face_create_for_data (hb_blob_t *blob, | 622 hb_face_create (hb_blob_t *blob, |
381 » » » unsigned int index) | 623 » » unsigned int index) |
382 { | 624 { |
| 625 hb_face_t *face; |
| 626 |
| 627 if (unlikely (!blob || !hb_blob_get_length (blob))) |
| 628 return &_hb_face_nil; |
| 629 |
383 hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (Saniti
zer<OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index); | 630 hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (Saniti
zer<OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index); |
384 | 631 |
385 if (unlikely (!closure)) | 632 if (unlikely (!closure)) |
386 return &_hb_face_nil; | 633 return &_hb_face_nil; |
387 | 634 |
388 return hb_face_create_for_tables (_hb_face_for_data_get_table, | 635 face = hb_face_create_for_tables (_hb_face_for_data_reference_table, |
389 » » » » (hb_destroy_func_t) _hb_face_for_data_closur
e_destroy, | 636 » » » » closure, |
390 » » » » closure); | 637 » » » » (hb_destroy_func_t) _hb_face_for_data_closur
e_destroy); |
| 638 |
| 639 hb_face_set_index (face, index); |
| 640 |
| 641 return face; |
| 642 } |
| 643 |
| 644 hb_face_t * |
| 645 hb_face_get_empty (void) |
| 646 { |
| 647 return &_hb_face_nil; |
391 } | 648 } |
392 | 649 |
393 | 650 |
394 hb_face_t * | 651 hb_face_t * |
395 hb_face_reference (hb_face_t *face) | 652 hb_face_reference (hb_face_t *face) |
396 { | 653 { |
397 HB_OBJECT_DO_REFERENCE (face); | 654 return hb_object_reference (face); |
398 } | |
399 | |
400 unsigned int | |
401 hb_face_get_reference_count (hb_face_t *face) | |
402 { | |
403 HB_OBJECT_DO_GET_REFERENCE_COUNT (face); | |
404 } | 655 } |
405 | 656 |
406 void | 657 void |
407 hb_face_destroy (hb_face_t *face) | 658 hb_face_destroy (hb_face_t *face) |
408 { | 659 { |
409 HB_OBJECT_DO_DESTROY (face); | 660 if (!hb_object_destroy (face)) return; |
410 | 661 |
411 _hb_ot_layout_free (face->ot_layout); | 662 _hb_ot_layout_destroy (face->ot_layout); |
412 | |
413 hb_blob_unlock (face->head_blob); | |
414 hb_blob_destroy (face->head_blob); | |
415 | 663 |
416 if (face->destroy) | 664 if (face->destroy) |
417 face->destroy (face->user_data); | 665 face->destroy (face->user_data); |
418 | 666 |
419 free (face); | 667 free (face); |
420 } | 668 } |
421 | 669 |
| 670 hb_bool_t |
| 671 hb_face_set_user_data (hb_face_t *face, |
| 672 hb_user_data_key_t *key, |
| 673 void * data, |
| 674 hb_destroy_func_t destroy, |
| 675 hb_bool_t replace) |
| 676 { |
| 677 return hb_object_set_user_data (face, key, data, destroy, replace); |
| 678 } |
| 679 |
| 680 void * |
| 681 hb_face_get_user_data (hb_face_t *face, |
| 682 hb_user_data_key_t *key) |
| 683 { |
| 684 return hb_object_get_user_data (face, key); |
| 685 } |
| 686 |
| 687 void |
| 688 hb_face_make_immutable (hb_face_t *face) |
| 689 { |
| 690 if (hb_object_is_inert (face)) |
| 691 return; |
| 692 |
| 693 face->immutable = true; |
| 694 } |
| 695 |
| 696 hb_bool_t |
| 697 hb_face_is_immutable (hb_face_t *face) |
| 698 { |
| 699 return face->immutable; |
| 700 } |
| 701 |
| 702 |
422 hb_blob_t * | 703 hb_blob_t * |
423 hb_face_get_table (hb_face_t *face, | 704 hb_face_reference_table (hb_face_t *face, |
424 » » hb_tag_t tag) | 705 » » » hb_tag_t tag) |
425 { | 706 { |
426 hb_blob_t *blob; | 707 hb_blob_t *blob; |
427 | 708 |
428 if (unlikely (!face || !face->get_table)) | 709 if (unlikely (!face || !face->reference_table)) |
429 return &_hb_blob_nil; | 710 return hb_blob_get_empty (); |
430 | 711 |
431 blob = face->get_table (tag, face->user_data); | 712 blob = face->reference_table (face, tag, face->user_data); |
| 713 if (unlikely (!blob)) |
| 714 return hb_blob_get_empty (); |
432 | 715 |
433 return blob; | 716 return blob; |
434 } | 717 } |
435 | 718 |
| 719 hb_blob_t * |
| 720 hb_face_reference_blob (hb_face_t *face) |
| 721 { |
| 722 return hb_face_reference_table (face, HB_TAG_NONE); |
| 723 } |
| 724 |
| 725 void |
| 726 hb_face_set_index (hb_face_t *face, |
| 727 unsigned int index) |
| 728 { |
| 729 if (hb_object_is_inert (face)) |
| 730 return; |
| 731 |
| 732 face->index = 0; |
| 733 } |
| 734 |
| 735 unsigned int |
| 736 hb_face_get_index (hb_face_t *face) |
| 737 { |
| 738 return face->index; |
| 739 } |
| 740 |
| 741 void |
| 742 hb_face_set_upem (hb_face_t *face, |
| 743 unsigned int upem) |
| 744 { |
| 745 if (hb_object_is_inert (face)) |
| 746 return; |
| 747 |
| 748 face->upem = upem; |
| 749 } |
| 750 |
436 unsigned int | 751 unsigned int |
437 hb_face_get_upem (hb_face_t *face) | 752 hb_face_get_upem (hb_face_t *face) |
438 { | 753 { |
439 return (face->head_table ? face->head_table : &Null(head))->get_upem (); | 754 if (unlikely (!face->upem)) { |
| 755 hb_blob_t *head_blob = Sanitizer<head>::sanitize (hb_face_reference_table (f
ace, HB_OT_TAG_head)); |
| 756 const head *head_table = Sanitizer<head>::lock_instance (head_blob); |
| 757 face->upem = head_table->get_upem (); |
| 758 hb_blob_destroy (head_blob); |
| 759 } |
| 760 return face->upem; |
440 } | 761 } |
441 | 762 |
442 | 763 |
443 /* | 764 /* |
444 * hb_font_t | 765 * hb_font_t |
445 */ | 766 */ |
446 | 767 |
447 static hb_font_t _hb_font_nil = { | 768 static hb_font_t _hb_font_nil = { |
448 HB_REFERENCE_COUNT_INVALID, /* ref_count */ | 769 HB_OBJECT_HEADER_STATIC, |
| 770 |
| 771 TRUE, /* immutable */ |
| 772 |
| 773 NULL, /* parent */ |
| 774 &_hb_face_nil, |
449 | 775 |
450 0, /* x_scale */ | 776 0, /* x_scale */ |
451 0, /* y_scale */ | 777 0, /* y_scale */ |
452 | 778 |
453 0, /* x_ppem */ | 779 0, /* x_ppem */ |
454 0, /* y_ppem */ | 780 0, /* y_ppem */ |
455 | 781 |
456 NULL, /* klass */ | 782 &_hb_font_funcs_nil, /* klass */ |
457 NULL, /* destroy */ | 783 NULL, /* user_data */ |
458 NULL /* user_data */ | 784 NULL /* destroy */ |
459 }; | 785 }; |
460 | 786 |
461 hb_font_t * | 787 hb_font_t * |
462 hb_font_create (void) | 788 hb_font_create (hb_face_t *face) |
463 { | 789 { |
464 hb_font_t *font; | 790 hb_font_t *font; |
465 | 791 |
466 if (!HB_OBJECT_DO_CREATE (hb_font_t, font)) | 792 if (unlikely (!face)) |
| 793 face = &_hb_face_nil; |
| 794 if (unlikely (hb_object_is_inert (face))) |
467 return &_hb_font_nil; | 795 return &_hb_font_nil; |
| 796 if (!(font = hb_object_create<hb_font_t> ())) |
| 797 return &_hb_font_nil; |
| 798 |
| 799 hb_face_make_immutable (face); |
| 800 font->face = hb_face_reference (face); |
| 801 font->klass = &_hb_font_funcs_nil; |
| 802 |
| 803 return font; |
| 804 } |
| 805 |
| 806 hb_font_t * |
| 807 hb_font_create_sub_font (hb_font_t *parent) |
| 808 { |
| 809 if (unlikely (!parent)) |
| 810 return &_hb_font_nil; |
| 811 |
| 812 hb_font_t *font = hb_font_create (parent->face); |
| 813 |
| 814 if (unlikely (hb_object_is_inert (font))) |
| 815 return font; |
| 816 |
| 817 hb_font_make_immutable (parent); |
| 818 font->parent = hb_font_reference (parent); |
| 819 |
| 820 font->x_scale = parent->x_scale; |
| 821 font->y_scale = parent->y_scale; |
| 822 font->x_ppem = parent->x_ppem; |
| 823 font->y_ppem = parent->y_ppem; |
468 | 824 |
469 font->klass = &_hb_font_funcs_nil; | 825 font->klass = &_hb_font_funcs_nil; |
470 | 826 |
471 return font; | 827 return font; |
472 } | 828 } |
473 | 829 |
474 hb_font_t * | 830 hb_font_t * |
| 831 hb_font_get_empty (void) |
| 832 { |
| 833 return &_hb_font_nil; |
| 834 } |
| 835 |
| 836 hb_font_t * |
475 hb_font_reference (hb_font_t *font) | 837 hb_font_reference (hb_font_t *font) |
476 { | 838 { |
477 HB_OBJECT_DO_REFERENCE (font); | 839 return hb_object_reference (font); |
478 } | |
479 | |
480 unsigned int | |
481 hb_font_get_reference_count (hb_font_t *font) | |
482 { | |
483 HB_OBJECT_DO_GET_REFERENCE_COUNT (font); | |
484 } | 840 } |
485 | 841 |
486 void | 842 void |
487 hb_font_destroy (hb_font_t *font) | 843 hb_font_destroy (hb_font_t *font) |
488 { | 844 { |
489 HB_OBJECT_DO_DESTROY (font); | 845 if (!hb_object_destroy (font)) return; |
490 | 846 |
| 847 hb_font_destroy (font->parent); |
| 848 hb_face_destroy (font->face); |
491 hb_font_funcs_destroy (font->klass); | 849 hb_font_funcs_destroy (font->klass); |
492 if (font->destroy) | 850 if (font->destroy) |
493 font->destroy (font->user_data); | 851 font->destroy (font->user_data); |
494 | 852 |
495 free (font); | 853 free (font); |
496 } | 854 } |
497 | 855 |
| 856 hb_bool_t |
| 857 hb_font_set_user_data (hb_font_t *font, |
| 858 hb_user_data_key_t *key, |
| 859 void * data, |
| 860 hb_destroy_func_t destroy, |
| 861 hb_bool_t replace) |
| 862 { |
| 863 return hb_object_set_user_data (font, key, data, destroy, replace); |
| 864 } |
| 865 |
| 866 void * |
| 867 hb_font_get_user_data (hb_font_t *font, |
| 868 hb_user_data_key_t *key) |
| 869 { |
| 870 return hb_object_get_user_data (font, key); |
| 871 } |
| 872 |
| 873 void |
| 874 hb_font_make_immutable (hb_font_t *font) |
| 875 { |
| 876 if (hb_object_is_inert (font)) |
| 877 return; |
| 878 |
| 879 font->immutable = true; |
| 880 } |
| 881 |
| 882 hb_bool_t |
| 883 hb_font_is_immutable (hb_font_t *font) |
| 884 { |
| 885 return font->immutable; |
| 886 } |
| 887 |
| 888 hb_font_t * |
| 889 hb_font_get_parent (hb_font_t *font) |
| 890 { |
| 891 return font->parent; |
| 892 } |
| 893 |
| 894 hb_face_t * |
| 895 hb_font_get_face (hb_font_t *font) |
| 896 { |
| 897 return font->face; |
| 898 } |
| 899 |
| 900 |
498 void | 901 void |
499 hb_font_set_funcs (hb_font_t *font, | 902 hb_font_set_funcs (hb_font_t *font, |
500 hb_font_funcs_t *klass, | 903 hb_font_funcs_t *klass, |
501 » » hb_destroy_func_t destroy, | 904 » » void *user_data, |
502 » » void *user_data) | 905 » » hb_destroy_func_t destroy) |
503 { | 906 { |
504 if (HB_OBJECT_IS_INERT (font)) | 907 if (font->immutable) { |
| 908 if (destroy) |
| 909 destroy (user_data); |
505 return; | 910 return; |
| 911 } |
506 | 912 |
507 if (font->destroy) | 913 if (font->destroy) |
508 font->destroy (font->user_data); | 914 font->destroy (font->user_data); |
509 | 915 |
510 if (!klass) | 916 if (!klass) |
511 klass = &_hb_font_funcs_nil; | 917 klass = &_hb_font_funcs_nil; |
512 | 918 |
513 hb_font_funcs_reference (klass); | 919 hb_font_funcs_reference (klass); |
514 hb_font_funcs_destroy (font->klass); | 920 hb_font_funcs_destroy (font->klass); |
515 font->klass = klass; | 921 font->klass = klass; |
| 922 font->user_data = user_data; |
516 font->destroy = destroy; | 923 font->destroy = destroy; |
517 font->user_data = user_data; | |
518 } | 924 } |
519 | 925 |
520 void | 926 void |
521 hb_font_unset_funcs (hb_font_t *font, | 927 hb_font_set_funcs_data (hb_font_t *font, |
522 » » hb_font_funcs_t **klass, | 928 » » void *user_data, |
523 » » hb_destroy_func_t *destroy, | 929 » » hb_destroy_func_t destroy) |
524 » » void **user_data) | |
525 { | 930 { |
526 /* None of the input arguments can be NULL. */ | 931 /* Destroy user_data? */ |
| 932 if (font->immutable) { |
| 933 if (destroy) |
| 934 destroy (user_data); |
| 935 return; |
| 936 } |
527 | 937 |
528 *klass = font->klass; | 938 if (font->destroy) |
529 *destroy = font->destroy; | 939 font->destroy (font->user_data); |
530 *user_data = font->user_data; | |
531 | 940 |
532 if (HB_OBJECT_IS_INERT (font)) | 941 font->user_data = user_data; |
533 return; | 942 font->destroy = destroy; |
| 943 } |
534 | 944 |
535 font->klass = NULL; | |
536 font->destroy = NULL; | |
537 font->user_data = NULL; | |
538 } | |
539 | 945 |
540 void | 946 void |
541 hb_font_set_scale (hb_font_t *font, | 947 hb_font_set_scale (hb_font_t *font, |
542 » » unsigned int x_scale, | 948 » » int x_scale, |
543 » » unsigned int y_scale) | 949 » » int y_scale) |
544 { | 950 { |
545 if (HB_OBJECT_IS_INERT (font)) | 951 if (font->immutable) |
546 return; | 952 return; |
547 | 953 |
548 font->x_scale = x_scale; | 954 font->x_scale = x_scale; |
549 font->y_scale = y_scale; | 955 font->y_scale = y_scale; |
550 } | 956 } |
551 | 957 |
552 void | 958 void |
553 hb_font_get_scale (hb_font_t *font, | 959 hb_font_get_scale (hb_font_t *font, |
554 » » unsigned int *x_scale, | 960 » » int *x_scale, |
555 » » unsigned int *y_scale) | 961 » » int *y_scale) |
556 { | 962 { |
557 if (x_scale) *x_scale = font->x_scale; | 963 if (x_scale) *x_scale = font->x_scale; |
558 if (y_scale) *y_scale = font->y_scale; | 964 if (y_scale) *y_scale = font->y_scale; |
559 } | 965 } |
560 | 966 |
561 void | 967 void |
562 hb_font_set_ppem (hb_font_t *font, | 968 hb_font_set_ppem (hb_font_t *font, |
563 unsigned int x_ppem, | 969 unsigned int x_ppem, |
564 unsigned int y_ppem) | 970 unsigned int y_ppem) |
565 { | 971 { |
566 if (HB_OBJECT_IS_INERT (font)) | 972 if (font->immutable) |
567 return; | 973 return; |
568 | 974 |
569 font->x_ppem = x_ppem; | 975 font->x_ppem = x_ppem; |
570 font->y_ppem = y_ppem; | 976 font->y_ppem = y_ppem; |
571 } | 977 } |
572 | 978 |
573 void | 979 void |
574 hb_font_get_ppem (hb_font_t *font, | 980 hb_font_get_ppem (hb_font_t *font, |
575 unsigned int *x_ppem, | 981 unsigned int *x_ppem, |
576 unsigned int *y_ppem) | 982 unsigned int *y_ppem) |
577 { | 983 { |
578 if (x_ppem) *x_ppem = font->x_ppem; | 984 if (x_ppem) *x_ppem = font->x_ppem; |
579 if (y_ppem) *y_ppem = font->y_ppem; | 985 if (y_ppem) *y_ppem = font->y_ppem; |
580 } | 986 } |
581 | 987 |
582 | 988 |
583 HB_END_DECLS | |
OLD | NEW |