OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2009 Red Hat, Inc. | 2 * Copyright © 2009 Red Hat, Inc. |
| 3 * Copyright © 2012 Google, Inc. |
3 * | 4 * |
4 * This is part of HarfBuzz, a text shaping library. | 5 * This is part of HarfBuzz, a text shaping library. |
5 * | 6 * |
6 * Permission is hereby granted, without written agreement and without | 7 * Permission is hereby granted, without written agreement and without |
7 * license or royalty fees, to use, copy, modify, and distribute this | 8 * license or royalty fees, to use, copy, modify, and distribute this |
8 * software and its documentation for any purpose, provided that the | 9 * software and its documentation for any purpose, provided that the |
9 * above copyright notice and the following two paragraphs appear in | 10 * above copyright notice and the following two paragraphs appear in |
10 * all copies of this software. | 11 * all copies of this software. |
11 * | 12 * |
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR | 13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES | 14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN | 15 * 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 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
16 * DAMAGE. | 17 * DAMAGE. |
17 * | 18 * |
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, | 19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | 20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS | 21 * 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 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | 23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
23 * | 24 * |
24 * Red Hat Author(s): Behdad Esfahbod | 25 * Red Hat Author(s): Behdad Esfahbod |
| 26 * Google Author(s): Behdad Esfahbod |
25 */ | 27 */ |
26 | 28 |
27 #include "hb-private.hh" | 29 #include "hb-private.hh" |
28 | 30 |
29 #include "hb-ot-layout-private.hh" | 31 #include "hb-ot-layout-private.hh" |
30 | 32 |
31 #include "hb-font-private.hh" | 33 #include "hb-font-private.hh" |
32 #include "hb-blob.h" | 34 #include "hb-blob.h" |
33 #include "hb-open-file-private.hh" | 35 #include "hb-open-file-private.hh" |
34 #include "hb-ot-head-table.hh" | 36 #include "hb-ot-head-table.hh" |
(...skipping 10 matching lines...) Expand all Loading... |
45 | 47 |
46 static hb_bool_t | 48 static hb_bool_t |
47 hb_font_get_glyph_nil (hb_font_t *font, | 49 hb_font_get_glyph_nil (hb_font_t *font, |
48 void *font_data HB_UNUSED, | 50 void *font_data HB_UNUSED, |
49 hb_codepoint_t unicode, | 51 hb_codepoint_t unicode, |
50 hb_codepoint_t variation_selector, | 52 hb_codepoint_t variation_selector, |
51 hb_codepoint_t *glyph, | 53 hb_codepoint_t *glyph, |
52 void *user_data HB_UNUSED) | 54 void *user_data HB_UNUSED) |
53 { | 55 { |
54 if (font->parent) | 56 if (font->parent) |
55 return hb_font_get_glyph (font->parent, unicode, variation_selector, glyph); | 57 return font->parent->get_glyph (unicode, variation_selector, glyph); |
56 | 58 |
57 *glyph = 0; | 59 *glyph = 0; |
58 return false; | 60 return false; |
59 } | 61 } |
60 | 62 |
61 static hb_position_t | 63 static hb_position_t |
62 hb_font_get_glyph_h_advance_nil (hb_font_t *font, | 64 hb_font_get_glyph_h_advance_nil (hb_font_t *font, |
63 void *font_data HB_UNUSED, | 65 void *font_data HB_UNUSED, |
64 hb_codepoint_t glyph, | 66 hb_codepoint_t glyph, |
65 void *user_data HB_UNUSED) | 67 void *user_data HB_UNUSED) |
66 { | 68 { |
67 if (font->parent) | 69 if (font->parent) |
68 return font->parent_scale_x_distance (hb_font_get_glyph_h_advance (font->par
ent, glyph)); | 70 return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (gly
ph)); |
69 | 71 |
70 return font->x_scale; | 72 return font->x_scale; |
71 } | 73 } |
72 | 74 |
73 static hb_position_t | 75 static hb_position_t |
74 hb_font_get_glyph_v_advance_nil (hb_font_t *font, | 76 hb_font_get_glyph_v_advance_nil (hb_font_t *font, |
75 void *font_data HB_UNUSED, | 77 void *font_data HB_UNUSED, |
76 hb_codepoint_t glyph, | 78 hb_codepoint_t glyph, |
77 void *user_data HB_UNUSED) | 79 void *user_data HB_UNUSED) |
78 { | 80 { |
79 if (font->parent) | 81 if (font->parent) |
80 return font->parent_scale_y_distance (hb_font_get_glyph_v_advance (font->par
ent, glyph)); | 82 return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (gly
ph)); |
81 | 83 |
82 return font->y_scale; | 84 return font->y_scale; |
83 } | 85 } |
84 | 86 |
85 static hb_bool_t | 87 static hb_bool_t |
86 hb_font_get_glyph_h_origin_nil (hb_font_t *font, | 88 hb_font_get_glyph_h_origin_nil (hb_font_t *font, |
87 void *font_data HB_UNUSED, | 89 void *font_data HB_UNUSED, |
88 hb_codepoint_t glyph, | 90 hb_codepoint_t glyph, |
89 hb_position_t *x, | 91 hb_position_t *x, |
90 hb_position_t *y, | 92 hb_position_t *y, |
91 void *user_data HB_UNUSED) | 93 void *user_data HB_UNUSED) |
92 { | 94 { |
93 if (font->parent) { | 95 if (font->parent) { |
94 hb_bool_t ret = hb_font_get_glyph_h_origin (font->parent, glyph, x, y); | 96 hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y); |
95 if (ret) | 97 if (ret) |
96 font->parent_scale_position (x, y); | 98 font->parent_scale_position (x, y); |
97 return ret; | 99 return ret; |
98 } | 100 } |
99 | 101 |
100 *x = *y = 0; | 102 *x = *y = 0; |
101 return false; | 103 return false; |
102 } | 104 } |
103 | 105 |
104 static hb_bool_t | 106 static hb_bool_t |
105 hb_font_get_glyph_v_origin_nil (hb_font_t *font, | 107 hb_font_get_glyph_v_origin_nil (hb_font_t *font, |
106 void *font_data HB_UNUSED, | 108 void *font_data HB_UNUSED, |
107 hb_codepoint_t glyph, | 109 hb_codepoint_t glyph, |
108 hb_position_t *x, | 110 hb_position_t *x, |
109 hb_position_t *y, | 111 hb_position_t *y, |
110 void *user_data HB_UNUSED) | 112 void *user_data HB_UNUSED) |
111 { | 113 { |
112 if (font->parent) { | 114 if (font->parent) { |
113 hb_bool_t ret = hb_font_get_glyph_v_origin (font->parent, glyph, x, y); | 115 hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y); |
114 if (ret) | 116 if (ret) |
115 font->parent_scale_position (x, y); | 117 font->parent_scale_position (x, y); |
116 return ret; | 118 return ret; |
117 } | 119 } |
118 | 120 |
119 *x = *y = 0; | 121 *x = *y = 0; |
120 return false; | 122 return false; |
121 } | 123 } |
122 | 124 |
123 static hb_position_t | 125 static hb_position_t |
124 hb_font_get_glyph_h_kerning_nil (hb_font_t *font, | 126 hb_font_get_glyph_h_kerning_nil (hb_font_t *font, |
125 void *font_data HB_UNUSED, | 127 void *font_data HB_UNUSED, |
126 hb_codepoint_t left_glyph, | 128 hb_codepoint_t left_glyph, |
127 hb_codepoint_t right_glyph, | 129 hb_codepoint_t right_glyph, |
128 void *user_data HB_UNUSED) | 130 void *user_data HB_UNUSED) |
129 { | 131 { |
130 if (font->parent) | 132 if (font->parent) |
131 return font->parent_scale_x_distance (hb_font_get_glyph_h_kerning (font->par
ent, left_glyph, right_glyph)); | 133 return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (lef
t_glyph, right_glyph)); |
132 | 134 |
133 return 0; | 135 return 0; |
134 } | 136 } |
135 | 137 |
136 static hb_position_t | 138 static hb_position_t |
137 hb_font_get_glyph_v_kerning_nil (hb_font_t *font, | 139 hb_font_get_glyph_v_kerning_nil (hb_font_t *font, |
138 void *font_data HB_UNUSED, | 140 void *font_data HB_UNUSED, |
139 hb_codepoint_t top_glyph, | 141 hb_codepoint_t top_glyph, |
140 hb_codepoint_t bottom_glyph, | 142 hb_codepoint_t bottom_glyph, |
141 void *user_data HB_UNUSED) | 143 void *user_data HB_UNUSED) |
142 { | 144 { |
143 if (font->parent) | 145 if (font->parent) |
144 return font->parent_scale_y_distance (hb_font_get_glyph_v_kerning (font->par
ent, top_glyph, bottom_glyph)); | 146 return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top
_glyph, bottom_glyph)); |
145 | 147 |
146 return 0; | 148 return 0; |
147 } | 149 } |
148 | 150 |
149 static hb_bool_t | 151 static hb_bool_t |
150 hb_font_get_glyph_extents_nil (hb_font_t *font, | 152 hb_font_get_glyph_extents_nil (hb_font_t *font, |
151 void *font_data HB_UNUSED, | 153 void *font_data HB_UNUSED, |
152 hb_codepoint_t glyph, | 154 hb_codepoint_t glyph, |
153 hb_glyph_extents_t *extents, | 155 hb_glyph_extents_t *extents, |
154 void *user_data HB_UNUSED) | 156 void *user_data HB_UNUSED) |
155 { | 157 { |
156 if (font->parent) { | 158 if (font->parent) { |
157 hb_bool_t ret = hb_font_get_glyph_extents (font->parent, | 159 hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents); |
158 » » » » » glyph, | |
159 » » » » » extents); | |
160 if (ret) { | 160 if (ret) { |
161 font->parent_scale_position (&extents->x_bearing, &extents->y_bearing); | 161 font->parent_scale_position (&extents->x_bearing, &extents->y_bearing); |
162 font->parent_scale_distance (&extents->width, &extents->height); | 162 font->parent_scale_distance (&extents->width, &extents->height); |
163 } | 163 } |
164 return ret; | 164 return ret; |
165 } | 165 } |
166 | 166 |
167 memset (extents, 0, sizeof (*extents)); | 167 memset (extents, 0, sizeof (*extents)); |
168 return false; | 168 return false; |
169 } | 169 } |
170 | 170 |
171 static hb_bool_t | 171 static hb_bool_t |
172 hb_font_get_glyph_contour_point_nil (hb_font_t *font, | 172 hb_font_get_glyph_contour_point_nil (hb_font_t *font, |
173 void *font_data HB_UNUSED, | 173 void *font_data HB_UNUSED, |
174 hb_codepoint_t glyph, | 174 hb_codepoint_t glyph, |
175 unsigned int point_index, | 175 unsigned int point_index, |
176 hb_position_t *x, | 176 hb_position_t *x, |
177 hb_position_t *y, | 177 hb_position_t *y, |
178 void *user_data HB_UNUSED) | 178 void *user_data HB_UNUSED) |
179 { | 179 { |
180 if (font->parent) { | 180 if (font->parent) { |
181 hb_bool_t ret = hb_font_get_glyph_contour_point (font->parent, glyph, point_
index, x, y); | 181 hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x
, y); |
182 if (ret) | 182 if (ret) |
183 font->parent_scale_position (x, y); | 183 font->parent_scale_position (x, y); |
184 return ret; | 184 return ret; |
185 } | 185 } |
186 | 186 |
187 *x = *y = 0; | 187 *x = *y = 0; |
188 return false; | 188 return false; |
189 } | 189 } |
190 | 190 |
191 static hb_bool_t | 191 static hb_bool_t |
192 hb_font_get_glyph_name_nil (hb_font_t *font, | 192 hb_font_get_glyph_name_nil (hb_font_t *font, |
193 void *font_data HB_UNUSED, | 193 void *font_data HB_UNUSED, |
194 hb_codepoint_t glyph, | 194 hb_codepoint_t glyph, |
195 char *name, unsigned int size, | 195 char *name, unsigned int size, |
196 void *user_data HB_UNUSED) | 196 void *user_data HB_UNUSED) |
197 { | 197 { |
198 if (font->parent) | 198 if (font->parent) |
199 return hb_font_get_glyph_name (font->parent, glyph, name, size); | 199 return font->parent->get_glyph_name (glyph, name, size); |
200 | 200 |
201 snprintf (name, size, "gid%u", glyph); | 201 if (size) *name = '\0'; |
202 return false; | 202 return false; |
203 } | 203 } |
204 | 204 |
205 static hb_bool_t | 205 static hb_bool_t |
206 hb_font_get_glyph_from_name_nil (hb_font_t *font, | 206 hb_font_get_glyph_from_name_nil (hb_font_t *font, |
207 void *font_data HB_UNUSED, | 207 void *font_data HB_UNUSED, |
208 const char *name, int len, /* -1 means nul-term
inated */ | 208 const char *name, int len, /* -1 means nul-term
inated */ |
209 hb_codepoint_t *glyph, | 209 hb_codepoint_t *glyph, |
210 void *user_data HB_UNUSED) | 210 void *user_data HB_UNUSED) |
211 { | 211 { |
212 if (font->parent) | 212 if (font->parent) |
213 return hb_font_get_glyph_from_name (font->parent, name, len, glyph); | 213 return font->parent->get_glyph_from_name (name, len, glyph); |
214 | 214 |
215 *glyph = 0; | 215 *glyph = 0; |
216 return false; | 216 return false; |
217 } | 217 } |
218 | 218 |
219 | 219 |
220 static const hb_font_funcs_t _hb_font_funcs_nil = { | 220 static const hb_font_funcs_t _hb_font_funcs_nil = { |
221 HB_OBJECT_HEADER_STATIC, | 221 HB_OBJECT_HEADER_STATIC, |
222 | 222 |
223 true, /* immutable */ | 223 true, /* immutable */ |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 ffuncs->get.name = hb_font_get_##name##_nil; \ | 327 ffuncs->get.name = hb_font_get_##name##_nil; \ |
328 ffuncs->user_data.name = NULL; \ | 328 ffuncs->user_data.name = NULL; \ |
329 ffuncs->destroy.name = NULL; \ | 329 ffuncs->destroy.name = NULL; \ |
330 } \ | 330 } \ |
331 } | 331 } |
332 | 332 |
333 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS | 333 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS |
334 #undef HB_FONT_FUNC_IMPLEMENT | 334 #undef HB_FONT_FUNC_IMPLEMENT |
335 | 335 |
336 | 336 |
| 337 /* Public getters */ |
| 338 |
337 hb_bool_t | 339 hb_bool_t |
338 hb_font_get_glyph (hb_font_t *font, | 340 hb_font_get_glyph (hb_font_t *font, |
339 hb_codepoint_t unicode, hb_codepoint_t variation_selector, | 341 hb_codepoint_t unicode, hb_codepoint_t variation_selector, |
340 hb_codepoint_t *glyph) | 342 hb_codepoint_t *glyph) |
341 { | 343 { |
342 *glyph = 0; | 344 return font->get_glyph (unicode, variation_selector, glyph); |
343 return font->klass->get.glyph (font, font->user_data, | |
344 » » » » unicode, variation_selector, glyph, | |
345 » » » » font->klass->user_data.glyph); | |
346 } | 345 } |
347 | 346 |
348 hb_position_t | 347 hb_position_t |
349 hb_font_get_glyph_h_advance (hb_font_t *font, | 348 hb_font_get_glyph_h_advance (hb_font_t *font, |
350 hb_codepoint_t glyph) | 349 hb_codepoint_t glyph) |
351 { | 350 { |
352 return font->klass->get.glyph_h_advance (font, font->user_data, | 351 return font->get_glyph_h_advance (glyph); |
353 » » » » » glyph, | |
354 » » » » » font->klass->user_data.glyph_h_advanc
e); | |
355 } | 352 } |
356 | 353 |
357 hb_position_t | 354 hb_position_t |
358 hb_font_get_glyph_v_advance (hb_font_t *font, | 355 hb_font_get_glyph_v_advance (hb_font_t *font, |
359 hb_codepoint_t glyph) | 356 hb_codepoint_t glyph) |
360 { | 357 { |
361 return font->klass->get.glyph_v_advance (font, font->user_data, | 358 return font->get_glyph_v_advance (glyph); |
362 » » » » » glyph, | |
363 » » » » » font->klass->user_data.glyph_v_advanc
e); | |
364 } | 359 } |
365 | 360 |
366 hb_bool_t | 361 hb_bool_t |
367 hb_font_get_glyph_h_origin (hb_font_t *font, | 362 hb_font_get_glyph_h_origin (hb_font_t *font, |
368 hb_codepoint_t glyph, | 363 hb_codepoint_t glyph, |
369 hb_position_t *x, hb_position_t *y) | 364 hb_position_t *x, hb_position_t *y) |
370 { | 365 { |
371 *x = *y = 0; | 366 return font->get_glyph_h_origin (glyph, x, y); |
372 return font->klass->get.glyph_h_origin (font, font->user_data, | |
373 » » » » » glyph, x, y, | |
374 » » » » » font->klass->user_data.glyph_h_origin
); | |
375 } | 367 } |
376 | 368 |
377 hb_bool_t | 369 hb_bool_t |
378 hb_font_get_glyph_v_origin (hb_font_t *font, | 370 hb_font_get_glyph_v_origin (hb_font_t *font, |
379 hb_codepoint_t glyph, | 371 hb_codepoint_t glyph, |
380 hb_position_t *x, hb_position_t *y) | 372 hb_position_t *x, hb_position_t *y) |
381 { | 373 { |
382 *x = *y = 0; | 374 return font->get_glyph_v_origin (glyph, x, y); |
383 return font->klass->get.glyph_v_origin (font, font->user_data, | |
384 » » » » » glyph, x, y, | |
385 » » » » » font->klass->user_data.glyph_v_origin
); | |
386 } | 375 } |
387 | 376 |
388 hb_position_t | 377 hb_position_t |
389 hb_font_get_glyph_h_kerning (hb_font_t *font, | 378 hb_font_get_glyph_h_kerning (hb_font_t *font, |
390 hb_codepoint_t left_glyph, hb_codepoint_t right_gly
ph) | 379 hb_codepoint_t left_glyph, hb_codepoint_t right_gly
ph) |
391 { | 380 { |
392 return font->klass->get.glyph_h_kerning (font, font->user_data, | 381 return font->get_glyph_h_kerning (left_glyph, right_glyph); |
393 » » » » » left_glyph, right_glyph, | |
394 » » » » » font->klass->user_data.glyph_h_kernin
g); | |
395 } | 382 } |
396 | 383 |
397 hb_position_t | 384 hb_position_t |
398 hb_font_get_glyph_v_kerning (hb_font_t *font, | 385 hb_font_get_glyph_v_kerning (hb_font_t *font, |
399 hb_codepoint_t left_glyph, hb_codepoint_t right_gly
ph) | 386 hb_codepoint_t left_glyph, hb_codepoint_t right_gly
ph) |
400 { | 387 { |
401 return font->klass->get.glyph_v_kerning (font, font->user_data, | 388 return font->get_glyph_v_kerning (left_glyph, right_glyph); |
402 » » » » left_glyph, right_glyph, | |
403 » » » » font->klass->user_data.glyph_v_kerning); | |
404 } | 389 } |
405 | 390 |
406 hb_bool_t | 391 hb_bool_t |
407 hb_font_get_glyph_extents (hb_font_t *font, | 392 hb_font_get_glyph_extents (hb_font_t *font, |
408 hb_codepoint_t glyph, | 393 hb_codepoint_t glyph, |
409 hb_glyph_extents_t *extents) | 394 hb_glyph_extents_t *extents) |
410 { | 395 { |
411 memset (extents, 0, sizeof (*extents)); | 396 return font->get_glyph_extents (glyph, extents); |
412 return font->klass->get.glyph_extents (font, font->user_data, | |
413 » » » » » glyph, | |
414 » » » » » extents, | |
415 » » » » » font->klass->user_data.glyph_extents); | |
416 } | 397 } |
417 | 398 |
418 hb_bool_t | 399 hb_bool_t |
419 hb_font_get_glyph_contour_point (hb_font_t *font, | 400 hb_font_get_glyph_contour_point (hb_font_t *font, |
420 hb_codepoint_t glyph, unsigned int point_index, | 401 hb_codepoint_t glyph, unsigned int point_index, |
421 hb_position_t *x, hb_position_t *y) | 402 hb_position_t *x, hb_position_t *y) |
422 { | 403 { |
423 *x = *y = 0; | 404 return font->get_glyph_contour_point (glyph, point_index, x, y); |
424 return font->klass->get.glyph_contour_point (font, font->user_data, | |
425 » » » » » glyph, point_index, | |
426 » » » » » x, y, | |
427 » » » » » font->klass->user_data.glyph_cont
our_point); | |
428 } | 405 } |
429 | 406 |
430 hb_bool_t | 407 hb_bool_t |
431 hb_font_get_glyph_name (hb_font_t *font, | 408 hb_font_get_glyph_name (hb_font_t *font, |
432 hb_codepoint_t glyph, | 409 hb_codepoint_t glyph, |
433 char *name, unsigned int size) | 410 char *name, unsigned int size) |
434 { | 411 { |
435 return font->klass->get.glyph_name (font, font->user_data, | 412 return font->get_glyph_name (glyph, name, size); |
436 » » » » glyph, | |
437 » » » » name, size, | |
438 » » » » font->klass->user_data.glyph_name); | |
439 } | 413 } |
440 | 414 |
441 hb_bool_t | 415 hb_bool_t |
442 hb_font_get_glyph_from_name (hb_font_t *font, | 416 hb_font_get_glyph_from_name (hb_font_t *font, |
443 const char *name, int len, /* -1 means nul-terminat
ed */ | 417 const char *name, int len, /* -1 means nul-terminat
ed */ |
444 hb_codepoint_t *glyph) | 418 hb_codepoint_t *glyph) |
445 { | 419 { |
446 return font->klass->get.glyph_from_name (font, font->user_data, | 420 return font->get_glyph_from_name (name, len, glyph); |
447 » » » » » name, len, | |
448 » » » » » glyph, | |
449 » » » » » font->klass->user_data.glyph_from_nam
e); | |
450 } | 421 } |
451 | 422 |
452 | 423 |
453 /* A bit higher-level, and with fallback */ | 424 /* A bit higher-level, and with fallback */ |
454 | 425 |
455 void | 426 void |
456 hb_font_get_glyph_advance_for_direction (hb_font_t *font, | 427 hb_font_get_glyph_advance_for_direction (hb_font_t *font, |
457 hb_codepoint_t glyph, | 428 hb_codepoint_t glyph, |
458 hb_direction_t direction, | 429 hb_direction_t direction, |
459 hb_position_t *x, hb_position_t *y) | 430 hb_position_t *x, hb_position_t *y) |
460 { | 431 { |
461 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { | 432 return font->get_glyph_advance_for_direction (glyph, direction, x, y); |
462 *x = hb_font_get_glyph_h_advance (font, glyph); | |
463 *y = 0; | |
464 } else { | |
465 *x = 0; | |
466 *y = hb_font_get_glyph_v_advance (font, glyph); | |
467 } | |
468 } | 433 } |
469 | 434 |
470 static void | |
471 guess_v_origin_minus_h_origin (hb_font_t *font, | |
472 hb_codepoint_t glyph, | |
473 hb_position_t *x, hb_position_t *y) | |
474 { | |
475 *x = hb_font_get_glyph_h_advance (font, glyph) / 2; | |
476 | |
477 /* TODO use font_metics.ascent */ | |
478 *y = font->y_scale; | |
479 } | |
480 | |
481 | |
482 void | 435 void |
483 hb_font_get_glyph_origin_for_direction (hb_font_t *font, | 436 hb_font_get_glyph_origin_for_direction (hb_font_t *font, |
484 hb_codepoint_t glyph, | 437 hb_codepoint_t glyph, |
485 hb_direction_t direction, | 438 hb_direction_t direction, |
486 hb_position_t *x, hb_position_t *y) | 439 hb_position_t *x, hb_position_t *y) |
487 { | 440 { |
488 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { | 441 return font->get_glyph_origin_for_direction (glyph, direction, x, y); |
489 hb_bool_t ret = hb_font_get_glyph_h_origin (font, glyph, x, y); | |
490 if (!ret && (ret = hb_font_get_glyph_v_origin (font, glyph, x, y))) { | |
491 hb_position_t dx, dy; | |
492 guess_v_origin_minus_h_origin (font, glyph, &dx, &dy); | |
493 *x -= dx; *y -= dy; | |
494 } | |
495 } else { | |
496 hb_bool_t ret = hb_font_get_glyph_v_origin (font, glyph, x, y); | |
497 if (!ret && (ret = hb_font_get_glyph_h_origin (font, glyph, x, y))) { | |
498 hb_position_t dx, dy; | |
499 guess_v_origin_minus_h_origin (font, glyph, &dx, &dy); | |
500 *x += dx; *y += dy; | |
501 } | |
502 } | |
503 } | 442 } |
504 | 443 |
505 void | 444 void |
506 hb_font_add_glyph_origin_for_direction (hb_font_t *font, | 445 hb_font_add_glyph_origin_for_direction (hb_font_t *font, |
507 hb_codepoint_t glyph, | 446 hb_codepoint_t glyph, |
508 hb_direction_t direction, | 447 hb_direction_t direction, |
509 hb_position_t *x, hb_position_t *y) | 448 hb_position_t *x, hb_position_t *y) |
510 { | 449 { |
511 hb_position_t origin_x, origin_y; | 450 return font->add_glyph_origin_for_direction (glyph, direction, x, y); |
512 | |
513 hb_font_get_glyph_origin_for_direction (font, glyph, direction, &origin_x, &or
igin_y); | |
514 | |
515 *x += origin_x; | |
516 *y += origin_y; | |
517 } | 451 } |
518 | 452 |
519 void | 453 void |
520 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, | 454 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, |
521 hb_codepoint_t glyph, | 455 hb_codepoint_t glyph, |
522 hb_direction_t direction, | 456 hb_direction_t direction, |
523 hb_position_t *x, hb_position_t *y) | 457 hb_position_t *x, hb_position_t *y) |
524 { | 458 { |
525 hb_position_t origin_x, origin_y; | 459 return font->subtract_glyph_origin_for_direction (glyph, direction, x, y); |
526 | |
527 hb_font_get_glyph_origin_for_direction (font, glyph, direction, &origin_x, &or
igin_y); | |
528 | |
529 *x -= origin_x; | |
530 *y -= origin_y; | |
531 } | 460 } |
532 | 461 |
533 void | 462 void |
534 hb_font_get_glyph_kerning_for_direction (hb_font_t *font, | 463 hb_font_get_glyph_kerning_for_direction (hb_font_t *font, |
535 hb_codepoint_t first_glyph, hb_codepoin
t_t second_glyph, | 464 hb_codepoint_t first_glyph, hb_codepoin
t_t second_glyph, |
536 hb_direction_t direction, | 465 hb_direction_t direction, |
537 hb_position_t *x, hb_position_t *y) | 466 hb_position_t *x, hb_position_t *y) |
538 { | 467 { |
539 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { | 468 return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direc
tion, x, y); |
540 *x = hb_font_get_glyph_h_kerning (font, first_glyph, second_glyph); | |
541 *y = 0; | |
542 } else { | |
543 *x = 0; | |
544 *y = hb_font_get_glyph_v_kerning (font, first_glyph, second_glyph); | |
545 } | |
546 } | 469 } |
547 | 470 |
548 hb_bool_t | 471 hb_bool_t |
549 hb_font_get_glyph_extents_for_origin (hb_font_t *font, | 472 hb_font_get_glyph_extents_for_origin (hb_font_t *font, |
550 hb_codepoint_t glyph, | 473 hb_codepoint_t glyph, |
551 hb_direction_t direction, | 474 hb_direction_t direction, |
552 hb_glyph_extents_t *extents) | 475 hb_glyph_extents_t *extents) |
553 { | 476 { |
554 hb_bool_t ret = hb_font_get_glyph_extents (font, glyph, extents); | 477 return font->get_glyph_extents_for_origin (glyph, direction, extents); |
555 | |
556 if (ret) | |
557 hb_font_subtract_glyph_origin_for_direction (font, glyph, direction, &extent
s->x_bearing, &extents->y_bearing); | |
558 | |
559 return ret; | |
560 } | 478 } |
561 | 479 |
562 hb_bool_t | 480 hb_bool_t |
563 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, | 481 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, |
564 hb_codepoint_t glyph, unsigned int p
oint_index, | 482 hb_codepoint_t glyph, unsigned int p
oint_index, |
565 hb_direction_t direction, | 483 hb_direction_t direction, |
566 hb_position_t *x, hb_position_t *y) | 484 hb_position_t *x, hb_position_t *y) |
567 { | 485 { |
568 hb_bool_t ret = hb_font_get_glyph_contour_point (font, glyph, point_index, x,
y); | 486 return font->get_glyph_contour_point_for_origin (glyph, point_index, direction
, x, y); |
| 487 } |
569 | 488 |
570 if (ret) | 489 /* Generates gidDDD if glyph has no name. */ |
571 hb_font_subtract_glyph_origin_for_direction (font, glyph, direction, x, y); | 490 void |
| 491 hb_font_glyph_to_string (hb_font_t *font, |
| 492 » » » hb_codepoint_t glyph, |
| 493 » » » char *s, unsigned int size) |
| 494 { |
| 495 font->glyph_to_string (glyph, s, size); |
| 496 } |
572 | 497 |
573 return ret; | 498 /* Parses gidDDD and uniUUUU strings automatically. */ |
| 499 hb_bool_t |
| 500 hb_font_glyph_from_string (hb_font_t *font, |
| 501 » » » const char *s, int len, /* -1 means nul-terminated */ |
| 502 » » » hb_codepoint_t *glyph) |
| 503 { |
| 504 return font->glyph_from_string (s, len, glyph); |
574 } | 505 } |
575 | 506 |
576 | 507 |
577 /* | 508 /* |
578 * hb_face_t | 509 * hb_face_t |
579 */ | 510 */ |
580 | 511 |
581 static const hb_face_t _hb_face_nil = { | 512 static const hb_face_t _hb_face_nil = { |
582 HB_OBJECT_HEADER_STATIC, | 513 HB_OBJECT_HEADER_STATIC, |
583 | 514 |
584 true, /* immutable */ | 515 true, /* immutable */ |
585 | 516 |
586 NULL, /* reference_table */ | 517 NULL, /* reference_table_func */ |
587 NULL, /* user_data */ | 518 NULL, /* user_data */ |
588 NULL, /* destroy */ | 519 NULL, /* destroy */ |
589 | 520 |
590 NULL, /* ot_layout */ | 521 0, /* index */ |
| 522 1000, /* upem */ |
591 | 523 |
592 0, /* index */ | 524 { |
593 1000 /* upem */ | 525 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, |
| 526 #include "hb-shaper-list.hh" |
| 527 #undef HB_SHAPER_IMPLEMENT |
| 528 }, |
| 529 |
| 530 NULL, /* shape_plans */ |
594 }; | 531 }; |
595 | 532 |
596 | 533 |
597 hb_face_t * | 534 hb_face_t * |
598 hb_face_create_for_tables (hb_reference_table_func_t reference_table, | 535 hb_face_create_for_tables (hb_reference_table_func_t reference_table_func, |
599 void *user_data, | 536 void *user_data, |
600 hb_destroy_func_t destroy) | 537 hb_destroy_func_t destroy) |
601 { | 538 { |
602 hb_face_t *face; | 539 hb_face_t *face; |
603 | 540 |
604 if (!reference_table || !(face = hb_object_create<hb_face_t> ())) { | 541 if (!reference_table_func || !(face = hb_object_create<hb_face_t> ())) { |
605 if (destroy) | 542 if (destroy) |
606 destroy (user_data); | 543 destroy (user_data); |
607 return hb_face_get_empty (); | 544 return hb_face_get_empty (); |
608 } | 545 } |
609 | 546 |
610 face->reference_table = reference_table; | 547 face->reference_table_func = reference_table_func; |
611 face->user_data = user_data; | 548 face->user_data = user_data; |
612 face->destroy = destroy; | 549 face->destroy = destroy; |
613 | 550 |
614 face->ot_layout = _hb_ot_layout_create (face); | |
615 | |
616 face->upem = 0; | 551 face->upem = 0; |
617 | 552 |
618 return face; | 553 return face; |
619 } | 554 } |
620 | 555 |
621 | 556 |
622 typedef struct _hb_face_for_data_closure_t { | 557 typedef struct hb_face_for_data_closure_t { |
623 hb_blob_t *blob; | 558 hb_blob_t *blob; |
624 unsigned int index; | 559 unsigned int index; |
625 } hb_face_for_data_closure_t; | 560 } hb_face_for_data_closure_t; |
626 | 561 |
627 static hb_face_for_data_closure_t * | 562 static hb_face_for_data_closure_t * |
628 _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index) | 563 _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index) |
629 { | 564 { |
630 hb_face_for_data_closure_t *closure; | 565 hb_face_for_data_closure_t *closure; |
631 | 566 |
632 closure = (hb_face_for_data_closure_t *) malloc (sizeof (hb_face_for_data_clos
ure_t)); | 567 closure = (hb_face_for_data_closure_t *) malloc (sizeof (hb_face_for_data_clos
ure_t)); |
(...skipping 14 matching lines...) Expand all Loading... |
647 } | 582 } |
648 | 583 |
649 static hb_blob_t * | 584 static hb_blob_t * |
650 _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
*user_data) | 585 _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
*user_data) |
651 { | 586 { |
652 hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; | 587 hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; |
653 | 588 |
654 if (tag == HB_TAG_NONE) | 589 if (tag == HB_TAG_NONE) |
655 return hb_blob_reference (data->blob); | 590 return hb_blob_reference (data->blob); |
656 | 591 |
657 const OpenTypeFontFile &ot_file = *Sanitizer<OpenTypeFontFile>::lock_instance
(data->blob); | 592 const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lo
ck_instance (data->blob); |
658 const OpenTypeFontFace &ot_face = ot_file.get_face (data->index); | 593 const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index); |
659 | 594 |
660 const OpenTypeTable &table = ot_face.get_table_by_tag (tag); | 595 const OT::OpenTypeTable &table = ot_face.get_table_by_tag (tag); |
661 | 596 |
662 hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.len
gth); | 597 hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.len
gth); |
663 | 598 |
664 return blob; | 599 return blob; |
665 } | 600 } |
666 | 601 |
667 hb_face_t * | 602 hb_face_t * |
668 hb_face_create (hb_blob_t *blob, | 603 hb_face_create (hb_blob_t *blob, |
669 unsigned int index) | 604 unsigned int index) |
670 { | 605 { |
671 hb_face_t *face; | 606 hb_face_t *face; |
672 | 607 |
673 if (unlikely (!blob || !hb_blob_get_length (blob))) | 608 if (unlikely (!blob || !hb_blob_get_length (blob))) |
674 return hb_face_get_empty (); | 609 return hb_face_get_empty (); |
675 | 610 |
676 hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (Saniti
zer<OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index); | 611 hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sa
nitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index); |
677 | 612 |
678 if (unlikely (!closure)) | 613 if (unlikely (!closure)) |
679 return hb_face_get_empty (); | 614 return hb_face_get_empty (); |
680 | 615 |
681 face = hb_face_create_for_tables (_hb_face_for_data_reference_table, | 616 face = hb_face_create_for_tables (_hb_face_for_data_reference_table, |
682 closure, | 617 closure, |
683 (hb_destroy_func_t) _hb_face_for_data_closur
e_destroy); | 618 (hb_destroy_func_t) _hb_face_for_data_closur
e_destroy); |
684 | 619 |
685 hb_face_set_index (face, index); | 620 hb_face_set_index (face, index); |
686 | 621 |
(...skipping 11 matching lines...) Expand all Loading... |
698 hb_face_reference (hb_face_t *face) | 633 hb_face_reference (hb_face_t *face) |
699 { | 634 { |
700 return hb_object_reference (face); | 635 return hb_object_reference (face); |
701 } | 636 } |
702 | 637 |
703 void | 638 void |
704 hb_face_destroy (hb_face_t *face) | 639 hb_face_destroy (hb_face_t *face) |
705 { | 640 { |
706 if (!hb_object_destroy (face)) return; | 641 if (!hb_object_destroy (face)) return; |
707 | 642 |
708 _hb_ot_layout_destroy (face->ot_layout); | 643 for (hb_face_t::plan_node_t *node = face->shape_plans; node; ) |
| 644 { |
| 645 hb_face_t::plan_node_t *next = node->next; |
| 646 hb_shape_plan_destroy (node->shape_plan); |
| 647 free (node); |
| 648 node = next; |
| 649 } |
| 650 |
| 651 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, face); |
| 652 #include "hb-shaper-list.hh" |
| 653 #undef HB_SHAPER_IMPLEMENT |
709 | 654 |
710 if (face->destroy) | 655 if (face->destroy) |
711 face->destroy (face->user_data); | 656 face->destroy (face->user_data); |
712 | 657 |
713 free (face); | 658 free (face); |
714 } | 659 } |
715 | 660 |
716 hb_bool_t | 661 hb_bool_t |
717 hb_face_set_user_data (hb_face_t *face, | 662 hb_face_set_user_data (hb_face_t *face, |
718 hb_user_data_key_t *key, | 663 hb_user_data_key_t *key, |
(...skipping 24 matching lines...) Expand all Loading... |
743 hb_face_is_immutable (hb_face_t *face) | 688 hb_face_is_immutable (hb_face_t *face) |
744 { | 689 { |
745 return face->immutable; | 690 return face->immutable; |
746 } | 691 } |
747 | 692 |
748 | 693 |
749 hb_blob_t * | 694 hb_blob_t * |
750 hb_face_reference_table (hb_face_t *face, | 695 hb_face_reference_table (hb_face_t *face, |
751 hb_tag_t tag) | 696 hb_tag_t tag) |
752 { | 697 { |
753 hb_blob_t *blob; | 698 return face->reference_table (tag); |
754 | |
755 if (unlikely (!face || !face->reference_table)) | |
756 return hb_blob_get_empty (); | |
757 | |
758 blob = face->reference_table (face, tag, face->user_data); | |
759 if (unlikely (!blob)) | |
760 return hb_blob_get_empty (); | |
761 | |
762 return blob; | |
763 } | 699 } |
764 | 700 |
765 hb_blob_t * | 701 hb_blob_t * |
766 hb_face_reference_blob (hb_face_t *face) | 702 hb_face_reference_blob (hb_face_t *face) |
767 { | 703 { |
768 return hb_face_reference_table (face, HB_TAG_NONE); | 704 return face->reference_table (HB_TAG_NONE); |
769 } | 705 } |
770 | 706 |
771 void | 707 void |
772 hb_face_set_index (hb_face_t *face, | 708 hb_face_set_index (hb_face_t *face, |
773 unsigned int index) | 709 unsigned int index) |
774 { | 710 { |
775 if (hb_object_is_inert (face)) | 711 if (hb_object_is_inert (face)) |
776 return; | 712 return; |
777 | 713 |
778 face->index = index; | 714 face->index = index; |
(...skipping 11 matching lines...) Expand all Loading... |
790 { | 726 { |
791 if (hb_object_is_inert (face)) | 727 if (hb_object_is_inert (face)) |
792 return; | 728 return; |
793 | 729 |
794 face->upem = upem; | 730 face->upem = upem; |
795 } | 731 } |
796 | 732 |
797 unsigned int | 733 unsigned int |
798 hb_face_get_upem (hb_face_t *face) | 734 hb_face_get_upem (hb_face_t *face) |
799 { | 735 { |
800 if (unlikely (!face->upem)) { | 736 return face->get_upem (); |
801 hb_blob_t *head_blob = Sanitizer<head>::sanitize (hb_face_reference_table (f
ace, HB_OT_TAG_head)); | |
802 const head *head_table = Sanitizer<head>::lock_instance (head_blob); | |
803 face->upem = head_table->get_upem (); | |
804 hb_blob_destroy (head_blob); | |
805 } | |
806 return face->upem; | |
807 } | 737 } |
808 | 738 |
809 | 739 |
| 740 void |
| 741 hb_face_t::load_upem (void) const |
| 742 { |
| 743 hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (reference_table (HB_
OT_TAG_head)); |
| 744 const OT::head *head_table = OT::Sanitizer<OT::head>::lock_instance (head_blob
); |
| 745 upem = head_table->get_upem (); |
| 746 hb_blob_destroy (head_blob); |
| 747 } |
| 748 |
| 749 |
810 /* | 750 /* |
811 * hb_font_t | 751 * hb_font_t |
812 */ | 752 */ |
813 | 753 |
814 hb_font_t * | 754 hb_font_t * |
815 hb_font_create (hb_face_t *face) | 755 hb_font_create (hb_face_t *face) |
816 { | 756 { |
817 hb_font_t *font; | 757 hb_font_t *font; |
818 | 758 |
819 if (unlikely (!face)) | 759 if (unlikely (!face)) |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
864 const_cast<hb_face_t *> (&_hb_face_nil), | 804 const_cast<hb_face_t *> (&_hb_face_nil), |
865 | 805 |
866 0, /* x_scale */ | 806 0, /* x_scale */ |
867 0, /* y_scale */ | 807 0, /* y_scale */ |
868 | 808 |
869 0, /* x_ppem */ | 809 0, /* x_ppem */ |
870 0, /* y_ppem */ | 810 0, /* y_ppem */ |
871 | 811 |
872 const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */ | 812 const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */ |
873 NULL, /* user_data */ | 813 NULL, /* user_data */ |
874 NULL /* destroy */ | 814 NULL, /* destroy */ |
| 815 |
| 816 { |
| 817 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, |
| 818 #include "hb-shaper-list.hh" |
| 819 #undef HB_SHAPER_IMPLEMENT |
| 820 } |
875 }; | 821 }; |
876 | 822 |
877 return const_cast<hb_font_t *> (&_hb_font_nil); | 823 return const_cast<hb_font_t *> (&_hb_font_nil); |
878 } | 824 } |
879 | 825 |
880 hb_font_t * | 826 hb_font_t * |
881 hb_font_reference (hb_font_t *font) | 827 hb_font_reference (hb_font_t *font) |
882 { | 828 { |
883 return hb_object_reference (font); | 829 return hb_object_reference (font); |
884 } | 830 } |
885 | 831 |
886 void | 832 void |
887 hb_font_destroy (hb_font_t *font) | 833 hb_font_destroy (hb_font_t *font) |
888 { | 834 { |
889 if (!hb_object_destroy (font)) return; | 835 if (!hb_object_destroy (font)) return; |
890 | 836 |
| 837 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font); |
| 838 #include "hb-shaper-list.hh" |
| 839 #undef HB_SHAPER_IMPLEMENT |
| 840 |
| 841 if (font->destroy) |
| 842 font->destroy (font->user_data); |
| 843 |
891 hb_font_destroy (font->parent); | 844 hb_font_destroy (font->parent); |
892 hb_face_destroy (font->face); | 845 hb_face_destroy (font->face); |
893 hb_font_funcs_destroy (font->klass); | 846 hb_font_funcs_destroy (font->klass); |
894 if (font->destroy) | |
895 font->destroy (font->user_data); | |
896 | 847 |
897 free (font); | 848 free (font); |
898 } | 849 } |
899 | 850 |
900 hb_bool_t | 851 hb_bool_t |
901 hb_font_set_user_data (hb_font_t *font, | 852 hb_font_set_user_data (hb_font_t *font, |
902 hb_user_data_key_t *key, | 853 hb_user_data_key_t *key, |
903 void * data, | 854 void * data, |
904 hb_destroy_func_t destroy, | 855 hb_destroy_func_t destroy, |
905 hb_bool_t replace) | 856 hb_bool_t replace) |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1021 } | 972 } |
1022 | 973 |
1023 void | 974 void |
1024 hb_font_get_ppem (hb_font_t *font, | 975 hb_font_get_ppem (hb_font_t *font, |
1025 unsigned int *x_ppem, | 976 unsigned int *x_ppem, |
1026 unsigned int *y_ppem) | 977 unsigned int *y_ppem) |
1027 { | 978 { |
1028 if (x_ppem) *x_ppem = font->x_ppem; | 979 if (x_ppem) *x_ppem = font->x_ppem; |
1029 if (y_ppem) *y_ppem = font->y_ppem; | 980 if (y_ppem) *y_ppem = font->y_ppem; |
1030 } | 981 } |
1031 | |
1032 | |
OLD | NEW |