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 * Copyright © 2015 Google, Inc. | 4 * Copyright © 2015 Google, Inc. |
5 * | 5 * |
6 * This is part of HarfBuzz, a text shaping library. | 6 * This is part of HarfBuzz, a text shaping library. |
7 * | 7 * |
8 * Permission is hereby granted, without written agreement and without | 8 * Permission is hereby granted, without written agreement and without |
9 * license or royalty fees, to use, copy, modify, and distribute this | 9 * license or royalty fees, to use, copy, modify, and distribute this |
10 * software and its documentation for any purpose, provided that the | 10 * software and its documentation for any purpose, provided that the |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 | 210 |
211 if (font->y_scale < 0) | 211 if (font->y_scale < 0) |
212 v = -v; | 212 v = -v; |
213 | 213 |
214 /* Note: FreeType's vertical metrics grows downward while other FreeType coord
inates | 214 /* Note: FreeType's vertical metrics grows downward while other FreeType coord
inates |
215 * have a Y growing upward. Hence the extra negation. */ | 215 * have a Y growing upward. Hence the extra negation. */ |
216 return (-v + (1<<9)) >> 10; | 216 return (-v + (1<<9)) >> 10; |
217 } | 217 } |
218 | 218 |
219 static hb_bool_t | 219 static hb_bool_t |
220 hb_ft_get_glyph_h_origin (hb_font_t *font HB_UNUSED, | |
221 void *font_data HB_UNUSED, | |
222 hb_codepoint_t glyph HB_UNUSED, | |
223 hb_position_t *x HB_UNUSED, | |
224 hb_position_t *y HB_UNUSED, | |
225 void *user_data HB_UNUSED) | |
226 { | |
227 /* We always work in the horizontal coordinates. */ | |
228 return true; | |
229 } | |
230 | |
231 static hb_bool_t | |
232 hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED, | 220 hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED, |
233 void *font_data, | 221 void *font_data, |
234 hb_codepoint_t glyph, | 222 hb_codepoint_t glyph, |
235 hb_position_t *x, | 223 hb_position_t *x, |
236 hb_position_t *y, | 224 hb_position_t *y, |
237 void *user_data HB_UNUSED) | 225 void *user_data HB_UNUSED) |
238 { | 226 { |
239 const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; | 227 const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; |
240 FT_Face ft_face = ft_font->ft_face; | 228 FT_Face ft_face = ft_font->ft_face; |
241 | 229 |
(...skipping 23 matching lines...) Expand all Loading... |
265 const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; | 253 const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; |
266 FT_Vector kerningv; | 254 FT_Vector kerningv; |
267 | 255 |
268 FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED
; | 256 FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED
; |
269 if (FT_Get_Kerning (ft_font->ft_face, left_glyph, right_glyph, mode, &kerningv
)) | 257 if (FT_Get_Kerning (ft_font->ft_face, left_glyph, right_glyph, mode, &kerningv
)) |
270 return 0; | 258 return 0; |
271 | 259 |
272 return kerningv.x; | 260 return kerningv.x; |
273 } | 261 } |
274 | 262 |
275 static hb_position_t | |
276 hb_ft_get_glyph_v_kerning (hb_font_t *font HB_UNUSED, | |
277 void *font_data HB_UNUSED, | |
278 hb_codepoint_t top_glyph HB_UNUSED, | |
279 hb_codepoint_t bottom_glyph HB_UNUSED, | |
280 void *user_data HB_UNUSED) | |
281 { | |
282 /* FreeType API doesn't support vertical kerning */ | |
283 return 0; | |
284 } | |
285 | |
286 static hb_bool_t | 263 static hb_bool_t |
287 hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED, | 264 hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED, |
288 void *font_data, | 265 void *font_data, |
289 hb_codepoint_t glyph, | 266 hb_codepoint_t glyph, |
290 hb_glyph_extents_t *extents, | 267 hb_glyph_extents_t *extents, |
291 void *user_data HB_UNUSED) | 268 void *user_data HB_UNUSED) |
292 { | 269 { |
293 const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; | 270 const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; |
294 FT_Face ft_face = ft_font->ft_face; | 271 FT_Face ft_face = ft_font->ft_face; |
295 | 272 |
296 if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) | 273 if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) |
297 return false; | 274 return false; |
298 | 275 |
299 extents->x_bearing = ft_face->glyph->metrics.horiBearingX; | 276 extents->x_bearing = ft_face->glyph->metrics.horiBearingX; |
300 extents->y_bearing = ft_face->glyph->metrics.horiBearingY; | 277 extents->y_bearing = ft_face->glyph->metrics.horiBearingY; |
301 extents->width = ft_face->glyph->metrics.width; | 278 extents->width = ft_face->glyph->metrics.width; |
302 extents->height = -ft_face->glyph->metrics.height; | 279 extents->height = -ft_face->glyph->metrics.height; |
| 280 if (font->x_scale < 0) |
| 281 { |
| 282 extents->x_bearing = -extents->x_bearing; |
| 283 extents->width = -extents->width; |
| 284 } |
| 285 if (font->y_scale < 0) |
| 286 { |
| 287 extents->y_bearing = -extents->y_bearing; |
| 288 extents->height = -extents->height; |
| 289 } |
303 return true; | 290 return true; |
304 } | 291 } |
305 | 292 |
306 static hb_bool_t | 293 static hb_bool_t |
307 hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED, | 294 hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED, |
308 void *font_data, | 295 void *font_data, |
309 hb_codepoint_t glyph, | 296 hb_codepoint_t glyph, |
310 unsigned int point_index, | 297 unsigned int point_index, |
311 hb_position_t *x, | 298 hb_position_t *x, |
312 hb_position_t *y, | 299 hb_position_t *y, |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 char buf[128]; | 360 char buf[128]; |
374 if (!FT_Get_Glyph_Name(ft_face, 0, buf, sizeof (buf)) && | 361 if (!FT_Get_Glyph_Name(ft_face, 0, buf, sizeof (buf)) && |
375 len < 0 ? !strcmp (buf, name) : !strncmp (buf, name, len)) | 362 len < 0 ? !strcmp (buf, name) : !strncmp (buf, name, len)) |
376 return true; | 363 return true; |
377 } | 364 } |
378 | 365 |
379 return *glyph != 0; | 366 return *glyph != 0; |
380 } | 367 } |
381 | 368 |
382 | 369 |
| 370 static hb_font_funcs_t *static_ft_funcs = NULL; |
| 371 |
| 372 #ifdef HB_USE_ATEXIT |
| 373 static |
| 374 void free_static_ft_funcs (void) |
| 375 { |
| 376 hb_font_funcs_destroy (static_ft_funcs); |
| 377 } |
| 378 #endif |
| 379 |
383 static void | 380 static void |
384 _hb_ft_font_set_funcs (hb_font_t *font, FT_Face ft_face, bool unref) | 381 _hb_ft_font_set_funcs (hb_font_t *font, FT_Face ft_face, bool unref) |
385 { | 382 { |
386 static const hb_font_funcs_t ft_ffuncs = { | 383 retry: |
387 HB_OBJECT_HEADER_STATIC, | 384 hb_font_funcs_t *funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ft_fun
cs); |
388 | 385 |
389 true, /* immutable */ | 386 if (unlikely (!funcs)) |
| 387 { |
| 388 funcs = hb_font_funcs_create (); |
390 | 389 |
391 { | 390 hb_font_funcs_set_glyph_func (funcs, hb_ft_get_glyph, NULL, NULL); |
392 #define HB_FONT_FUNC_IMPLEMENT(name) hb_ft_get_##name, | 391 hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ft_get_glyph_h_advance, NU
LL, NULL); |
393 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS | 392 hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, NU
LL, NULL); |
394 #undef HB_FONT_FUNC_IMPLEMENT | 393 //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, NU
LL, NULL); |
| 394 hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ft_get_glyph_v_origin, NULL
, NULL); |
| 395 hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ft_get_glyph_h_kerning, NU
LL, NULL); |
| 396 //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ft_get_glyph_v_kerning,
NULL, NULL); |
| 397 hb_font_funcs_set_glyph_extents_func (funcs, hb_ft_get_glyph_extents, NULL,
NULL); |
| 398 hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ft_get_glyph_contour_p
oint, NULL, NULL); |
| 399 hb_font_funcs_set_glyph_name_func (funcs, hb_ft_get_glyph_name, NULL, NULL); |
| 400 hb_font_funcs_set_glyph_from_name_func (funcs, hb_ft_get_glyph_from_name, NU
LL, NULL); |
| 401 |
| 402 hb_font_funcs_make_immutable (funcs); |
| 403 |
| 404 if (!hb_atomic_ptr_cmpexch (&static_ft_funcs, NULL, funcs)) { |
| 405 hb_font_funcs_destroy (funcs); |
| 406 goto retry; |
395 } | 407 } |
| 408 |
| 409 #ifdef HB_USE_ATEXIT |
| 410 atexit (free_static_ft_funcs); /* First person registers atexit() callback.
*/ |
| 411 #endif |
396 }; | 412 }; |
397 | 413 |
398 hb_font_set_funcs (font, | 414 hb_font_set_funcs (font, |
399 » » const_cast<hb_font_funcs_t *> (&ft_ffuncs), | 415 » » funcs, |
400 _hb_ft_font_create (ft_face, unref), | 416 _hb_ft_font_create (ft_face, unref), |
401 (hb_destroy_func_t) _hb_ft_font_destroy); | 417 (hb_destroy_func_t) _hb_ft_font_destroy); |
402 } | 418 } |
403 | 419 |
404 | 420 |
405 static hb_blob_t * | 421 static hb_blob_t * |
406 reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) | 422 reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) |
407 { | 423 { |
408 FT_Face ft_face = (FT_Face) user_data; | 424 FT_Face ft_face = (FT_Face) user_data; |
409 FT_Byte *buffer; | 425 FT_Byte *buffer; |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 0, font->y_scale < 0 ? -1 : +1}; | 657 0, font->y_scale < 0 ? -1 : +1}; |
642 FT_Set_Transform (ft_face, &matrix, NULL); | 658 FT_Set_Transform (ft_face, &matrix, NULL); |
643 } | 659 } |
644 | 660 |
645 ft_face->generic.data = blob; | 661 ft_face->generic.data = blob; |
646 ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob; | 662 ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob; |
647 | 663 |
648 _hb_ft_font_set_funcs (font, ft_face, true); | 664 _hb_ft_font_set_funcs (font, ft_face, true); |
649 hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING); | 665 hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING); |
650 } | 666 } |
OLD | NEW |