OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2009 Red Hat, Inc. | 2 * Copyright © 2009 Red Hat, Inc. |
3 * Copyright © 2009 Keith Stribley | 3 * Copyright © 2009 Keith Stribley |
4 * | 4 * |
5 * This is part of HarfBuzz, a text shaping library. | 5 * This is part of HarfBuzz, a text shaping library. |
6 * | 6 * |
7 * Permission is hereby granted, without written agreement and without | 7 * Permission is hereby granted, without written agreement and without |
8 * license or royalty fees, to use, copy, modify, and distribute this | 8 * license or royalty fees, to use, copy, modify, and distribute this |
9 * software and its documentation for any purpose, provided that the | 9 * software and its documentation for any purpose, provided that the |
10 * above copyright notice and the following two paragraphs appear in | 10 * above copyright notice and the following two paragraphs appear in |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 hb_codepoint_t variation_selector, | 66 hb_codepoint_t variation_selector, |
67 hb_codepoint_t *glyph, | 67 hb_codepoint_t *glyph, |
68 void *user_data HB_UNUSED) | 68 void *user_data HB_UNUSED) |
69 | 69 |
70 { | 70 { |
71 FT_Face ft_face = (FT_Face) font_data; | 71 FT_Face ft_face = (FT_Face) font_data; |
72 | 72 |
73 #ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX | 73 #ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX |
74 if (unlikely (variation_selector)) { | 74 if (unlikely (variation_selector)) { |
75 *glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector); | 75 *glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector); |
76 if (*glyph) | 76 return *glyph != 0; |
77 return true; | |
78 } | 77 } |
79 #endif | 78 #endif |
80 | 79 |
81 *glyph = FT_Get_Char_Index (ft_face, unicode); | 80 *glyph = FT_Get_Char_Index (ft_face, unicode); |
82 return *glyph != 0; | 81 return *glyph != 0; |
83 } | 82 } |
84 | 83 |
85 static hb_position_t | 84 static hb_position_t |
86 hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED, | 85 hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED, |
87 void *font_data, | 86 void *font_data, |
88 hb_codepoint_t glyph, | 87 hb_codepoint_t glyph, |
89 void *user_data HB_UNUSED) | 88 void *user_data HB_UNUSED) |
90 { | 89 { |
91 FT_Face ft_face = (FT_Face) font_data; | 90 FT_Face ft_face = (FT_Face) font_data; |
92 int load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; | 91 int load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; |
93 FT_Fixed v; | 92 FT_Fixed v; |
94 | 93 |
95 if (unlikely (FT_Get_Advance (ft_face, glyph, load_flags, &v))) | 94 if (unlikely (FT_Get_Advance (ft_face, glyph, load_flags, &v))) |
96 return 0; | 95 return 0; |
97 | 96 |
98 return v >> 10; | 97 return (v + (1<<9)) >> 10; |
99 } | 98 } |
100 | 99 |
101 static hb_position_t | 100 static hb_position_t |
102 hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED, | 101 hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED, |
103 void *font_data, | 102 void *font_data, |
104 hb_codepoint_t glyph, | 103 hb_codepoint_t glyph, |
105 void *user_data HB_UNUSED) | 104 void *user_data HB_UNUSED) |
106 { | 105 { |
107 FT_Face ft_face = (FT_Face) font_data; | 106 FT_Face ft_face = (FT_Face) font_data; |
108 int load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING | FT_LOAD_VERTICAL_LAYOU
T; | 107 int load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING | FT_LOAD_VERTICAL_LAYOU
T; |
109 FT_Fixed v; | 108 FT_Fixed v; |
110 | 109 |
111 if (unlikely (FT_Get_Advance (ft_face, glyph, load_flags, &v))) | 110 if (unlikely (FT_Get_Advance (ft_face, glyph, load_flags, &v))) |
112 return 0; | 111 return 0; |
113 | 112 |
114 /* Note: FreeType's vertical metrics grows downward while other FreeType coord
inates | 113 /* Note: FreeType's vertical metrics grows downward while other FreeType coord
inates |
115 * have a Y growing upward. Hence the extra negation. */ | 114 * have a Y growing upward. Hence the extra negation. */ |
116 return -v >> 10; | 115 return (-v + (1<<9)) >> 10; |
117 } | 116 } |
118 | 117 |
119 static hb_bool_t | 118 static hb_bool_t |
120 hb_ft_get_glyph_h_origin (hb_font_t *font HB_UNUSED, | 119 hb_ft_get_glyph_h_origin (hb_font_t *font HB_UNUSED, |
121 void *font_data HB_UNUSED, | 120 void *font_data HB_UNUSED, |
122 hb_codepoint_t glyph HB_UNUSED, | 121 hb_codepoint_t glyph HB_UNUSED, |
123 hb_position_t *x HB_UNUSED, | 122 hb_position_t *x HB_UNUSED, |
124 hb_position_t *y HB_UNUSED, | 123 hb_position_t *y HB_UNUSED, |
125 void *user_data HB_UNUSED) | 124 void *user_data HB_UNUSED) |
126 { | 125 { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 *glyph = FT_Get_Name_Index (ft_face, (FT_String *) name); | 253 *glyph = FT_Get_Name_Index (ft_face, (FT_String *) name); |
255 else { | 254 else { |
256 /* Make a nul-terminated version. */ | 255 /* Make a nul-terminated version. */ |
257 char buf[128]; | 256 char buf[128]; |
258 len = MIN (len, (int) sizeof (buf) - 1); | 257 len = MIN (len, (int) sizeof (buf) - 1); |
259 strncpy (buf, name, len); | 258 strncpy (buf, name, len); |
260 buf[len] = '\0'; | 259 buf[len] = '\0'; |
261 *glyph = FT_Get_Name_Index (ft_face, buf); | 260 *glyph = FT_Get_Name_Index (ft_face, buf); |
262 } | 261 } |
263 | 262 |
| 263 if (*glyph == 0) |
| 264 { |
| 265 /* Check whether the given name was actually the name of glyph 0. */ |
| 266 char buf[128]; |
| 267 if (!FT_Get_Glyph_Name(ft_face, 0, buf, sizeof (buf)) && |
| 268 len < 0 ? !strcmp (buf, name) : !strncmp (buf, name, len)) |
| 269 return true; |
| 270 } |
| 271 |
264 return *glyph != 0; | 272 return *glyph != 0; |
265 } | 273 } |
266 | 274 |
267 | 275 |
268 static hb_font_funcs_t * | 276 static hb_font_funcs_t * |
269 _hb_ft_get_font_funcs (void) | 277 _hb_ft_get_font_funcs (void) |
270 { | 278 { |
271 static const hb_font_funcs_t ft_ffuncs = { | 279 static const hb_font_funcs_t ft_ffuncs = { |
272 HB_OBJECT_HEADER_STATIC, | 280 HB_OBJECT_HEADER_STATIC, |
273 | 281 |
(...skipping 30 matching lines...) Expand all Loading... |
304 | 312 |
305 error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length); | 313 error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length); |
306 if (error) | 314 if (error) |
307 return NULL; | 315 return NULL; |
308 | 316 |
309 return hb_blob_create ((const char *) buffer, length, | 317 return hb_blob_create ((const char *) buffer, length, |
310 HB_MEMORY_MODE_WRITABLE, | 318 HB_MEMORY_MODE_WRITABLE, |
311 buffer, free); | 319 buffer, free); |
312 } | 320 } |
313 | 321 |
314 | 322 /** |
| 323 * hb_ft_face_create: |
| 324 * @ft_face: (destroy destroy) (scope notified): |
| 325 * @destroy: |
| 326 * |
| 327 * |
| 328 * |
| 329 * Return value: (transfer full): |
| 330 * Since: 1.0 |
| 331 **/ |
315 hb_face_t * | 332 hb_face_t * |
316 hb_ft_face_create (FT_Face ft_face, | 333 hb_ft_face_create (FT_Face ft_face, |
317 hb_destroy_func_t destroy) | 334 hb_destroy_func_t destroy) |
318 { | 335 { |
319 hb_face_t *face; | 336 hb_face_t *face; |
320 | 337 |
321 if (ft_face->stream->read == NULL) { | 338 if (ft_face->stream->read == NULL) { |
322 hb_blob_t *blob; | 339 hb_blob_t *blob; |
323 | 340 |
324 blob = hb_blob_create ((const char *) ft_face->stream->base, | 341 blob = hb_blob_create ((const char *) ft_face->stream->base, |
(...skipping 15 matching lines...) Expand all Loading... |
340 | 357 |
341 return face; | 358 return face; |
342 } | 359 } |
343 | 360 |
344 static void | 361 static void |
345 hb_ft_face_finalize (FT_Face ft_face) | 362 hb_ft_face_finalize (FT_Face ft_face) |
346 { | 363 { |
347 hb_face_destroy ((hb_face_t *) ft_face->generic.data); | 364 hb_face_destroy ((hb_face_t *) ft_face->generic.data); |
348 } | 365 } |
349 | 366 |
| 367 /** |
| 368 * hb_ft_face_create_cached: |
| 369 * @ft_face: |
| 370 * |
| 371 * |
| 372 * |
| 373 * Return value: (transfer full): |
| 374 * Since: 1.0 |
| 375 **/ |
350 hb_face_t * | 376 hb_face_t * |
351 hb_ft_face_create_cached (FT_Face ft_face) | 377 hb_ft_face_create_cached (FT_Face ft_face) |
352 { | 378 { |
353 if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Gene
ric_Finalizer) hb_ft_face_finalize)) | 379 if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Gene
ric_Finalizer) hb_ft_face_finalize)) |
354 { | 380 { |
355 if (ft_face->generic.finalizer) | 381 if (ft_face->generic.finalizer) |
356 ft_face->generic.finalizer (ft_face); | 382 ft_face->generic.finalizer (ft_face); |
357 | 383 |
358 ft_face->generic.data = hb_ft_face_create (ft_face, NULL); | 384 ft_face->generic.data = hb_ft_face_create (ft_face, NULL); |
359 ft_face->generic.finalizer = (FT_Generic_Finalizer) hb_ft_face_finalize; | 385 ft_face->generic.finalizer = (FT_Generic_Finalizer) hb_ft_face_finalize; |
360 } | 386 } |
361 | 387 |
362 return hb_face_reference ((hb_face_t *) ft_face->generic.data); | 388 return hb_face_reference ((hb_face_t *) ft_face->generic.data); |
363 } | 389 } |
364 | 390 |
365 static void | 391 static void |
366 _do_nothing (void) | 392 _do_nothing (void) |
367 { | 393 { |
368 } | 394 } |
369 | 395 |
370 | 396 |
| 397 /** |
| 398 * hb_ft_font_create: |
| 399 * @ft_face: (destroy destroy) (scope notified): |
| 400 * @destroy: |
| 401 * |
| 402 * |
| 403 * |
| 404 * Return value: (transfer full): |
| 405 * Since: 1.0 |
| 406 **/ |
371 hb_font_t * | 407 hb_font_t * |
372 hb_ft_font_create (FT_Face ft_face, | 408 hb_ft_font_create (FT_Face ft_face, |
373 hb_destroy_func_t destroy) | 409 hb_destroy_func_t destroy) |
374 { | 410 { |
375 hb_font_t *font; | 411 hb_font_t *font; |
376 hb_face_t *face; | 412 hb_face_t *face; |
377 | 413 |
378 face = hb_ft_face_create (ft_face, destroy); | 414 face = hb_ft_face_create (ft_face, destroy); |
379 font = hb_font_create (face); | 415 font = hb_font_create (face); |
380 hb_face_destroy (face); | 416 hb_face_destroy (face); |
381 hb_font_set_funcs (font, | 417 hb_font_set_funcs (font, |
382 _hb_ft_get_font_funcs (), | 418 _hb_ft_get_font_funcs (), |
383 ft_face, (hb_destroy_func_t) _do_nothing); | 419 ft_face, (hb_destroy_func_t) _do_nothing); |
384 hb_font_set_scale (font, | 420 hb_font_set_scale (font, |
385 » » ((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_
face->units_per_EM) >> 16, | 421 » » (int) (((uint64_t) ft_face->size->metrics.x_scale * (uint64
_t) ft_face->units_per_EM + (1<<15)) >> 16), |
386 » » ((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_
face->units_per_EM) >> 16); | 422 » » (int) (((uint64_t) ft_face->size->metrics.y_scale * (uint64
_t) ft_face->units_per_EM + (1<<15)) >> 16)); |
387 hb_font_set_ppem (font, | 423 hb_font_set_ppem (font, |
388 ft_face->size->metrics.x_ppem, | 424 ft_face->size->metrics.x_ppem, |
389 ft_face->size->metrics.y_ppem); | 425 ft_face->size->metrics.y_ppem); |
390 | 426 |
391 return font; | 427 return font; |
392 } | 428 } |
393 | 429 |
394 | 430 |
395 /* Thread-safe, lock-free, FT_Library */ | 431 /* Thread-safe, lock-free, FT_Library */ |
396 | 432 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 | 513 |
478 FT_Face | 514 FT_Face |
479 hb_ft_font_get_face (hb_font_t *font) | 515 hb_ft_font_get_face (hb_font_t *font) |
480 { | 516 { |
481 if (font->destroy == (hb_destroy_func_t) FT_Done_Face || | 517 if (font->destroy == (hb_destroy_func_t) FT_Done_Face || |
482 font->destroy == (hb_destroy_func_t) _do_nothing) | 518 font->destroy == (hb_destroy_func_t) _do_nothing) |
483 return (FT_Face) font->user_data; | 519 return (FT_Face) font->user_data; |
484 | 520 |
485 return NULL; | 521 return NULL; |
486 } | 522 } |
OLD | NEW |