blob: 48fbb0ee54931990bc8089e7791500bac2fcdd4b [file] [log] [blame]
Behdad Esfahbodc62b5032009-08-01 19:54:49 -04001/*
Behdad Esfahbod2409d5f2011-04-21 17:14:28 -04002 * Copyright © 2009 Red Hat, Inc.
3 * Copyright © 2011 Google, Inc.
Behdad Esfahbodc62b5032009-08-01 19:54:49 -04004 *
Behdad Esfahbodc755cb32010-04-22 00:11:43 -04005 * This is part of HarfBuzz, a text shaping library.
Behdad Esfahbodc62b5032009-08-01 19:54:49 -04006 *
7 * Permission is hereby granted, without written agreement and without
8 * license or royalty fees, to use, copy, modify, and distribute this
9 * software and its documentation for any purpose, provided that the
10 * above copyright notice and the following two paragraphs appear in
11 * all copies of this software.
12 *
13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17 * DAMAGE.
18 *
19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
22 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24 *
25 * Red Hat Author(s): Behdad Esfahbod
Behdad Esfahbod2409d5f2011-04-21 17:14:28 -040026 * Google Author(s): Behdad Esfahbod
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040027 */
28
Behdad Esfahbodc57d4542011-04-20 18:50:27 -040029#ifndef HB_FONT_PRIVATE_HH
30#define HB_FONT_PRIVATE_HH
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040031
Behdad Esfahbodc57d4542011-04-20 18:50:27 -040032#include "hb-private.hh"
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040033
34#include "hb-font.h"
Behdad Esfahbodfca368c2011-04-21 18:24:02 -040035#include "hb-object-private.hh"
Behdad Esfahbod027857d2012-07-26 17:34:25 -040036#include "hb-shaper-private.hh"
Behdad Esfahbod2f87ceb2012-07-27 04:02:38 -040037#include "hb-shape-plan-private.hh"
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040038
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040039
Behdad Esfahbodacdba3f2010-07-23 15:11:18 -040040
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040041/*
Behdad Esfahbod5c441882009-08-10 20:05:16 -040042 * hb_font_funcs_t
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040043 */
44
Behdad Esfahbod744970a2011-05-16 18:15:37 -040045#define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \
46 HB_FONT_FUNC_IMPLEMENT (glyph) \
47 HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
48 HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
Behdad Esfahbod7e2c85d2011-05-17 17:55:03 -040049 HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \
Behdad Esfahbod744970a2011-05-16 18:15:37 -040050 HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
Behdad Esfahbod7e2c85d2011-05-17 17:55:03 -040051 HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
52 HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \
Behdad Esfahbod744970a2011-05-16 18:15:37 -040053 HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
Behdad Esfahbod4b6317c2011-07-07 23:14:42 -040054 HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
Behdad Esfahbodbce09552012-05-27 11:29:21 -040055 HB_FONT_FUNC_IMPLEMENT (glyph_name) \
56 HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \
Behdad Esfahbod4b6317c2011-07-07 23:14:42 -040057 /* ^--- Add new callbacks here */
Behdad Esfahbod744970a2011-05-16 18:15:37 -040058
Behdad Esfahbod1bc1cb32012-06-16 15:21:55 -040059struct hb_font_funcs_t {
Behdad Esfahbod4b6317c2011-07-07 23:14:42 -040060 hb_object_header_t header;
Behdad Esfahbod6220e5f2012-06-06 03:30:09 -040061 ASSERT_POD ();
Behdad Esfahbod4b6317c2011-07-07 23:14:42 -040062
63 hb_bool_t immutable;
64
65 /* Don't access these directly. Call hb_font_get_*() instead. */
Behdad Esfahbod744970a2011-05-16 18:15:37 -040066
Behdad Esfahbodbf36a102010-05-24 17:46:21 +010067 struct {
Behdad Esfahbod744970a2011-05-16 18:15:37 -040068#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name;
69 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
70#undef HB_FONT_FUNC_IMPLEMENT
Behdad Esfahbodb9d975b2011-05-10 20:41:13 -040071 } get;
72
73 struct {
Behdad Esfahbod744970a2011-05-16 18:15:37 -040074#define HB_FONT_FUNC_IMPLEMENT(name) void *name;
75 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
76#undef HB_FONT_FUNC_IMPLEMENT
Behdad Esfahbodb9d975b2011-05-10 20:41:13 -040077 } user_data;
78
79 struct {
Behdad Esfahbod744970a2011-05-16 18:15:37 -040080#define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
81 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
82#undef HB_FONT_FUNC_IMPLEMENT
Behdad Esfahbodb9d975b2011-05-10 20:41:13 -040083 } destroy;
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040084};
85
86
87/*
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040088 * hb_face_t
89 */
90
Behdad Esfahbod1bc1cb32012-06-16 15:21:55 -040091struct hb_face_t {
Behdad Esfahbodfca368c2011-04-21 18:24:02 -040092 hb_object_header_t header;
Behdad Esfahbod6220e5f2012-06-06 03:30:09 -040093 ASSERT_POD ();
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040094
Behdad Esfahbod7fc5a302011-05-12 17:48:20 -040095 hb_bool_t immutable;
96
Behdad Esfahbod4c8ac4f2012-08-08 17:44:19 -040097 hb_reference_table_func_t reference_table_func;
Behdad Esfahbode7157842011-08-08 21:42:02 +020098 void *user_data;
99 hb_destroy_func_t destroy;
Behdad Esfahbodc62b5032009-08-01 19:54:49 -0400100
Behdad Esfahbod38973352011-08-08 23:37:41 +0200101 unsigned int index;
Behdad Esfahbod4c8ac4f2012-08-08 17:44:19 -0400102 mutable unsigned int upem;
Behdad Esfahbode05a9992012-11-15 16:23:21 -0800103 mutable unsigned int num_glyphs;
Behdad Esfahbod027857d2012-07-26 17:34:25 -0400104
105 struct hb_shaper_data_t shaper_data;
Behdad Esfahbod2f87ceb2012-07-27 04:02:38 -0400106
107 struct plan_node_t {
108 hb_shape_plan_t *shape_plan;
109 plan_node_t *next;
110 } *shape_plans;
Behdad Esfahbod4c8ac4f2012-08-08 17:44:19 -0400111
112
113 inline hb_blob_t *reference_table (hb_tag_t tag) const
114 {
115 hb_blob_t *blob;
116
117 if (unlikely (!this || !reference_table_func))
118 return hb_blob_get_empty ();
119
120 blob = reference_table_func (/*XXX*/const_cast<hb_face_t *> (this), tag, user_data);
121 if (unlikely (!blob))
122 return hb_blob_get_empty ();
123
124 return blob;
125 }
126
127 inline unsigned int get_upem (void) const
128 {
129 if (unlikely (!upem))
130 load_upem ();
131 return upem;
132 }
133
Behdad Esfahbode05a9992012-11-15 16:23:21 -0800134 inline unsigned int get_num_glyphs (void) const
135 {
136 if (unlikely (num_glyphs == (unsigned int) -1))
137 load_num_glyphs ();
138 return num_glyphs;
139 }
140
Behdad Esfahbod4c8ac4f2012-08-08 17:44:19 -0400141 private:
142 HB_INTERNAL void load_upem (void) const;
Behdad Esfahbode05a9992012-11-15 16:23:21 -0800143 HB_INTERNAL void load_num_glyphs (void) const;
Behdad Esfahbodc62b5032009-08-01 19:54:49 -0400144};
145
Behdad Esfahbod5b95c142012-07-26 23:46:53 -0400146#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
Behdad Esfahbod027857d2012-07-26 17:34:25 -0400147#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, face);
148#include "hb-shaper-list.hh"
149#undef HB_SHAPER_IMPLEMENT
Behdad Esfahbod5b95c142012-07-26 23:46:53 -0400150#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
Behdad Esfahbod027857d2012-07-26 17:34:25 -0400151
Behdad Esfahbodc62b5032009-08-01 19:54:49 -0400152
153/*
154 * hb_font_t
155 */
156
Behdad Esfahbod1bc1cb32012-06-16 15:21:55 -0400157struct hb_font_t {
Behdad Esfahbodfca368c2011-04-21 18:24:02 -0400158 hb_object_header_t header;
Behdad Esfahbod6220e5f2012-06-06 03:30:09 -0400159 ASSERT_POD ();
Behdad Esfahbodc62b5032009-08-01 19:54:49 -0400160
Behdad Esfahbod74f1d892011-05-10 19:39:32 -0400161 hb_bool_t immutable;
162
Behdad Esfahboddefc45b2011-05-10 20:02:49 -0400163 hb_font_t *parent;
Behdad Esfahbod72657e42011-05-02 20:46:32 -0400164 hb_face_t *face;
165
Behdad Esfahbod11bb8fe2011-05-10 19:57:00 -0400166 int x_scale;
167 int y_scale;
Behdad Esfahbodc62b5032009-08-01 19:54:49 -0400168
169 unsigned int x_ppem;
170 unsigned int y_ppem;
Behdad Esfahbod5c441882009-08-10 20:05:16 -0400171
Behdad Esfahbod8fb3d1a2009-11-03 18:34:20 -0500172 hb_font_funcs_t *klass;
Behdad Esfahbod8fb3d1a2009-11-03 18:34:20 -0500173 void *user_data;
Behdad Esfahbod56681892011-04-20 03:03:32 -0400174 hb_destroy_func_t destroy;
Behdad Esfahbodabcfe9b2011-05-11 00:02:02 -0400175
Behdad Esfahbod027857d2012-07-26 17:34:25 -0400176 struct hb_shaper_data_t shaper_data;
177
Behdad Esfahbodabcfe9b2011-05-11 00:02:02 -0400178
179 /* Convert from font-space to user-space */
Behdad Esfahbodb6f902a2011-05-11 00:04:15 -0400180 inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, this->x_scale); }
181 inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, this->y_scale); }
Behdad Esfahbodabcfe9b2011-05-11 00:02:02 -0400182
Behdad Esfahbod63d646f2011-05-11 00:15:37 -0400183 /* Convert from parent-font user-space to our user-space */
184 inline hb_position_t parent_scale_x_distance (hb_position_t v) {
185 if (unlikely (parent && parent->x_scale != x_scale))
186 return v * (int64_t) this->x_scale / this->parent->x_scale;
187 return v;
188 }
189 inline hb_position_t parent_scale_y_distance (hb_position_t v) {
190 if (unlikely (parent && parent->y_scale != y_scale))
191 return v * (int64_t) this->y_scale / this->parent->y_scale;
192 return v;
193 }
194 inline hb_position_t parent_scale_x_position (hb_position_t v) {
Behdad Esfahbod60fbb362011-05-19 18:46:15 -0400195 return parent_scale_x_distance (v);
Behdad Esfahbod63d646f2011-05-11 00:15:37 -0400196 }
197 inline hb_position_t parent_scale_y_position (hb_position_t v) {
Behdad Esfahbod60fbb362011-05-19 18:46:15 -0400198 return parent_scale_y_distance (v);
Behdad Esfahbod63d646f2011-05-11 00:15:37 -0400199 }
200
201 inline void parent_scale_distance (hb_position_t *x, hb_position_t *y) {
202 *x = parent_scale_x_distance (*x);
203 *y = parent_scale_y_distance (*y);
204 }
205 inline void parent_scale_position (hb_position_t *x, hb_position_t *y) {
206 *x = parent_scale_x_position (*x);
207 *y = parent_scale_y_position (*y);
208 }
209
210
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400211 /* Public getters */
212
213 inline hb_bool_t get_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
214 hb_codepoint_t *glyph)
215 {
216 *glyph = 0;
217 return klass->get.glyph (this, user_data,
218 unicode, variation_selector, glyph,
219 klass->user_data.glyph);
220 }
221
222 inline hb_position_t get_glyph_h_advance (hb_codepoint_t glyph)
223 {
224 return klass->get.glyph_h_advance (this, user_data,
225 glyph,
226 klass->user_data.glyph_h_advance);
227 }
228
229 inline hb_position_t get_glyph_v_advance (hb_codepoint_t glyph)
230 {
231 return klass->get.glyph_v_advance (this, user_data,
232 glyph,
233 klass->user_data.glyph_v_advance);
234 }
235
236 inline hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
237 hb_position_t *x, hb_position_t *y)
238 {
239 *x = *y = 0;
240 return klass->get.glyph_h_origin (this, user_data,
241 glyph, x, y,
242 klass->user_data.glyph_h_origin);
243 }
244
245 inline hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph,
246 hb_position_t *x, hb_position_t *y)
247 {
248 *x = *y = 0;
249 return klass->get.glyph_v_origin (this, user_data,
250 glyph, x, y,
251 klass->user_data.glyph_v_origin);
252 }
253
254 inline hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
255 {
256 return klass->get.glyph_h_kerning (this, user_data,
257 left_glyph, right_glyph,
258 klass->user_data.glyph_h_kerning);
259 }
260
261 inline hb_position_t get_glyph_v_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
262 {
263 return klass->get.glyph_v_kerning (this, user_data,
264 left_glyph, right_glyph,
265 klass->user_data.glyph_v_kerning);
266 }
267
268 inline hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
269 hb_glyph_extents_t *extents)
270 {
271 memset (extents, 0, sizeof (*extents));
272 return klass->get.glyph_extents (this, user_data,
273 glyph,
274 extents,
275 klass->user_data.glyph_extents);
276 }
277
278 inline hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index,
279 hb_position_t *x, hb_position_t *y)
280 {
281 *x = *y = 0;
282 return klass->get.glyph_contour_point (this, user_data,
283 glyph, point_index,
284 x, y,
285 klass->user_data.glyph_contour_point);
286 }
287
288 inline hb_bool_t get_glyph_name (hb_codepoint_t glyph,
289 char *name, unsigned int size)
290 {
Behdad Esfahbod6f3a3002012-08-07 22:13:25 -0400291 if (size) *name = '\0';
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400292 return klass->get.glyph_name (this, user_data,
293 glyph,
294 name, size,
295 klass->user_data.glyph_name);
296 }
297
298 inline hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */
299 hb_codepoint_t *glyph)
300 {
Behdad Esfahbod6f3a3002012-08-07 22:13:25 -0400301 *glyph = 0;
302 if (len == -1) len = strlen (name);
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400303 return klass->get.glyph_from_name (this, user_data,
304 name, len,
305 glyph,
306 klass->user_data.glyph_from_name);
307 }
308
309
310 /* A bit higher-level, and with fallback */
311
312 inline void get_glyph_advance_for_direction (hb_codepoint_t glyph,
313 hb_direction_t direction,
314 hb_position_t *x, hb_position_t *y)
315 {
316 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
317 *x = get_glyph_h_advance (glyph);
318 *y = 0;
319 } else {
320 *x = 0;
321 *y = get_glyph_v_advance (glyph);
322 }
323 }
324
325 /* Internal only */
326 inline void guess_v_origin_minus_h_origin (hb_codepoint_t glyph,
327 hb_position_t *x, hb_position_t *y)
328 {
329 *x = get_glyph_h_advance (glyph) / 2;
330
331 /* TODO use font_metics.ascent */
332 *y = y_scale;
333 }
334
335 inline void get_glyph_origin_for_direction (hb_codepoint_t glyph,
336 hb_direction_t direction,
337 hb_position_t *x, hb_position_t *y)
338 {
339 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
340 hb_bool_t ret = get_glyph_h_origin (glyph, x, y);
341 if (!ret && (ret = get_glyph_v_origin (glyph, x, y))) {
342 hb_position_t dx, dy;
343 guess_v_origin_minus_h_origin (glyph, &dx, &dy);
344 *x -= dx; *y -= dy;
345 }
346 } else {
347 hb_bool_t ret = get_glyph_v_origin (glyph, x, y);
348 if (!ret && (ret = get_glyph_h_origin (glyph, x, y))) {
349 hb_position_t dx, dy;
350 guess_v_origin_minus_h_origin (glyph, &dx, &dy);
351 *x += dx; *y += dy;
352 }
353 }
354 }
355
356 inline void add_glyph_origin_for_direction (hb_codepoint_t glyph,
357 hb_direction_t direction,
358 hb_position_t *x, hb_position_t *y)
359 {
360 hb_position_t origin_x, origin_y;
361
362 get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
363
364 *x += origin_x;
365 *y += origin_y;
366 }
367
368 inline void subtract_glyph_origin_for_direction (hb_codepoint_t glyph,
369 hb_direction_t direction,
370 hb_position_t *x, hb_position_t *y)
371 {
372 hb_position_t origin_x, origin_y;
373
374 get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
375
376 *x -= origin_x;
377 *y -= origin_y;
378 }
379
380 inline void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
381 hb_direction_t direction,
382 hb_position_t *x, hb_position_t *y)
383 {
384 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
385 *x = get_glyph_h_kerning (first_glyph, second_glyph);
386 *y = 0;
387 } else {
388 *x = 0;
389 *y = get_glyph_v_kerning (first_glyph, second_glyph);
390 }
391 }
392
393 inline hb_bool_t get_glyph_extents_for_origin (hb_codepoint_t glyph,
394 hb_direction_t direction,
395 hb_glyph_extents_t *extents)
396 {
397 hb_bool_t ret = get_glyph_extents (glyph, extents);
398
399 if (ret)
400 subtract_glyph_origin_for_direction (glyph, direction, &extents->x_bearing, &extents->y_bearing);
401
402 return ret;
403 }
404
405 inline hb_bool_t get_glyph_contour_point_for_origin (hb_codepoint_t glyph, unsigned int point_index,
406 hb_direction_t direction,
407 hb_position_t *x, hb_position_t *y)
408 {
409 hb_bool_t ret = get_glyph_contour_point (glyph, point_index, x, y);
410
411 if (ret)
412 subtract_glyph_origin_for_direction (glyph, direction, x, y);
413
414 return ret;
415 }
416
Behdad Esfahbod6f3a3002012-08-07 22:13:25 -0400417 /* Generates gidDDD if glyph has no name. */
418 inline void
419 glyph_to_string (hb_codepoint_t glyph,
420 char *s, unsigned int size)
421 {
422 if (get_glyph_name (glyph, s, size)) return;
423
424 snprintf (s, size, "gid%u", glyph);
425 }
426
427 /* Parses gidDDD and uniUUUU strings automatically. */
428 inline hb_bool_t
429 glyph_from_string (const char *s, int len, /* -1 means nul-terminated */
430 hb_codepoint_t *glyph)
431 {
432 if (get_glyph_from_name (s, len, glyph)) return true;
433
434 if (len == -1) len = strlen (s);
435
436 /* Straight glyph index. */
437 if (hb_codepoint_parse (s, len, 10, glyph))
438 return true;
439
440 if (len > 3)
441 {
442 /* gidDDD syntax for glyph indices. */
443 if (0 == strncmp (s, "gid", 3) &&
444 hb_codepoint_parse (s + 3, len - 3, 10, glyph))
445 return true;
446
447 /* uniUUUU and other Unicode character indices. */
448 hb_codepoint_t unichar;
449 if (0 == strncmp (s, "uni", 3) &&
450 hb_codepoint_parse (s + 3, len - 3, 16, &unichar) &&
451 get_glyph (unichar, 0, glyph))
452 return true;
453 }
454
455 return false;
456 }
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400457
Behdad Esfahbodabcfe9b2011-05-11 00:02:02 -0400458 private:
Behdad Esfahbod38973352011-08-08 23:37:41 +0200459 inline hb_position_t em_scale (int16_t v, int scale) { return v * (int64_t) scale / hb_face_get_upem (this->face); }
Behdad Esfahbodc62b5032009-08-01 19:54:49 -0400460};
461
Behdad Esfahbod5b95c142012-07-26 23:46:53 -0400462#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
Behdad Esfahbod027857d2012-07-26 17:34:25 -0400463#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
464#include "hb-shaper-list.hh"
465#undef HB_SHAPER_IMPLEMENT
Behdad Esfahbod5b95c142012-07-26 23:46:53 -0400466#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
Behdad Esfahbodc62b5032009-08-01 19:54:49 -0400467
Behdad Esfahbodc62b5032009-08-01 19:54:49 -0400468
Behdad Esfahbodc57d4542011-04-20 18:50:27 -0400469#endif /* HB_FONT_PRIVATE_HH */