Changes.
[cairo/gpu.git] / src / cairo-ft-font.c
blob6c6ff59ff2fa244de0ffc7fd550166270d871d7a
1 /* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
2 /* cairo - a vector graphics library with display and print output
4 * Copyright © 2000 Keith Packard
5 * Copyright © 2005 Red Hat, Inc
7 * This library is free software; you can redistribute it and/or
8 * modify it either under the terms of the GNU Lesser General Public
9 * License version 2.1 as published by the Free Software Foundation
10 * (the "LGPL") or, at your option, under the terms of the Mozilla
11 * Public License Version 1.1 (the "MPL"). If you do not alter this
12 * notice, a recipient may use your version of this file under either
13 * the MPL or the LGPL.
15 * You should have received a copy of the LGPL along with this library
16 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * You should have received a copy of the MPL along with this library
19 * in the file COPYING-MPL-1.1
21 * The contents of this file are subject to the Mozilla Public License
22 * Version 1.1 (the "License"); you may not use this file except in
23 * compliance with the License. You may obtain a copy of the License at
24 * http://www.mozilla.org/MPL/
26 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
27 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
28 * the specific language governing rights and limitations.
30 * The Original Code is the cairo graphics library.
32 * The Initial Developer of the Original Code is Red Hat, Inc.
34 * Contributor(s):
35 * Graydon Hoare <graydon@redhat.com>
36 * Owen Taylor <otaylor@redhat.com>
37 * Keith Packard <keithp@keithp.com>
38 * Carl Worth <cworth@cworth.org>
41 #define _BSD_SOURCE /* for strdup() */
42 #include "cairoint.h"
44 #include "cairo-ft-private.h"
46 #include <float.h>
48 #if CAIRO_HAS_FC_FONT
49 #include <fontconfig/fontconfig.h>
50 #include <fontconfig/fcfreetype.h>
51 #endif
53 #include <ft2build.h>
54 #include FT_FREETYPE_H
55 #include FT_OUTLINE_H
56 #include FT_IMAGE_H
57 #include FT_TRUETYPE_TABLES_H
58 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
59 #include FT_SYNTHESIS_H
60 #endif
62 #define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
63 #define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
64 #define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
65 #define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0)
67 /* This is the max number of FT_face objects we keep open at once
69 #define MAX_OPEN_FACES 10
72 * The simple 2x2 matrix is converted into separate scale and shape
73 * factors so that hinting works right
76 typedef struct _cairo_ft_font_transform {
77 double x_scale, y_scale;
78 double shape[2][2];
79 } cairo_ft_font_transform_t;
82 * We create an object that corresponds to a single font on the disk;
83 * (identified by a filename/id pair) these are shared between all
84 * fonts using that file. For cairo_ft_font_face_create_for_ft_face(), we
85 * just create a one-off version with a permanent face value.
88 typedef struct _cairo_ft_font_face cairo_ft_font_face_t;
90 struct _cairo_ft_unscaled_font {
91 cairo_unscaled_font_t base;
93 cairo_bool_t from_face; /* was the FT_Face provided by user? */
94 FT_Face face; /* provided or cached face */
96 /* only set if from_face is false */
97 char *filename;
98 int id;
100 /* We temporarily scale the unscaled font as needed */
101 cairo_bool_t have_scale;
102 cairo_matrix_t current_scale;
103 double x_scale; /* Extracted X scale factor */
104 double y_scale; /* Extracted Y scale factor */
105 cairo_bool_t have_shape; /* true if the current scale has a non-scale component*/
106 cairo_matrix_t current_shape;
107 FT_Matrix Current_Shape;
109 cairo_mutex_t mutex;
110 int lock_count;
112 cairo_ft_font_face_t *faces; /* Linked list of faces for this font */
115 static int
116 _cairo_ft_unscaled_font_keys_equal (const void *key_a,
117 const void *key_b);
119 static void
120 _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled);
122 typedef enum _cairo_ft_extra_flags {
123 CAIRO_FT_OPTIONS_HINT_METRICS = (1 << 0),
124 CAIRO_FT_OPTIONS_EMBOLDEN = (1 << 1)
125 } cairo_ft_extra_flags_t;
127 typedef struct _cairo_ft_options {
128 cairo_font_options_t base;
129 int load_flags; /* flags for FT_Load_Glyph */
130 cairo_ft_extra_flags_t extra_flags; /* other flags that affect results */
131 } cairo_ft_options_t;
133 struct _cairo_ft_font_face {
134 cairo_font_face_t base;
136 cairo_ft_unscaled_font_t *unscaled;
137 cairo_ft_options_t ft_options;
138 cairo_ft_font_face_t *next;
140 #if CAIRO_HAS_FC_FONT
141 FcPattern *pattern; /* if pattern is set, the above fields will be NULL */
142 cairo_font_face_t *resolved_font_face;
143 FcConfig *resolved_config;
144 #endif
147 static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend;
149 #if CAIRO_HAS_FC_FONT
150 static cairo_status_t
151 _cairo_ft_font_options_substitute (const cairo_font_options_t *options,
152 FcPattern *pattern);
154 static cairo_font_face_t *
155 _cairo_ft_resolve_pattern (FcPattern *pattern,
156 const cairo_matrix_t *font_matrix,
157 const cairo_matrix_t *ctm,
158 const cairo_font_options_t *options);
160 #endif
163 * We maintain a hash table to map file/id => #cairo_ft_unscaled_font_t.
164 * The hash table itself isn't limited in size. However, we limit the
165 * number of FT_Face objects we keep around; when we've exceeded that
166 * limit and need to create a new FT_Face, we dump the FT_Face from a
167 * random #cairo_ft_unscaled_font_t which has an unlocked FT_Face, (if
168 * there are any).
171 typedef struct _cairo_ft_unscaled_font_map {
172 cairo_hash_table_t *hash_table;
173 FT_Library ft_library;
174 int num_open_faces;
175 } cairo_ft_unscaled_font_map_t;
177 static cairo_ft_unscaled_font_map_t *cairo_ft_unscaled_font_map = NULL;
179 static void
180 _font_map_release_face_lock_held (cairo_ft_unscaled_font_map_t *font_map,
181 cairo_ft_unscaled_font_t *unscaled)
183 if (unscaled->face) {
184 FT_Done_Face (unscaled->face);
185 unscaled->face = NULL;
186 unscaled->have_scale = FALSE;
188 font_map->num_open_faces--;
192 static cairo_status_t
193 _cairo_ft_unscaled_font_map_create (void)
195 cairo_ft_unscaled_font_map_t *font_map;
197 /* This function is only intended to be called from
198 * _cairo_ft_unscaled_font_map_lock. So we'll crash if we can
199 * detect some other call path. */
200 assert (cairo_ft_unscaled_font_map == NULL);
202 font_map = malloc (sizeof (cairo_ft_unscaled_font_map_t));
203 if (unlikely (font_map == NULL))
204 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
206 font_map->hash_table =
207 _cairo_hash_table_create (_cairo_ft_unscaled_font_keys_equal);
209 if (unlikely (font_map->hash_table == NULL))
210 goto FAIL;
212 if (unlikely (FT_Init_FreeType (&font_map->ft_library)))
213 goto FAIL;
215 font_map->num_open_faces = 0;
217 cairo_ft_unscaled_font_map = font_map;
218 return CAIRO_STATUS_SUCCESS;
220 FAIL:
221 if (font_map->hash_table)
222 _cairo_hash_table_destroy (font_map->hash_table);
223 free (font_map);
225 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
229 static void
230 _cairo_ft_unscaled_font_map_pluck_entry (void *entry, void *closure)
232 cairo_ft_unscaled_font_t *unscaled = entry;
233 cairo_ft_unscaled_font_map_t *font_map = closure;
235 _cairo_hash_table_remove (font_map->hash_table,
236 &unscaled->base.hash_entry);
238 if (! unscaled->from_face)
239 _font_map_release_face_lock_held (font_map, unscaled);
241 _cairo_ft_unscaled_font_fini (unscaled);
242 free (unscaled);
245 static void
246 _cairo_ft_unscaled_font_map_destroy (void)
248 cairo_ft_unscaled_font_map_t *font_map;
250 CAIRO_MUTEX_LOCK (_cairo_ft_unscaled_font_map_mutex);
251 font_map = cairo_ft_unscaled_font_map;
252 cairo_ft_unscaled_font_map = NULL;
253 CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex);
255 if (font_map != NULL) {
256 _cairo_hash_table_foreach (font_map->hash_table,
257 _cairo_ft_unscaled_font_map_pluck_entry,
258 font_map);
259 assert (font_map->num_open_faces == 0);
261 FT_Done_FreeType (font_map->ft_library);
263 _cairo_hash_table_destroy (font_map->hash_table);
265 free (font_map);
269 static cairo_ft_unscaled_font_map_t *
270 _cairo_ft_unscaled_font_map_lock (void)
272 CAIRO_MUTEX_LOCK (_cairo_ft_unscaled_font_map_mutex);
274 if (unlikely (cairo_ft_unscaled_font_map == NULL)) {
275 if (unlikely (_cairo_ft_unscaled_font_map_create ())) {
276 CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex);
277 return NULL;
281 return cairo_ft_unscaled_font_map;
284 static void
285 _cairo_ft_unscaled_font_map_unlock (void)
287 CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex);
290 static void
291 _cairo_ft_unscaled_font_init_key (cairo_ft_unscaled_font_t *key,
292 cairo_bool_t from_face,
293 char *filename,
294 int id,
295 FT_Face face)
297 unsigned long hash;
299 key->from_face = from_face;
300 key->filename = filename;
301 key->id = id;
302 key->face = face;
304 hash = _cairo_hash_string (filename);
305 /* the constants are just arbitrary primes */
306 hash += ((unsigned long) id) * 1607;
307 hash += ((unsigned long) face) * 2137;
309 key->base.hash_entry.hash = hash;
313 * _cairo_ft_unscaled_font_init:
315 * Initialize a #cairo_ft_unscaled_font_t.
317 * There are two basic flavors of #cairo_ft_unscaled_font_t, one
318 * created from an FT_Face and the other created from a filename/id
319 * pair. These two flavors are identified as from_face and !from_face.
321 * To initialize a from_face font, pass filename==%NULL, id=0 and the
322 * desired face.
324 * To initialize a !from_face font, pass the filename/id as desired
325 * and face==%NULL.
327 * Note that the code handles these two flavors in very distinct
328 * ways. For example there is a hash_table mapping
329 * filename/id->#cairo_unscaled_font_t in the !from_face case, but no
330 * parallel in the from_face case, (where the calling code would have
331 * to do its own mapping to ensure similar sharing).
333 static cairo_status_t
334 _cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled,
335 cairo_bool_t from_face,
336 const char *filename,
337 int id,
338 FT_Face face)
340 _cairo_unscaled_font_init (&unscaled->base,
341 &cairo_ft_unscaled_font_backend);
343 if (from_face) {
344 unscaled->from_face = TRUE;
345 _cairo_ft_unscaled_font_init_key (unscaled, TRUE, NULL, 0, face);
346 } else {
347 char *filename_copy;
349 unscaled->from_face = FALSE;
350 unscaled->face = NULL;
352 filename_copy = strdup (filename);
353 if (unlikely (filename_copy == NULL))
354 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
356 _cairo_ft_unscaled_font_init_key (unscaled, FALSE, filename_copy, id, NULL);
359 unscaled->have_scale = FALSE;
360 CAIRO_MUTEX_INIT (unscaled->mutex);
361 unscaled->lock_count = 0;
363 unscaled->faces = NULL;
365 return CAIRO_STATUS_SUCCESS;
369 * _cairo_ft_unscaled_font_fini:
371 * Free all data associated with a #cairo_ft_unscaled_font_t.
373 * CAUTION: The unscaled->face field must be %NULL before calling this
374 * function. This is because the #cairo_ft_unscaled_font_t_map keeps a
375 * count of these faces (font_map->num_open_faces) so it maintains the
376 * unscaled->face field while it has its lock held. See
377 * _font_map_release_face_lock_held().
379 static void
380 _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled)
382 assert (unscaled->face == NULL);
384 if (unscaled->filename) {
385 free (unscaled->filename);
386 unscaled->filename = NULL;
389 CAIRO_MUTEX_FINI (unscaled->mutex);
392 static int
393 _cairo_ft_unscaled_font_keys_equal (const void *key_a,
394 const void *key_b)
396 const cairo_ft_unscaled_font_t *unscaled_a = key_a;
397 const cairo_ft_unscaled_font_t *unscaled_b = key_b;
399 if (unscaled_a->id == unscaled_b->id &&
400 unscaled_a->from_face == unscaled_b->from_face)
402 if (unscaled_a->from_face)
403 return unscaled_a->face == unscaled_b->face;
405 if (unscaled_a->filename == NULL && unscaled_b->filename == NULL)
406 return TRUE;
407 else if (unscaled_a->filename == NULL || unscaled_b->filename == NULL)
408 return FALSE;
409 else
410 return (strcmp (unscaled_a->filename, unscaled_b->filename) == 0);
413 return FALSE;
416 /* Finds or creates a #cairo_ft_unscaled_font_t for the filename/id from
417 * pattern. Returns a new reference to the unscaled font.
419 static cairo_status_t
420 _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face,
421 char *filename,
422 int id,
423 FT_Face font_face,
424 cairo_ft_unscaled_font_t **out)
426 cairo_ft_unscaled_font_t key, *unscaled;
427 cairo_ft_unscaled_font_map_t *font_map;
428 cairo_status_t status;
430 font_map = _cairo_ft_unscaled_font_map_lock ();
431 if (unlikely (font_map == NULL))
432 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
434 _cairo_ft_unscaled_font_init_key (&key, from_face, filename, id, font_face);
436 /* Return existing unscaled font if it exists in the hash table. */
437 unscaled = _cairo_hash_table_lookup (font_map->hash_table,
438 &key.base.hash_entry);
439 if (unscaled != NULL) {
440 _cairo_unscaled_font_reference (&unscaled->base);
441 goto DONE;
444 /* Otherwise create it and insert into hash table. */
445 unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
446 if (unlikely (unscaled == NULL)) {
447 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
448 goto UNWIND_FONT_MAP_LOCK;
451 status = _cairo_ft_unscaled_font_init (unscaled, from_face, filename, id, font_face);
452 if (unlikely (status))
453 goto UNWIND_UNSCALED_MALLOC;
455 assert (unscaled->base.hash_entry.hash == key.base.hash_entry.hash);
456 status = _cairo_hash_table_insert (font_map->hash_table,
457 &unscaled->base.hash_entry);
458 if (unlikely (status))
459 goto UNWIND_UNSCALED_FONT_INIT;
461 DONE:
462 _cairo_ft_unscaled_font_map_unlock ();
463 *out = unscaled;
464 return CAIRO_STATUS_SUCCESS;
466 UNWIND_UNSCALED_FONT_INIT:
467 _cairo_ft_unscaled_font_fini (unscaled);
468 UNWIND_UNSCALED_MALLOC:
469 free (unscaled);
470 UNWIND_FONT_MAP_LOCK:
471 _cairo_ft_unscaled_font_map_unlock ();
472 return status;
476 #if CAIRO_HAS_FC_FONT
477 static cairo_status_t
478 _cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern,
479 cairo_ft_unscaled_font_t **out)
481 FT_Face font_face = NULL;
482 char *filename = NULL;
483 int id = 0;
484 FcResult ret;
486 ret = FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &font_face);
487 if (ret == FcResultMatch)
488 goto DONE;
489 if (ret == FcResultOutOfMemory)
490 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
492 ret = FcPatternGetString (pattern, FC_FILE, 0, (FcChar8 **) &filename);
493 if (ret == FcResultOutOfMemory)
494 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
495 if (ret == FcResultMatch) {
496 /* If FC_INDEX is not set, we just use 0 */
497 ret = FcPatternGetInteger (pattern, FC_INDEX, 0, &id);
498 if (ret == FcResultOutOfMemory)
499 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
501 goto DONE;
504 /* The pattern contains neither a face nor a filename, resolve it later. */
505 *out = NULL;
506 return CAIRO_STATUS_SUCCESS;
508 DONE:
509 return _cairo_ft_unscaled_font_create_internal (font_face != NULL,
510 filename, id, font_face,
511 out);
513 #endif
515 static cairo_status_t
516 _cairo_ft_unscaled_font_create_from_face (FT_Face face,
517 cairo_ft_unscaled_font_t **out)
519 return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, 0, face, out);
522 static void
523 _cairo_ft_unscaled_font_destroy (void *abstract_font)
525 cairo_ft_unscaled_font_t *unscaled = abstract_font;
526 cairo_ft_unscaled_font_map_t *font_map;
528 if (unscaled == NULL)
529 return;
531 font_map = _cairo_ft_unscaled_font_map_lock ();
532 /* All created objects must have been mapped in the font map. */
533 assert (font_map != NULL);
535 if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled->base.ref_count)) {
536 /* somebody recreated the font whilst we waited for the lock */
537 _cairo_ft_unscaled_font_map_unlock ();
538 return;
541 _cairo_hash_table_remove (font_map->hash_table,
542 &unscaled->base.hash_entry);
544 if (unscaled->from_face) {
545 /* See comments in _ft_font_face_destroy about the "zombie" state
546 * for a _ft_font_face.
548 if (unscaled->faces && unscaled->faces->unscaled == NULL) {
549 assert (unscaled->faces->next == NULL);
550 cairo_font_face_destroy (&unscaled->faces->base);
552 } else {
553 _font_map_release_face_lock_held (font_map, unscaled);
555 unscaled->face = NULL;
557 _cairo_ft_unscaled_font_map_unlock ();
559 _cairo_ft_unscaled_font_fini (unscaled);
562 static cairo_bool_t
563 _has_unlocked_face (const void *entry)
565 const cairo_ft_unscaled_font_t *unscaled = entry;
567 return (!unscaled->from_face && unscaled->lock_count == 0 && unscaled->face);
570 /* Ensures that an unscaled font has a face object. If we exceed
571 * MAX_OPEN_FACES, try to close some.
573 * This differs from _cairo_ft_scaled_font_lock_face in that it doesn't
574 * set the scale on the face, but just returns it at the last scale.
576 cairo_warn FT_Face
577 _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled)
579 cairo_ft_unscaled_font_map_t *font_map;
580 FT_Face face = NULL;
582 CAIRO_MUTEX_LOCK (unscaled->mutex);
583 unscaled->lock_count++;
585 if (unscaled->face)
586 return unscaled->face;
588 /* If this unscaled font was created from an FT_Face then we just
589 * returned it above. */
590 assert (!unscaled->from_face);
592 font_map = _cairo_ft_unscaled_font_map_lock ();
594 assert (font_map != NULL);
596 while (font_map->num_open_faces >= MAX_OPEN_FACES)
598 cairo_ft_unscaled_font_t *entry;
600 entry = _cairo_hash_table_random_entry (font_map->hash_table,
601 _has_unlocked_face);
602 if (entry == NULL)
603 break;
605 _font_map_release_face_lock_held (font_map, entry);
608 _cairo_ft_unscaled_font_map_unlock ();
610 if (FT_New_Face (font_map->ft_library,
611 unscaled->filename,
612 unscaled->id,
613 &face) != FT_Err_Ok)
615 unscaled->lock_count--;
616 CAIRO_MUTEX_UNLOCK (unscaled->mutex);
617 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
618 return NULL;
621 unscaled->face = face;
623 font_map->num_open_faces++;
625 return face;
629 /* Unlock unscaled font locked with _cairo_ft_unscaled_font_lock_face
631 void
632 _cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled)
634 assert (unscaled->lock_count > 0);
636 unscaled->lock_count--;
638 CAIRO_MUTEX_UNLOCK (unscaled->mutex);
642 static cairo_status_t
643 _compute_transform (cairo_ft_font_transform_t *sf,
644 cairo_matrix_t *scale)
646 cairo_status_t status;
647 double x_scale, y_scale;
648 cairo_matrix_t normalized = *scale;
650 /* The font matrix has x and y "scale" components which we extract and
651 * use as character scale values. These influence the way freetype
652 * chooses hints, as well as selecting different bitmaps in
653 * hand-rendered fonts. We also copy the normalized matrix to
654 * freetype's transformation.
657 status = _cairo_matrix_compute_basis_scale_factors (scale,
658 &x_scale, &y_scale,
660 if (unlikely (status))
661 return status;
663 /* FreeType docs say this about x_scale and y_scale:
664 * "A character width or height smaller than 1pt is set to 1pt;"
665 * So, we cap them from below at 1.0 and let the FT transform
666 * take care of sub-1.0 scaling. */
667 if (x_scale < 1.0)
668 x_scale = 1.0;
669 if (y_scale < 1.0)
670 y_scale = 1.0;
672 sf->x_scale = x_scale;
673 sf->y_scale = y_scale;
675 cairo_matrix_scale (&normalized, 1.0 / x_scale, 1.0 / y_scale);
677 _cairo_matrix_get_affine (&normalized,
678 &sf->shape[0][0], &sf->shape[0][1],
679 &sf->shape[1][0], &sf->shape[1][1],
680 NULL, NULL);
682 return CAIRO_STATUS_SUCCESS;
685 /* Temporarily scales an unscaled font to the give scale. We catch
686 * scaling to the same size, since changing a FT_Face is expensive.
688 static cairo_status_t
689 _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
690 cairo_matrix_t *scale)
692 cairo_status_t status;
693 cairo_ft_font_transform_t sf;
694 FT_Matrix mat;
695 FT_Error error;
697 assert (unscaled->face != NULL);
699 if (unscaled->have_scale &&
700 scale->xx == unscaled->current_scale.xx &&
701 scale->yx == unscaled->current_scale.yx &&
702 scale->xy == unscaled->current_scale.xy &&
703 scale->yy == unscaled->current_scale.yy)
704 return CAIRO_STATUS_SUCCESS;
706 unscaled->have_scale = TRUE;
707 unscaled->current_scale = *scale;
709 status = _compute_transform (&sf, scale);
710 if (unlikely (status))
711 return status;
713 unscaled->x_scale = sf.x_scale;
714 unscaled->y_scale = sf.y_scale;
716 mat.xx = DOUBLE_TO_16_16(sf.shape[0][0]);
717 mat.yx = - DOUBLE_TO_16_16(sf.shape[0][1]);
718 mat.xy = - DOUBLE_TO_16_16(sf.shape[1][0]);
719 mat.yy = DOUBLE_TO_16_16(sf.shape[1][1]);
721 unscaled->have_shape = (mat.xx != 0x10000 ||
722 mat.yx != 0x00000 ||
723 mat.xy != 0x00000 ||
724 mat.yy != 0x10000);
726 unscaled->Current_Shape = mat;
727 cairo_matrix_init (&unscaled->current_shape,
728 sf.shape[0][0], sf.shape[0][1],
729 sf.shape[1][0], sf.shape[1][1],
730 0.0, 0.0);
732 FT_Set_Transform(unscaled->face, &mat, NULL);
734 if ((unscaled->face->face_flags & FT_FACE_FLAG_SCALABLE) != 0) {
735 error = FT_Set_Char_Size (unscaled->face,
736 sf.x_scale * 64.0 + .5,
737 sf.y_scale * 64.0 + .5,
738 0, 0);
739 if (error)
740 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
741 } else {
742 double min_distance = DBL_MAX;
743 int i;
744 int best_i = 0;
746 for (i = 0; i < unscaled->face->num_fixed_sizes; i++) {
747 #if HAVE_FT_BITMAP_SIZE_Y_PPEM
748 double size = unscaled->face->available_sizes[i].y_ppem / 64.;
749 #else
750 double size = unscaled->face->available_sizes[i].height;
751 #endif
752 double distance = fabs (size - sf.y_scale);
754 if (distance <= min_distance) {
755 min_distance = distance;
756 best_i = i;
759 #if HAVE_FT_BITMAP_SIZE_Y_PPEM
760 error = FT_Set_Char_Size (unscaled->face,
761 unscaled->face->available_sizes[best_i].x_ppem,
762 unscaled->face->available_sizes[best_i].y_ppem,
763 0, 0);
764 if (error)
765 #endif
766 error = FT_Set_Pixel_Sizes (unscaled->face,
767 unscaled->face->available_sizes[best_i].width,
768 unscaled->face->available_sizes[best_i].height);
769 if (error)
770 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
773 return CAIRO_STATUS_SUCCESS;
776 /* Empirically-derived subpixel filtering values thanks to Keith
777 * Packard and libXft. */
778 static const int filters[3][3] = {
779 /* red */
780 #if 0
781 { 65538*4/7,65538*2/7,65538*1/7 },
782 /* green */
783 { 65536*1/4, 65536*2/4, 65537*1/4 },
784 /* blue */
785 { 65538*1/7,65538*2/7,65538*4/7 },
786 #endif
787 { 65538*9/13,65538*3/13,65538*1/13 },
788 /* green */
789 { 65538*1/6, 65538*4/6, 65538*1/6 },
790 /* blue */
791 { 65538*1/13,65538*3/13,65538*9/13 },
794 /* Fills in val->image with an image surface created from @bitmap
796 static cairo_status_t
797 _get_bitmap_surface (FT_Bitmap *bitmap,
798 cairo_bool_t own_buffer,
799 cairo_font_options_t *font_options,
800 cairo_image_surface_t **surface)
802 int width, height, stride;
803 unsigned char *data;
804 int format = CAIRO_FORMAT_A8;
805 cairo_bool_t subpixel = FALSE;
807 width = bitmap->width;
808 height = bitmap->rows;
810 if (width == 0 || height == 0) {
811 *surface = (cairo_image_surface_t *)
812 cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);
813 return (*surface)->base.status;
816 switch (bitmap->pixel_mode) {
817 case FT_PIXEL_MODE_MONO:
818 stride = (((width + 31) & ~31) >> 3);
819 if (own_buffer) {
820 data = bitmap->buffer;
821 assert (stride == bitmap->pitch);
822 } else {
823 data = _cairo_malloc_ab (height, stride);
824 if (!data)
825 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
827 if (stride == bitmap->pitch) {
828 memcpy (data, bitmap->buffer, stride * height);
829 } else {
830 int i;
831 unsigned char *source, *dest;
833 source = bitmap->buffer;
834 dest = data;
835 for (i = height; i; i--) {
836 memcpy (dest, source, bitmap->pitch);
837 memset (dest + bitmap->pitch, '\0', stride - bitmap->pitch);
839 source += bitmap->pitch;
840 dest += stride;
845 #ifndef WORDS_BIGENDIAN
847 uint8_t *d = data;
848 int count = stride * height;
850 while (count--) {
851 *d = CAIRO_BITSWAP8 (*d);
852 d++;
855 #endif
856 format = CAIRO_FORMAT_A1;
857 break;
859 case FT_PIXEL_MODE_LCD:
860 case FT_PIXEL_MODE_LCD_V:
861 case FT_PIXEL_MODE_GRAY:
862 switch (font_options->antialias) {
863 case CAIRO_ANTIALIAS_DEFAULT:
864 case CAIRO_ANTIALIAS_GRAY:
865 case CAIRO_ANTIALIAS_NONE:
866 default:
867 stride = bitmap->pitch;
868 if (own_buffer) {
869 data = bitmap->buffer;
870 } else {
871 data = _cairo_malloc_ab (height, stride);
872 if (!data)
873 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
875 memcpy (data, bitmap->buffer, stride * height);
877 format = CAIRO_FORMAT_A8;
878 break;
879 case CAIRO_ANTIALIAS_SUBPIXEL: {
880 int x, y;
881 unsigned char *in_line, *out_line, *in;
882 unsigned int *out;
883 unsigned int red, green, blue;
884 int rf, gf, bf;
885 int s;
886 int o, os;
887 unsigned char *data_rgba;
888 unsigned int width_rgba, stride_rgba;
889 int vmul = 1;
890 int hmul = 1;
892 switch (font_options->subpixel_order) {
893 case CAIRO_SUBPIXEL_ORDER_DEFAULT:
894 case CAIRO_SUBPIXEL_ORDER_RGB:
895 case CAIRO_SUBPIXEL_ORDER_BGR:
896 default:
897 width /= 3;
898 hmul = 3;
899 break;
900 case CAIRO_SUBPIXEL_ORDER_VRGB:
901 case CAIRO_SUBPIXEL_ORDER_VBGR:
902 vmul = 3;
903 height /= 3;
904 break;
907 * Filter the glyph to soften the color fringes
909 width_rgba = width;
910 stride = bitmap->pitch;
911 stride_rgba = (width_rgba * 4 + 3) & ~3;
912 data_rgba = calloc (stride_rgba, height);
913 if (unlikely (data_rgba == NULL)) {
914 if (own_buffer)
915 free (bitmap->buffer);
916 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
919 os = 1;
920 switch (font_options->subpixel_order) {
921 case CAIRO_SUBPIXEL_ORDER_VRGB:
922 os = stride;
923 case CAIRO_SUBPIXEL_ORDER_DEFAULT:
924 case CAIRO_SUBPIXEL_ORDER_RGB:
925 default:
926 rf = 0;
927 gf = 1;
928 bf = 2;
929 break;
930 case CAIRO_SUBPIXEL_ORDER_VBGR:
931 os = stride;
932 case CAIRO_SUBPIXEL_ORDER_BGR:
933 bf = 0;
934 gf = 1;
935 rf = 2;
936 break;
938 in_line = bitmap->buffer;
939 out_line = data_rgba;
940 for (y = 0; y < height; y++)
942 in = in_line;
943 out = (unsigned int *) out_line;
944 in_line += stride * vmul;
945 out_line += stride_rgba;
946 for (x = 0; x < width * hmul; x += hmul)
948 red = green = blue = 0;
949 o = 0;
950 for (s = 0; s < 3; s++)
952 red += filters[rf][s]*in[x+o];
953 green += filters[gf][s]*in[x+o];
954 blue += filters[bf][s]*in[x+o];
955 o += os;
957 red = red / 65536;
958 green = green / 65536;
959 blue = blue / 65536;
960 *out++ = (green << 24) | (red << 16) | (green << 8) | blue;
964 /* Images here are stored in native format. The
965 * backend must convert to its own format as needed
968 if (own_buffer)
969 free (bitmap->buffer);
970 data = data_rgba;
971 stride = stride_rgba;
972 format = CAIRO_FORMAT_ARGB32;
973 subpixel = TRUE;
974 break;
977 break;
978 case FT_PIXEL_MODE_GRAY2:
979 case FT_PIXEL_MODE_GRAY4:
980 /* These could be triggered by very rare types of TrueType fonts */
981 default:
982 if (own_buffer)
983 free (bitmap->buffer);
984 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
987 *surface = (cairo_image_surface_t *)
988 cairo_image_surface_create_for_data (data,
989 format,
990 width, height, stride);
991 if ((*surface)->base.status) {
992 free (data);
993 return (*surface)->base.status;
996 if (subpixel)
997 pixman_image_set_component_alpha ((*surface)->pixman_image, TRUE);
999 _cairo_image_surface_assume_ownership_of_data ((*surface));
1001 _cairo_debug_check_image_surface_is_defined (&(*surface)->base);
1003 return CAIRO_STATUS_SUCCESS;
1006 /* Converts an outline FT_GlyphSlot into an image
1008 * This could go through _render_glyph_bitmap as well, letting
1009 * FreeType convert the outline to a bitmap, but doing it ourselves
1010 * has two minor advantages: first, we save a copy of the bitmap
1011 * buffer: we can directly use the buffer that FreeType renders
1012 * into.
1014 * Second, it may help when we add support for subpixel
1015 * rendering: the Xft code does it this way. (Keith thinks that
1016 * it may also be possible to get the subpixel rendering with
1017 * FT_Render_Glyph: something worth looking into in more detail
1018 * when we add subpixel support. If so, we may want to eliminate
1019 * this version of the code path entirely.
1021 static cairo_status_t
1022 _render_glyph_outline (FT_Face face,
1023 cairo_font_options_t *font_options,
1024 cairo_image_surface_t **surface)
1026 FT_GlyphSlot glyphslot = face->glyph;
1027 FT_Outline *outline = &glyphslot->outline;
1028 FT_Bitmap bitmap;
1029 FT_BBox cbox;
1030 FT_Matrix matrix;
1031 int hmul = 1;
1032 int vmul = 1;
1033 unsigned int width, height, stride;
1034 cairo_bool_t subpixel = FALSE;
1035 cairo_status_t status;
1037 FT_Outline_Get_CBox (outline, &cbox);
1039 cbox.xMin &= -64;
1040 cbox.yMin &= -64;
1041 cbox.xMax = (cbox.xMax + 63) & -64;
1042 cbox.yMax = (cbox.yMax + 63) & -64;
1044 width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6);
1045 height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6);
1046 stride = (width * hmul + 3) & ~3;
1048 if (width * height == 0) {
1049 cairo_format_t format;
1050 /* Looks like fb handles zero-sized images just fine */
1051 switch (font_options->antialias) {
1052 case CAIRO_ANTIALIAS_NONE:
1053 format = CAIRO_FORMAT_A1;
1054 break;
1055 case CAIRO_ANTIALIAS_SUBPIXEL:
1056 format= CAIRO_FORMAT_ARGB32;
1057 break;
1058 case CAIRO_ANTIALIAS_DEFAULT:
1059 case CAIRO_ANTIALIAS_GRAY:
1060 default:
1061 format = CAIRO_FORMAT_A8;
1062 break;
1065 (*surface) = (cairo_image_surface_t *)
1066 cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);
1067 if ((*surface)->base.status)
1068 return (*surface)->base.status;
1069 } else {
1071 matrix.xx = matrix.yy = 0x10000L;
1072 matrix.xy = matrix.yx = 0;
1074 switch (font_options->antialias) {
1075 case CAIRO_ANTIALIAS_NONE:
1076 bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
1077 bitmap.num_grays = 1;
1078 stride = ((width + 31) & -32) >> 3;
1079 break;
1080 case CAIRO_ANTIALIAS_DEFAULT:
1081 case CAIRO_ANTIALIAS_GRAY:
1082 bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
1083 bitmap.num_grays = 256;
1084 stride = (width + 3) & -4;
1085 break;
1086 case CAIRO_ANTIALIAS_SUBPIXEL:
1087 switch (font_options->subpixel_order) {
1088 case CAIRO_SUBPIXEL_ORDER_RGB:
1089 case CAIRO_SUBPIXEL_ORDER_BGR:
1090 case CAIRO_SUBPIXEL_ORDER_DEFAULT:
1091 default:
1092 matrix.xx *= 3;
1093 hmul = 3;
1094 subpixel = TRUE;
1095 break;
1096 case CAIRO_SUBPIXEL_ORDER_VRGB:
1097 case CAIRO_SUBPIXEL_ORDER_VBGR:
1098 matrix.yy *= 3;
1099 vmul = 3;
1100 subpixel = TRUE;
1101 break;
1103 FT_Outline_Transform (outline, &matrix);
1105 bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
1106 bitmap.num_grays = 256;
1107 stride = (width * hmul + 3) & -4;
1110 bitmap.pitch = stride;
1111 bitmap.width = width * hmul;
1112 bitmap.rows = height * vmul;
1113 bitmap.buffer = calloc (stride, bitmap.rows);
1114 if (unlikely (bitmap.buffer == NULL))
1115 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1117 FT_Outline_Translate (outline, -cbox.xMin*hmul, -cbox.yMin*vmul);
1119 if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) {
1120 free (bitmap.buffer);
1121 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1124 status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);
1125 if (unlikely (status))
1126 return status;
1130 * Note: the font's coordinate system is upside down from ours, so the
1131 * Y coordinate of the control box needs to be negated. Moreover, device
1132 * offsets are position of glyph origin relative to top left while xMin
1133 * and yMax are offsets of top left relative to origin. Another negation.
1135 cairo_surface_set_device_offset (&(*surface)->base,
1136 floor (-(double) cbox.xMin / 64.0),
1137 floor (+(double) cbox.yMax / 64.0));
1139 return CAIRO_STATUS_SUCCESS;
1142 /* Converts a bitmap (or other) FT_GlyphSlot into an image */
1143 static cairo_status_t
1144 _render_glyph_bitmap (FT_Face face,
1145 cairo_font_options_t *font_options,
1146 cairo_image_surface_t **surface)
1148 FT_GlyphSlot glyphslot = face->glyph;
1149 cairo_status_t status = CAIRO_STATUS_SUCCESS;
1150 FT_Error error;
1152 /* According to the FreeType docs, glyphslot->format could be
1153 * something other than FT_GLYPH_FORMAT_OUTLINE or
1154 * FT_GLYPH_FORMAT_BITMAP. Calling FT_Render_Glyph gives FreeType
1155 * the opportunity to convert such to
1156 * bitmap. FT_GLYPH_FORMAT_COMPOSITE will not be encountered since
1157 * we avoid the FT_LOAD_NO_RECURSE flag.
1159 error = FT_Render_Glyph (glyphslot, FT_RENDER_MODE_NORMAL);
1160 /* XXX ignoring all other errors for now. They are not fatal, typically
1161 * just a glyph-not-found. */
1162 if (error == FT_Err_Out_Of_Memory)
1163 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1165 status = _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface);
1166 if (unlikely (status))
1167 return status;
1170 * Note: the font's coordinate system is upside down from ours, so the
1171 * Y coordinate of the control box needs to be negated. Moreover, device
1172 * offsets are position of glyph origin relative to top left while
1173 * bitmap_left and bitmap_top are offsets of top left relative to origin.
1174 * Another negation.
1176 cairo_surface_set_device_offset (&(*surface)->base,
1177 -glyphslot->bitmap_left,
1178 +glyphslot->bitmap_top);
1180 return status;
1183 static cairo_status_t
1184 _transform_glyph_bitmap (cairo_matrix_t * shape,
1185 cairo_image_surface_t ** surface)
1187 cairo_matrix_t original_to_transformed;
1188 cairo_matrix_t transformed_to_original;
1189 cairo_image_surface_t *old_image;
1190 cairo_surface_t *image;
1191 double x[4], y[4];
1192 double origin_x, origin_y;
1193 int orig_width, orig_height;
1194 int i;
1195 int x_min, y_min, x_max, y_max;
1196 int width, height;
1197 cairo_status_t status;
1198 cairo_surface_pattern_t pattern;
1200 /* We want to compute a transform that takes the origin
1201 * (device_x_offset, device_y_offset) to 0,0, then applies
1202 * the "shape" portion of the font transform
1204 original_to_transformed = *shape;
1206 cairo_surface_get_device_offset (&(*surface)->base, &origin_x, &origin_y);
1207 orig_width = cairo_image_surface_get_width (&(*surface)->base);
1208 orig_height = cairo_image_surface_get_height (&(*surface)->base);
1210 cairo_matrix_translate (&original_to_transformed,
1211 -origin_x, -origin_y);
1213 /* Find the bounding box of the original bitmap under that
1214 * transform
1216 x[0] = 0; y[0] = 0;
1217 x[1] = orig_width; y[1] = 0;
1218 x[2] = orig_width; y[2] = orig_height;
1219 x[3] = 0; y[3] = orig_height;
1221 for (i = 0; i < 4; i++)
1222 cairo_matrix_transform_point (&original_to_transformed,
1223 &x[i], &y[i]);
1225 x_min = floor (x[0]); y_min = floor (y[0]);
1226 x_max = ceil (x[0]); y_max = ceil (y[0]);
1228 for (i = 1; i < 4; i++) {
1229 if (x[i] < x_min)
1230 x_min = floor (x[i]);
1231 else if (x[i] > x_max)
1232 x_max = ceil (x[i]);
1233 if (y[i] < y_min)
1234 y_min = floor (y[i]);
1235 else if (y[i] > y_max)
1236 y_max = ceil (y[i]);
1239 /* Adjust the transform so that the bounding box starts at 0,0 ...
1240 * this gives our final transform from original bitmap to transformed
1241 * bitmap.
1243 original_to_transformed.x0 -= x_min;
1244 original_to_transformed.y0 -= y_min;
1246 /* Create the transformed bitmap
1248 width = x_max - x_min;
1249 height = y_max - y_min;
1251 transformed_to_original = original_to_transformed;
1252 status = cairo_matrix_invert (&transformed_to_original);
1253 if (unlikely (status))
1254 return status;
1256 /* We need to pad out the width to 32-bit intervals for cairo-xlib-surface.c */
1257 width = (width + 3) & ~3;
1258 image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
1259 if (unlikely (image->status))
1260 return image->status;
1262 /* Initialize it to empty
1264 status = _cairo_surface_fill_rectangle (image, CAIRO_OPERATOR_CLEAR,
1265 CAIRO_COLOR_TRANSPARENT,
1266 0, 0,
1267 width, height);
1268 if (unlikely (status)) {
1269 cairo_surface_destroy (image);
1270 return status;
1273 /* Draw the original bitmap transformed into the new bitmap
1275 _cairo_pattern_init_for_surface (&pattern, &(*surface)->base);
1276 cairo_pattern_set_matrix (&pattern.base, &transformed_to_original);
1278 status = _cairo_surface_composite (CAIRO_OPERATOR_OVER,
1279 &pattern.base, NULL, image,
1280 0, 0, 0, 0, 0, 0,
1281 width,
1282 height);
1284 _cairo_pattern_fini (&pattern.base);
1286 if (unlikely (status)) {
1287 cairo_surface_destroy (image);
1288 return status;
1291 /* Now update the cache entry for the new bitmap, recomputing
1292 * the origin based on the final transform.
1294 cairo_matrix_transform_point (&original_to_transformed,
1295 &origin_x, &origin_y);
1297 old_image = (*surface);
1298 (*surface) = (cairo_image_surface_t *)image;
1299 cairo_surface_destroy (&old_image->base);
1301 cairo_surface_set_device_offset (&(*surface)->base,
1302 _cairo_lround (origin_x),
1303 _cairo_lround (origin_y));
1304 return status;
1307 static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend = {
1308 _cairo_ft_unscaled_font_destroy,
1309 #if 0
1310 _cairo_ft_unscaled_font_create_glyph
1311 #endif
1314 /* #cairo_ft_scaled_font_t */
1316 typedef struct _cairo_ft_scaled_font {
1317 cairo_scaled_font_t base;
1318 cairo_ft_unscaled_font_t *unscaled;
1319 cairo_ft_options_t ft_options;
1320 } cairo_ft_scaled_font_t;
1322 static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend;
1324 #if CAIRO_HAS_FC_FONT
1325 /* The load flags passed to FT_Load_Glyph control aspects like hinting and
1326 * antialiasing. Here we compute them from the fields of a FcPattern.
1328 static void
1329 _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
1331 FcBool antialias, vertical_layout, hinting, autohint, bitmap, embolden;
1332 cairo_ft_options_t ft_options;
1333 int rgba;
1334 #ifdef FC_HINT_STYLE
1335 int hintstyle;
1336 #endif
1338 _cairo_font_options_init_default (&ft_options.base);
1339 ft_options.load_flags = FT_LOAD_DEFAULT;
1340 ft_options.extra_flags = 0;
1342 #ifndef FC_EMBEDDED_BITMAP
1343 #define FC_EMBEDDED_BITMAP "embeddedbitmap"
1344 #endif
1346 /* Check whether to force use of embedded bitmaps */
1347 if (FcPatternGetBool (pattern,
1348 FC_EMBEDDED_BITMAP, 0, &bitmap) != FcResultMatch)
1349 bitmap = FcFalse;
1351 /* disable antialiasing if requested */
1352 if (FcPatternGetBool (pattern,
1353 FC_ANTIALIAS, 0, &antialias) != FcResultMatch)
1354 antialias = FcTrue;
1356 if (antialias) {
1357 cairo_subpixel_order_t subpixel_order;
1359 /* disable hinting if requested */
1360 if (FcPatternGetBool (pattern,
1361 FC_HINTING, 0, &hinting) != FcResultMatch)
1362 hinting = FcTrue;
1364 if (FcPatternGetInteger (pattern,
1365 FC_RGBA, 0, &rgba) != FcResultMatch)
1366 rgba = FC_RGBA_UNKNOWN;
1368 switch (rgba) {
1369 case FC_RGBA_RGB:
1370 subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB;
1371 break;
1372 case FC_RGBA_BGR:
1373 subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR;
1374 break;
1375 case FC_RGBA_VRGB:
1376 subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB;
1377 break;
1378 case FC_RGBA_VBGR:
1379 subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR;
1380 break;
1381 case FC_RGBA_UNKNOWN:
1382 case FC_RGBA_NONE:
1383 default:
1384 subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
1385 break;
1388 if (subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT) {
1389 ft_options.base.subpixel_order = subpixel_order;
1390 ft_options.base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;
1393 #ifdef FC_HINT_STYLE
1394 if (FcPatternGetInteger (pattern,
1395 FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch)
1396 hintstyle = FC_HINT_FULL;
1398 if (!hinting)
1399 hintstyle = FC_HINT_NONE;
1401 switch (hintstyle) {
1402 case FC_HINT_NONE:
1403 ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE;
1404 break;
1405 case FC_HINT_SLIGHT:
1406 ft_options.base.hint_style = CAIRO_HINT_STYLE_SLIGHT;
1407 break;
1408 case FC_HINT_MEDIUM:
1409 default:
1410 ft_options.base.hint_style = CAIRO_HINT_STYLE_MEDIUM;
1411 break;
1412 case FC_HINT_FULL:
1413 ft_options.base.hint_style = CAIRO_HINT_STYLE_FULL;
1414 break;
1416 #else /* !FC_HINT_STYLE */
1417 if (!hinting) {
1418 ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE;
1420 #endif /* FC_HINT_STYLE */
1422 /* Force embedded bitmaps off if no hinting requested */
1423 if (ft_options.base.hint_style == CAIRO_HINT_STYLE_NONE)
1424 bitmap = FcFalse;
1426 if (!bitmap)
1427 ft_options.load_flags |= FT_LOAD_NO_BITMAP;
1429 } else {
1430 ft_options.base.antialias = CAIRO_ANTIALIAS_NONE;
1433 /* force autohinting if requested */
1434 if (FcPatternGetBool (pattern,
1435 FC_AUTOHINT, 0, &autohint) != FcResultMatch)
1436 autohint = FcFalse;
1438 if (autohint)
1439 ft_options.load_flags |= FT_LOAD_FORCE_AUTOHINT;
1441 if (FcPatternGetBool (pattern,
1442 FC_VERTICAL_LAYOUT, 0, &vertical_layout) != FcResultMatch)
1443 vertical_layout = FcFalse;
1445 if (vertical_layout)
1446 ft_options.load_flags |= FT_LOAD_VERTICAL_LAYOUT;
1448 #ifndef FC_EMBOLDEN
1449 #define FC_EMBOLDEN "embolden"
1450 #endif
1451 if (FcPatternGetBool (pattern,
1452 FC_EMBOLDEN, 0, &embolden) != FcResultMatch)
1453 embolden = FcFalse;
1455 if (embolden)
1456 ft_options.extra_flags |= CAIRO_FT_OPTIONS_EMBOLDEN;
1458 *ret = ft_options;
1460 #endif
1462 static void
1463 _cairo_ft_options_merge (cairo_ft_options_t *options,
1464 cairo_ft_options_t *other)
1466 int load_flags = other->load_flags;
1467 int load_target = FT_LOAD_TARGET_NORMAL;
1469 /* clear load target mode */
1470 load_flags &= ~(FT_LOAD_TARGET_(FT_LOAD_TARGET_MODE(other->load_flags)));
1472 if (load_flags & FT_LOAD_NO_HINTING)
1473 other->base.hint_style = CAIRO_HINT_STYLE_NONE;
1475 if (other->base.antialias == CAIRO_ANTIALIAS_NONE ||
1476 options->base.antialias == CAIRO_ANTIALIAS_NONE) {
1477 options->base.antialias = CAIRO_ANTIALIAS_NONE;
1478 options->base.subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
1481 if (other->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL &&
1482 (options->base.antialias == CAIRO_ANTIALIAS_DEFAULT ||
1483 options->base.antialias == CAIRO_ANTIALIAS_GRAY)) {
1484 options->base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;
1485 options->base.subpixel_order = other->base.subpixel_order;
1488 if (options->base.hint_style == CAIRO_HINT_STYLE_DEFAULT)
1489 options->base.hint_style = other->base.hint_style;
1491 if (other->base.hint_style == CAIRO_HINT_STYLE_NONE)
1492 options->base.hint_style = CAIRO_HINT_STYLE_NONE;
1494 if (options->base.antialias == CAIRO_ANTIALIAS_NONE) {
1495 if (options->base.hint_style == CAIRO_HINT_STYLE_NONE)
1496 load_flags |= FT_LOAD_NO_HINTING;
1497 else
1498 load_target = FT_LOAD_TARGET_MONO;
1499 load_flags |= FT_LOAD_MONOCHROME;
1500 } else {
1501 switch (options->base.hint_style) {
1502 case CAIRO_HINT_STYLE_NONE:
1503 load_flags |= FT_LOAD_NO_HINTING;
1504 break;
1505 case CAIRO_HINT_STYLE_SLIGHT:
1506 load_target = FT_LOAD_TARGET_LIGHT;
1507 break;
1508 case CAIRO_HINT_STYLE_MEDIUM:
1509 break;
1510 case CAIRO_HINT_STYLE_FULL:
1511 case CAIRO_HINT_STYLE_DEFAULT:
1512 if (options->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL) {
1513 switch (options->base.subpixel_order) {
1514 case CAIRO_SUBPIXEL_ORDER_DEFAULT:
1515 case CAIRO_SUBPIXEL_ORDER_RGB:
1516 case CAIRO_SUBPIXEL_ORDER_BGR:
1517 load_target |= FT_LOAD_TARGET_LCD;
1518 break;
1519 case CAIRO_SUBPIXEL_ORDER_VRGB:
1520 case CAIRO_SUBPIXEL_ORDER_VBGR:
1521 load_target |= FT_LOAD_TARGET_LCD_V;
1522 break;
1525 break;
1529 options->load_flags = load_flags | load_target;
1530 options->extra_flags = other->extra_flags;
1531 if (options->base.hint_metrics != CAIRO_HINT_METRICS_OFF)
1532 options->extra_flags |= CAIRO_FT_OPTIONS_HINT_METRICS;
1535 static cairo_status_t
1536 _cairo_ft_font_face_scaled_font_create (void *abstract_font_face,
1537 const cairo_matrix_t *font_matrix,
1538 const cairo_matrix_t *ctm,
1539 const cairo_font_options_t *options,
1540 cairo_scaled_font_t **font_out)
1542 cairo_ft_font_face_t *font_face = abstract_font_face;
1543 cairo_ft_scaled_font_t *scaled_font;
1544 FT_Face face;
1545 FT_Size_Metrics *metrics;
1546 cairo_font_extents_t fs_metrics;
1547 cairo_status_t status;
1548 cairo_ft_unscaled_font_t *unscaled;
1550 assert (font_face->unscaled);
1552 face = _cairo_ft_unscaled_font_lock_face (font_face->unscaled);
1553 if (unlikely (face == NULL)) /* backend error */
1554 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1556 scaled_font = malloc (sizeof (cairo_ft_scaled_font_t));
1557 if (unlikely (scaled_font == NULL)) {
1558 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1559 goto FAIL;
1562 scaled_font->unscaled = unscaled = font_face->unscaled;
1563 _cairo_unscaled_font_reference (&unscaled->base);
1565 _cairo_font_options_init_copy (&scaled_font->ft_options.base, options);
1566 _cairo_ft_options_merge (&scaled_font->ft_options, &font_face->ft_options);
1568 status = _cairo_scaled_font_init (&scaled_font->base,
1569 &font_face->base,
1570 font_matrix, ctm, options,
1571 &_cairo_ft_scaled_font_backend);
1572 if (unlikely (status))
1573 goto CLEANUP_SCALED_FONT;
1575 status = _cairo_ft_unscaled_font_set_scale (unscaled,
1576 &scaled_font->base.scale);
1577 if (unlikely (status)) {
1578 /* This can only fail if we encounter an error with the underlying
1579 * font, so propagate the error back to the font-face. */
1580 _cairo_ft_unscaled_font_unlock_face (unscaled);
1581 _cairo_unscaled_font_destroy (&unscaled->base);
1582 free (scaled_font);
1583 return status;
1587 metrics = &face->size->metrics;
1590 * Get to unscaled metrics so that the upper level can get back to
1591 * user space
1593 * Also use this path for bitmap-only fonts. The other branch uses
1594 * face members that are only relevant for scalable fonts. This is
1595 * detected by simply checking for units_per_EM==0.
1597 if (scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF ||
1598 face->units_per_EM == 0) {
1599 double x_factor, y_factor;
1601 if (unscaled->x_scale == 0)
1602 x_factor = 0;
1603 else
1604 x_factor = 1 / unscaled->x_scale;
1606 if (unscaled->y_scale == 0)
1607 y_factor = 0;
1608 else
1609 y_factor = 1 / unscaled->y_scale;
1611 fs_metrics.ascent = DOUBLE_FROM_26_6(metrics->ascender) * y_factor;
1612 fs_metrics.descent = DOUBLE_FROM_26_6(- metrics->descender) * y_factor;
1613 fs_metrics.height = DOUBLE_FROM_26_6(metrics->height) * y_factor;
1614 if (!_cairo_ft_scaled_font_is_vertical (&scaled_font->base)) {
1615 fs_metrics.max_x_advance = DOUBLE_FROM_26_6(metrics->max_advance) * x_factor;
1616 fs_metrics.max_y_advance = 0;
1617 } else {
1618 fs_metrics.max_x_advance = 0;
1619 fs_metrics.max_y_advance = DOUBLE_FROM_26_6(metrics->max_advance) * y_factor;
1621 } else {
1622 double scale = face->units_per_EM;
1624 fs_metrics.ascent = face->ascender / scale;
1625 fs_metrics.descent = - face->descender / scale;
1626 fs_metrics.height = face->height / scale;
1627 if (!_cairo_ft_scaled_font_is_vertical (&scaled_font->base)) {
1628 fs_metrics.max_x_advance = face->max_advance_width / scale;
1629 fs_metrics.max_y_advance = 0;
1630 } else {
1631 fs_metrics.max_x_advance = 0;
1632 fs_metrics.max_y_advance = face->max_advance_height / scale;
1636 status = _cairo_scaled_font_set_metrics (&scaled_font->base, &fs_metrics);
1637 if (unlikely (status))
1638 goto CLEANUP_SCALED_FONT;
1640 _cairo_ft_unscaled_font_unlock_face (unscaled);
1642 *font_out = &scaled_font->base;
1643 return CAIRO_STATUS_SUCCESS;
1645 CLEANUP_SCALED_FONT:
1646 _cairo_unscaled_font_destroy (&unscaled->base);
1647 free (scaled_font);
1648 FAIL:
1649 _cairo_ft_unscaled_font_unlock_face (font_face->unscaled);
1650 *font_out = _cairo_scaled_font_create_in_error (status);
1651 return CAIRO_STATUS_SUCCESS; /* non-backend error */
1654 cairo_bool_t
1655 _cairo_scaled_font_is_ft (cairo_scaled_font_t *scaled_font)
1657 return scaled_font->backend == &_cairo_ft_scaled_font_backend;
1660 static void
1661 _cairo_ft_scaled_font_fini (void *abstract_font)
1663 cairo_ft_scaled_font_t *scaled_font = abstract_font;
1665 if (scaled_font == NULL)
1666 return;
1668 _cairo_unscaled_font_destroy (&scaled_font->unscaled->base);
1671 static int
1672 _move_to (FT_Vector *to, void *closure)
1674 cairo_path_fixed_t *path = closure;
1675 cairo_fixed_t x, y;
1677 x = _cairo_fixed_from_26_6 (to->x);
1678 y = _cairo_fixed_from_26_6 (to->y);
1680 if (_cairo_path_fixed_close_path (path) != CAIRO_STATUS_SUCCESS)
1681 return 1;
1682 if (_cairo_path_fixed_move_to (path, x, y) != CAIRO_STATUS_SUCCESS)
1683 return 1;
1685 return 0;
1688 static int
1689 _line_to (FT_Vector *to, void *closure)
1691 cairo_path_fixed_t *path = closure;
1692 cairo_fixed_t x, y;
1694 x = _cairo_fixed_from_26_6 (to->x);
1695 y = _cairo_fixed_from_26_6 (to->y);
1697 if (_cairo_path_fixed_line_to (path, x, y) != CAIRO_STATUS_SUCCESS)
1698 return 1;
1700 return 0;
1703 static int
1704 _conic_to (FT_Vector *control, FT_Vector *to, void *closure)
1706 cairo_path_fixed_t *path = closure;
1708 cairo_fixed_t x0, y0;
1709 cairo_fixed_t x1, y1;
1710 cairo_fixed_t x2, y2;
1711 cairo_fixed_t x3, y3;
1712 cairo_point_t conic;
1714 if (! _cairo_path_fixed_get_current_point (path, &x0, &y0))
1715 return 1;
1717 conic.x = _cairo_fixed_from_26_6 (control->x);
1718 conic.y = _cairo_fixed_from_26_6 (control->y);
1720 x3 = _cairo_fixed_from_26_6 (to->x);
1721 y3 = _cairo_fixed_from_26_6 (to->y);
1723 x1 = x0 + 2.0/3.0 * (conic.x - x0);
1724 y1 = y0 + 2.0/3.0 * (conic.y - y0);
1726 x2 = x3 + 2.0/3.0 * (conic.x - x3);
1727 y2 = y3 + 2.0/3.0 * (conic.y - y3);
1729 if (_cairo_path_fixed_curve_to (path,
1730 x1, y1,
1731 x2, y2,
1732 x3, y3) != CAIRO_STATUS_SUCCESS)
1733 return 1;
1735 return 0;
1738 static int
1739 _cubic_to (FT_Vector *control1, FT_Vector *control2,
1740 FT_Vector *to, void *closure)
1742 cairo_path_fixed_t *path = closure;
1743 cairo_fixed_t x0, y0;
1744 cairo_fixed_t x1, y1;
1745 cairo_fixed_t x2, y2;
1747 x0 = _cairo_fixed_from_26_6 (control1->x);
1748 y0 = _cairo_fixed_from_26_6 (control1->y);
1750 x1 = _cairo_fixed_from_26_6 (control2->x);
1751 y1 = _cairo_fixed_from_26_6 (control2->y);
1753 x2 = _cairo_fixed_from_26_6 (to->x);
1754 y2 = _cairo_fixed_from_26_6 (to->y);
1756 if (_cairo_path_fixed_curve_to (path,
1757 x0, y0,
1758 x1, y1,
1759 x2, y2) != CAIRO_STATUS_SUCCESS)
1760 return 1;
1762 return 0;
1765 static cairo_status_t
1766 _decompose_glyph_outline (FT_Face face,
1767 cairo_font_options_t *options,
1768 cairo_path_fixed_t **pathp)
1770 static const FT_Outline_Funcs outline_funcs = {
1771 (FT_Outline_MoveToFunc)_move_to,
1772 (FT_Outline_LineToFunc)_line_to,
1773 (FT_Outline_ConicToFunc)_conic_to,
1774 (FT_Outline_CubicToFunc)_cubic_to,
1775 0, /* shift */
1776 0, /* delta */
1778 static const FT_Matrix invert_y = {
1779 DOUBLE_TO_16_16 (1.0), 0,
1780 0, DOUBLE_TO_16_16 (-1.0),
1783 FT_GlyphSlot glyph;
1784 cairo_path_fixed_t *path;
1785 cairo_status_t status;
1787 path = _cairo_path_fixed_create ();
1788 if (!path)
1789 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1791 glyph = face->glyph;
1793 /* Font glyphs have an inverted Y axis compared to cairo. */
1794 FT_Outline_Transform (&glyph->outline, &invert_y);
1795 if (FT_Outline_Decompose (&glyph->outline, &outline_funcs, path)) {
1796 _cairo_path_fixed_destroy (path);
1797 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1800 status = _cairo_path_fixed_close_path (path);
1801 if (unlikely (status)) {
1802 _cairo_path_fixed_destroy (path);
1803 return status;
1806 *pathp = path;
1808 return CAIRO_STATUS_SUCCESS;
1812 * Translate glyph to match its metrics.
1814 static void
1815 _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (void *abstract_font,
1816 FT_GlyphSlot glyph)
1818 cairo_ft_scaled_font_t *scaled_font = abstract_font;
1819 FT_Vector vector;
1821 vector.x = glyph->metrics.vertBearingX - glyph->metrics.horiBearingX;
1822 vector.y = -glyph->metrics.vertBearingY - glyph->metrics.horiBearingY;
1824 if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
1825 FT_Vector_Transform (&vector, &scaled_font->unscaled->Current_Shape);
1826 FT_Outline_Translate(&glyph->outline, vector.x, vector.y);
1827 } else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
1828 glyph->bitmap_left += vector.x / 64;
1829 glyph->bitmap_top += vector.y / 64;
1833 static cairo_int_status_t
1834 _cairo_ft_scaled_glyph_init (void *abstract_font,
1835 cairo_scaled_glyph_t *scaled_glyph,
1836 cairo_scaled_glyph_info_t info)
1838 cairo_text_extents_t fs_metrics;
1839 cairo_ft_scaled_font_t *scaled_font = abstract_font;
1840 cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
1841 FT_GlyphSlot glyph;
1842 FT_Face face;
1843 FT_Error error;
1844 int load_flags = scaled_font->ft_options.load_flags;
1845 FT_Glyph_Metrics *metrics;
1846 double x_factor, y_factor;
1847 cairo_bool_t vertical_layout = FALSE;
1848 cairo_status_t status;
1850 face = _cairo_ft_unscaled_font_lock_face (unscaled);
1851 if (!face)
1852 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1854 status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
1855 &scaled_font->base.scale);
1856 if (unlikely (status))
1857 goto FAIL;
1859 /* Ignore global advance unconditionally */
1860 load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
1862 if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0 &&
1863 (info & CAIRO_SCALED_GLYPH_INFO_SURFACE) == 0)
1864 load_flags |= FT_LOAD_NO_BITMAP;
1867 * Don't pass FT_LOAD_VERTICAL_LAYOUT to FT_Load_Glyph here as
1868 * suggested by freetype people.
1870 if (load_flags & FT_LOAD_VERTICAL_LAYOUT) {
1871 load_flags &= ~FT_LOAD_VERTICAL_LAYOUT;
1872 vertical_layout = TRUE;
1875 error = FT_Load_Glyph (scaled_font->unscaled->face,
1876 _cairo_scaled_glyph_index(scaled_glyph),
1877 load_flags);
1878 /* XXX ignoring all other errors for now. They are not fatal, typically
1879 * just a glyph-not-found. */
1880 if (error == FT_Err_Out_Of_Memory) {
1881 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1882 goto FAIL;
1885 glyph = face->glyph;
1887 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
1889 * embolden glyphs if requested
1891 if (scaled_font->ft_options.extra_flags & CAIRO_FT_OPTIONS_EMBOLDEN)
1892 FT_GlyphSlot_Embolden (glyph);
1893 #endif
1895 if (vertical_layout)
1896 _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, glyph);
1898 if (info & CAIRO_SCALED_GLYPH_INFO_METRICS) {
1900 cairo_bool_t hint_metrics = scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF;
1902 * Compute font-space metrics
1904 metrics = &glyph->metrics;
1906 if (unscaled->x_scale == 0)
1907 x_factor = 0;
1908 else
1909 x_factor = 1 / unscaled->x_scale;
1911 if (unscaled->y_scale == 0)
1912 y_factor = 0;
1913 else
1914 y_factor = 1 / unscaled->y_scale;
1917 * Note: Y coordinates of the horizontal bearing need to be negated.
1919 * Scale metrics back to glyph space from the scaled glyph space returned
1920 * by FreeType
1922 * If we want hinted metrics but aren't asking for hinted glyphs from
1923 * FreeType, then we need to do the metric hinting ourselves.
1926 if (hint_metrics && (load_flags & FT_LOAD_NO_HINTING))
1928 FT_Pos x1, x2;
1929 FT_Pos y1, y2;
1930 FT_Pos advance;
1932 if (!vertical_layout) {
1933 x1 = (metrics->horiBearingX) & -64;
1934 x2 = (metrics->horiBearingX + metrics->width + 63) & -64;
1935 y1 = (-metrics->horiBearingY) & -64;
1936 y2 = (-metrics->horiBearingY + metrics->height + 63) & -64;
1938 advance = ((metrics->horiAdvance + 32) & -64);
1940 fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor;
1941 fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor;
1943 fs_metrics.width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;
1944 fs_metrics.height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;
1946 fs_metrics.x_advance = DOUBLE_FROM_26_6 (advance) * x_factor;
1947 fs_metrics.y_advance = 0;
1948 } else {
1949 x1 = (metrics->vertBearingX) & -64;
1950 x2 = (metrics->vertBearingX + metrics->width + 63) & -64;
1951 y1 = (metrics->vertBearingY) & -64;
1952 y2 = (metrics->vertBearingY + metrics->height + 63) & -64;
1954 advance = ((metrics->vertAdvance + 32) & -64);
1956 fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor;
1957 fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor;
1959 fs_metrics.width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;
1960 fs_metrics.height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;
1962 fs_metrics.x_advance = 0;
1963 fs_metrics.y_advance = DOUBLE_FROM_26_6 (advance) * y_factor;
1965 } else {
1966 fs_metrics.width = DOUBLE_FROM_26_6 (metrics->width) * x_factor;
1967 fs_metrics.height = DOUBLE_FROM_26_6 (metrics->height) * y_factor;
1969 if (!vertical_layout) {
1970 fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) * x_factor;
1971 fs_metrics.y_bearing = DOUBLE_FROM_26_6 (-metrics->horiBearingY) * y_factor;
1973 if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE)
1974 fs_metrics.x_advance = DOUBLE_FROM_26_6 (metrics->horiAdvance) * x_factor;
1975 else
1976 fs_metrics.x_advance = DOUBLE_FROM_16_16 (glyph->linearHoriAdvance) * x_factor;
1977 fs_metrics.y_advance = 0 * y_factor;
1978 } else {
1979 fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingX) * x_factor;
1980 fs_metrics.y_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingY) * y_factor;
1982 fs_metrics.x_advance = 0 * x_factor;
1983 if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE)
1984 fs_metrics.y_advance = DOUBLE_FROM_26_6 (metrics->vertAdvance) * y_factor;
1985 else
1986 fs_metrics.y_advance = DOUBLE_FROM_16_16 (glyph->linearVertAdvance) * y_factor;
1990 _cairo_scaled_glyph_set_metrics (scaled_glyph,
1991 &scaled_font->base,
1992 &fs_metrics);
1995 if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
1996 cairo_image_surface_t *surface;
1998 if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
1999 status = _render_glyph_outline (face, &scaled_font->ft_options.base,
2000 &surface);
2001 } else {
2002 status = _render_glyph_bitmap (face, &scaled_font->ft_options.base,
2003 &surface);
2004 if (likely (status == CAIRO_STATUS_SUCCESS) &&
2005 unscaled->have_shape)
2007 status = _transform_glyph_bitmap (&unscaled->current_shape,
2008 &surface);
2009 if (unlikely (status))
2010 cairo_surface_destroy (&surface->base);
2013 if (unlikely (status))
2014 goto FAIL;
2016 _cairo_scaled_glyph_set_surface (scaled_glyph,
2017 &scaled_font->base,
2018 surface);
2021 if (info & CAIRO_SCALED_GLYPH_INFO_PATH) {
2022 cairo_path_fixed_t *path = NULL; /* hide compiler warning */
2025 * A kludge -- the above code will trash the outline,
2026 * so reload it. This will probably never occur though
2028 if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
2029 error = FT_Load_Glyph (face,
2030 _cairo_scaled_glyph_index(scaled_glyph),
2031 load_flags | FT_LOAD_NO_BITMAP);
2032 /* XXX ignoring all other errors for now. They are not fatal, typically
2033 * just a glyph-not-found. */
2034 if (error == FT_Err_Out_Of_Memory) {
2035 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2036 goto FAIL;
2038 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
2040 * embolden glyphs if requested
2042 if (scaled_font->ft_options.extra_flags & CAIRO_FT_OPTIONS_EMBOLDEN)
2043 FT_GlyphSlot_Embolden (glyph);
2044 #endif
2045 if (vertical_layout)
2046 _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, glyph);
2049 if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
2050 status = _decompose_glyph_outline (face, &scaled_font->ft_options.base,
2051 &path);
2052 else
2053 status = CAIRO_INT_STATUS_UNSUPPORTED;
2055 if (unlikely (status))
2056 goto FAIL;
2058 _cairo_scaled_glyph_set_path (scaled_glyph,
2059 &scaled_font->base,
2060 path);
2062 FAIL:
2063 _cairo_ft_unscaled_font_unlock_face (unscaled);
2065 return status;
2068 static unsigned long
2069 _cairo_ft_ucs4_to_index (void *abstract_font,
2070 uint32_t ucs4)
2072 cairo_ft_scaled_font_t *scaled_font = abstract_font;
2073 cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
2074 FT_Face face;
2075 FT_UInt index;
2077 face = _cairo_ft_unscaled_font_lock_face (unscaled);
2078 if (!face)
2079 return 0;
2081 #if CAIRO_HAS_FC_FONT
2082 index = FcFreeTypeCharIndex (face, ucs4);
2083 #else
2084 index = FT_Get_Char_Index (face, ucs4);
2085 #endif
2087 _cairo_ft_unscaled_font_unlock_face (unscaled);
2088 return index;
2091 static cairo_int_status_t
2092 _cairo_ft_load_truetype_table (void *abstract_font,
2093 unsigned long tag,
2094 long offset,
2095 unsigned char *buffer,
2096 unsigned long *length)
2098 cairo_ft_scaled_font_t *scaled_font = abstract_font;
2099 cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
2100 FT_Face face;
2101 cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
2103 if (_cairo_ft_scaled_font_is_vertical (&scaled_font->base))
2104 return CAIRO_INT_STATUS_UNSUPPORTED;
2106 #if HAVE_FT_LOAD_SFNT_TABLE
2107 face = _cairo_ft_unscaled_font_lock_face (unscaled);
2108 if (!face)
2109 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2111 if (FT_IS_SFNT (face) &&
2112 FT_Load_Sfnt_Table (face, tag, offset, buffer, length) == 0)
2113 status = CAIRO_STATUS_SUCCESS;
2115 _cairo_ft_unscaled_font_unlock_face (unscaled);
2116 #endif
2118 return status;
2121 static cairo_int_status_t
2122 _cairo_ft_index_to_ucs4(void *abstract_font,
2123 unsigned long index,
2124 uint32_t *ucs4)
2126 cairo_ft_scaled_font_t *scaled_font = abstract_font;
2127 cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
2128 FT_Face face;
2129 FT_ULong charcode;
2130 FT_UInt gindex;
2132 face = _cairo_ft_unscaled_font_lock_face (unscaled);
2133 if (!face)
2134 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2136 *ucs4 = (uint32_t) -1;
2137 charcode = FT_Get_First_Char(face, &gindex);
2138 while (gindex != 0) {
2139 charcode = FT_Get_Next_Char (face, charcode, &gindex);
2140 if (gindex == index) {
2141 *ucs4 = charcode;
2142 break;
2146 _cairo_ft_unscaled_font_unlock_face (unscaled);
2148 return CAIRO_STATUS_SUCCESS;
2151 static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend = {
2152 CAIRO_FONT_TYPE_FT,
2153 _cairo_ft_scaled_font_fini,
2154 _cairo_ft_scaled_glyph_init,
2155 NULL, /* text_to_glyphs */
2156 _cairo_ft_ucs4_to_index,
2157 NULL, /* show_glyphs */
2158 _cairo_ft_load_truetype_table,
2159 _cairo_ft_index_to_ucs4
2162 /* #cairo_ft_font_face_t */
2164 #if CAIRO_HAS_FC_FONT
2165 static cairo_status_t
2166 _cairo_ft_font_face_create_for_pattern (FcPattern *pattern,
2167 cairo_font_face_t **out);
2169 static cairo_status_t
2170 _cairo_ft_font_face_create_for_toy (cairo_toy_font_face_t *toy_face,
2171 cairo_font_face_t **font_face)
2173 FcPattern *pattern;
2174 int fcslant;
2175 int fcweight;
2176 cairo_status_t status = CAIRO_STATUS_SUCCESS;
2178 pattern = FcPatternCreate ();
2179 if (!pattern)
2180 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2182 if (!FcPatternAddString (pattern,
2183 FC_FAMILY, (unsigned char *) toy_face->family))
2185 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2186 goto FREE_PATTERN;
2189 switch (toy_face->slant)
2191 case CAIRO_FONT_SLANT_ITALIC:
2192 fcslant = FC_SLANT_ITALIC;
2193 break;
2194 case CAIRO_FONT_SLANT_OBLIQUE:
2195 fcslant = FC_SLANT_OBLIQUE;
2196 break;
2197 case CAIRO_FONT_SLANT_NORMAL:
2198 default:
2199 fcslant = FC_SLANT_ROMAN;
2200 break;
2203 if (!FcPatternAddInteger (pattern, FC_SLANT, fcslant)) {
2204 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2205 goto FREE_PATTERN;
2208 switch (toy_face->weight)
2210 case CAIRO_FONT_WEIGHT_BOLD:
2211 fcweight = FC_WEIGHT_BOLD;
2212 break;
2213 case CAIRO_FONT_WEIGHT_NORMAL:
2214 default:
2215 fcweight = FC_WEIGHT_MEDIUM;
2216 break;
2219 if (!FcPatternAddInteger (pattern, FC_WEIGHT, fcweight)) {
2220 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2221 goto FREE_PATTERN;
2224 status = _cairo_ft_font_face_create_for_pattern (pattern, font_face);
2226 FREE_PATTERN:
2227 FcPatternDestroy (pattern);
2229 return status;
2231 #endif
2233 static void
2234 _cairo_ft_font_face_destroy (void *abstract_face)
2236 cairo_ft_font_face_t *font_face = abstract_face;
2238 cairo_ft_font_face_t *tmp_face = NULL;
2239 cairo_ft_font_face_t *last_face = NULL;
2241 if (font_face == NULL)
2242 return;
2244 /* When destroying a face created by cairo_ft_font_face_create_for_ft_face,
2245 * we have a special "zombie" state for the face when the unscaled font
2246 * is still alive but there are no other references to a font face with
2247 * the same FT_Face.
2249 * We go from:
2251 * font_face ------> unscaled
2252 * <-....weak....../
2254 * To:
2256 * font_face <------- unscaled
2259 if (font_face->unscaled &&
2260 font_face->unscaled->from_face &&
2261 font_face->next == NULL &&
2262 font_face->unscaled->faces == font_face &&
2263 CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1)
2265 cairo_font_face_reference (&font_face->base);
2267 _cairo_unscaled_font_destroy (&font_face->unscaled->base);
2268 font_face->unscaled = NULL;
2270 return;
2273 if (font_face->unscaled) {
2274 /* Remove face from linked list */
2275 for (tmp_face = font_face->unscaled->faces;
2276 tmp_face;
2277 tmp_face = tmp_face->next)
2279 if (tmp_face == font_face) {
2280 if (last_face)
2281 last_face->next = tmp_face->next;
2282 else
2283 font_face->unscaled->faces = tmp_face->next;
2286 last_face = tmp_face;
2289 _cairo_unscaled_font_destroy (&font_face->unscaled->base);
2290 font_face->unscaled = NULL;
2293 #if CAIRO_HAS_FC_FONT
2294 if (font_face->pattern) {
2295 FcPatternDestroy (font_face->pattern);
2296 cairo_font_face_destroy (font_face->resolved_font_face);
2298 #endif
2301 static cairo_font_face_t *
2302 _cairo_ft_font_face_get_implementation (void *abstract_face,
2303 const cairo_matrix_t *font_matrix,
2304 const cairo_matrix_t *ctm,
2305 const cairo_font_options_t *options)
2307 cairo_ft_font_face_t *font_face = abstract_face;
2309 /* The handling of font options is different depending on how the
2310 * font face was created. When the user creates a font face with
2311 * cairo_ft_font_face_create_for_ft_face(), then the load flags
2312 * passed in augment the load flags for the options. But for
2313 * cairo_ft_font_face_create_for_pattern(), the load flags are
2314 * derived from a pattern where the user has called
2315 * cairo_ft_font_options_substitute(), so *just* use those load
2316 * flags and ignore the options.
2319 #if CAIRO_HAS_FC_FONT
2320 /* If we have an unresolved pattern, resolve it and create
2321 * unscaled font. Otherwise, use the ones stored in font_face.
2323 if (font_face->pattern) {
2324 cairo_font_face_t *resolved;
2326 /* Cache the resolved font whilst the FcConfig remains consistent. */
2327 resolved = font_face->resolved_font_face;
2328 if (resolved != NULL) {
2329 if (! FcInitBringUptoDate ()) {
2330 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
2331 return (cairo_font_face_t *) &_cairo_font_face_nil;
2334 if (font_face->resolved_config == FcConfigGetCurrent ())
2335 return cairo_font_face_reference (resolved);
2337 cairo_font_face_destroy (resolved);
2340 resolved = _cairo_ft_resolve_pattern (font_face->pattern,
2341 font_matrix,
2342 ctm,
2343 options);
2345 font_face->resolved_font_face = cairo_font_face_reference (resolved);
2346 font_face->resolved_config = FcConfigGetCurrent ();
2348 return resolved;
2350 #endif
2352 return abstract_face;
2355 const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
2356 CAIRO_FONT_TYPE_FT,
2357 #if CAIRO_HAS_FC_FONT
2358 _cairo_ft_font_face_create_for_toy,
2359 #else
2360 NULL,
2361 #endif
2362 _cairo_ft_font_face_destroy,
2363 _cairo_ft_font_face_scaled_font_create,
2364 _cairo_ft_font_face_get_implementation
2367 #if CAIRO_HAS_FC_FONT
2368 static cairo_status_t
2369 _cairo_ft_font_face_create_for_pattern (FcPattern *pattern,
2370 cairo_font_face_t **out)
2372 cairo_ft_font_face_t *font_face;
2374 font_face = malloc (sizeof (cairo_ft_font_face_t));
2375 if (unlikely (font_face == NULL))
2376 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2378 font_face->unscaled = NULL;
2379 font_face->next = NULL;
2381 font_face->pattern = FcPatternDuplicate (pattern);
2382 if (unlikely (font_face->pattern == NULL)) {
2383 free (font_face);
2384 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2387 font_face->resolved_font_face = NULL;
2388 font_face->resolved_config = NULL;
2390 _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend);
2392 *out = &font_face->base;
2393 return CAIRO_STATUS_SUCCESS;
2395 #endif
2397 static cairo_font_face_t *
2398 _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
2399 cairo_ft_options_t *ft_options)
2401 cairo_ft_font_face_t *font_face, **prev_font_face;
2403 /* Looked for an existing matching font face */
2404 for (font_face = unscaled->faces, prev_font_face = &unscaled->faces;
2405 font_face;
2406 prev_font_face = &font_face->next, font_face = font_face->next)
2408 if (font_face->ft_options.load_flags == ft_options->load_flags &&
2409 font_face->ft_options.extra_flags == ft_options->extra_flags &&
2410 cairo_font_options_equal (&font_face->ft_options.base, &ft_options->base))
2412 if (font_face->base.status) {
2413 /* The font_face has been left in an error state, abandon it. */
2414 *prev_font_face = font_face->next;
2415 break;
2418 if (font_face->unscaled == NULL) {
2419 /* Resurrect this "zombie" font_face (from
2420 * _cairo_ft_font_face_destroy), switching its unscaled_font
2421 * from owner to ownee. */
2422 font_face->unscaled = unscaled;
2423 _cairo_unscaled_font_reference (&unscaled->base);
2424 return &font_face->base;
2425 } else
2426 return cairo_font_face_reference (&font_face->base);
2430 /* No match found, create a new one */
2431 font_face = malloc (sizeof (cairo_ft_font_face_t));
2432 if (unlikely (!font_face)) {
2433 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
2434 return (cairo_font_face_t *)&_cairo_font_face_nil;
2437 font_face->unscaled = unscaled;
2438 _cairo_unscaled_font_reference (&unscaled->base);
2440 font_face->ft_options = *ft_options;
2442 if (unscaled->faces && unscaled->faces->unscaled == NULL) {
2443 /* This "zombie" font_face (from _cairo_ft_font_face_destroy)
2444 * is no longer needed. */
2445 assert (unscaled->from_face && unscaled->faces->next == NULL);
2446 cairo_font_face_destroy (&unscaled->faces->base);
2447 unscaled->faces = NULL;
2450 font_face->next = unscaled->faces;
2451 unscaled->faces = font_face;
2453 #if CAIRO_HAS_FC_FONT
2454 font_face->pattern = NULL;
2455 #endif
2457 _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend);
2459 return &font_face->base;
2462 /* implement the platform-specific interface */
2464 #if CAIRO_HAS_FC_FONT
2465 static cairo_status_t
2466 _cairo_ft_font_options_substitute (const cairo_font_options_t *options,
2467 FcPattern *pattern)
2469 FcValue v;
2471 if (options->antialias != CAIRO_ANTIALIAS_DEFAULT)
2473 if (FcPatternGet (pattern, FC_ANTIALIAS, 0, &v) == FcResultNoMatch)
2475 if (! FcPatternAddBool (pattern,
2476 FC_ANTIALIAS,
2477 options->antialias != CAIRO_ANTIALIAS_NONE))
2478 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2480 if (options->antialias != CAIRO_ANTIALIAS_SUBPIXEL) {
2481 FcPatternDel (pattern, FC_RGBA);
2482 if (! FcPatternAddInteger (pattern, FC_RGBA, FC_RGBA_NONE))
2483 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2488 if (options->antialias != CAIRO_ANTIALIAS_DEFAULT)
2490 if (FcPatternGet (pattern, FC_RGBA, 0, &v) == FcResultNoMatch)
2492 int rgba;
2494 if (options->antialias == CAIRO_ANTIALIAS_SUBPIXEL) {
2495 switch (options->subpixel_order) {
2496 case CAIRO_SUBPIXEL_ORDER_DEFAULT:
2497 case CAIRO_SUBPIXEL_ORDER_RGB:
2498 default:
2499 rgba = FC_RGBA_RGB;
2500 break;
2501 case CAIRO_SUBPIXEL_ORDER_BGR:
2502 rgba = FC_RGBA_BGR;
2503 break;
2504 case CAIRO_SUBPIXEL_ORDER_VRGB:
2505 rgba = FC_RGBA_VRGB;
2506 break;
2507 case CAIRO_SUBPIXEL_ORDER_VBGR:
2508 rgba = FC_RGBA_VBGR;
2509 break;
2511 } else {
2512 rgba = FC_RGBA_NONE;
2515 if (! FcPatternAddInteger (pattern, FC_RGBA, rgba))
2516 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2520 if (options->hint_style != CAIRO_HINT_STYLE_DEFAULT)
2522 if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch)
2524 if (! FcPatternAddBool (pattern,
2525 FC_HINTING,
2526 options->hint_style != CAIRO_HINT_STYLE_NONE))
2527 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2530 #ifdef FC_HINT_STYLE
2531 if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch)
2533 int hint_style;
2535 switch (options->hint_style) {
2536 case CAIRO_HINT_STYLE_NONE:
2537 hint_style = FC_HINT_NONE;
2538 break;
2539 case CAIRO_HINT_STYLE_SLIGHT:
2540 hint_style = FC_HINT_SLIGHT;
2541 break;
2542 case CAIRO_HINT_STYLE_MEDIUM:
2543 hint_style = FC_HINT_MEDIUM;
2544 break;
2545 case CAIRO_HINT_STYLE_FULL:
2546 case CAIRO_HINT_STYLE_DEFAULT:
2547 default:
2548 hint_style = FC_HINT_FULL;
2549 break;
2552 if (! FcPatternAddInteger (pattern, FC_HINT_STYLE, hint_style))
2553 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2555 #endif
2558 return CAIRO_STATUS_SUCCESS;
2562 * cairo_ft_font_options_substitute:
2563 * @options: a #cairo_font_options_t object
2564 * @pattern: an existing #FcPattern
2566 * Add options to a #FcPattern based on a #cairo_font_options_t font
2567 * options object. Options that are already in the pattern, are not overridden,
2568 * so you should call this function after calling FcConfigSubstitute() (the
2569 * user's settings should override options based on the surface type), but
2570 * before calling FcDefaultSubstitute().
2572 void
2573 cairo_ft_font_options_substitute (const cairo_font_options_t *options,
2574 FcPattern *pattern)
2576 if (cairo_font_options_status ((cairo_font_options_t *) options))
2577 return;
2579 _cairo_ft_font_options_substitute (options, pattern);
2582 static cairo_font_face_t *
2583 _cairo_ft_resolve_pattern (FcPattern *pattern,
2584 const cairo_matrix_t *font_matrix,
2585 const cairo_matrix_t *ctm,
2586 const cairo_font_options_t *font_options)
2588 cairo_status_t status;
2590 cairo_matrix_t scale;
2591 FcPattern *resolved;
2592 cairo_ft_font_transform_t sf;
2593 FcResult result;
2594 cairo_ft_unscaled_font_t *unscaled;
2595 cairo_ft_options_t ft_options;
2596 cairo_font_face_t *font_face;
2598 scale = *ctm;
2599 scale.x0 = scale.y0 = 0;
2600 cairo_matrix_multiply (&scale,
2601 font_matrix,
2602 &scale);
2604 status = _compute_transform (&sf, &scale);
2605 if (unlikely (status))
2606 return (cairo_font_face_t *)&_cairo_font_face_nil;
2608 pattern = FcPatternDuplicate (pattern);
2609 if (pattern == NULL)
2610 return (cairo_font_face_t *)&_cairo_font_face_nil;
2612 if (! FcPatternAddDouble (pattern, FC_PIXEL_SIZE, sf.y_scale)) {
2613 font_face = (cairo_font_face_t *)&_cairo_font_face_nil;
2614 goto FREE_PATTERN;
2617 if (! FcConfigSubstitute (NULL, pattern, FcMatchPattern)) {
2618 font_face = (cairo_font_face_t *)&_cairo_font_face_nil;
2619 goto FREE_PATTERN;
2622 status = _cairo_ft_font_options_substitute (font_options, pattern);
2623 if (status) {
2624 font_face = (cairo_font_face_t *)&_cairo_font_face_nil;
2625 goto FREE_PATTERN;
2628 FcDefaultSubstitute (pattern);
2630 resolved = FcFontMatch (NULL, pattern, &result);
2631 if (!resolved) {
2632 /* We failed to find any font. Substitute twin so that the user can
2633 * see something (and hopefully recognise that the font is missing)
2634 * and not just receive a NO_MEMORY error during rendering.
2636 font_face = _cairo_font_face_twin_create_fallback ();
2637 goto FREE_PATTERN;
2640 status = _cairo_ft_unscaled_font_create_for_pattern (resolved, &unscaled);
2641 if (unlikely (status)) {
2642 font_face = (cairo_font_face_t *)&_cairo_font_face_nil;
2643 goto FREE_RESOLVED;
2646 assert (unscaled != NULL);
2648 _get_pattern_ft_options (resolved, &ft_options);
2649 font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
2650 _cairo_unscaled_font_destroy (&unscaled->base);
2652 FREE_RESOLVED:
2653 FcPatternDestroy (resolved);
2655 FREE_PATTERN:
2656 FcPatternDestroy (pattern);
2658 return font_face;
2662 * cairo_ft_font_face_create_for_pattern:
2663 * @pattern: A fontconfig pattern. Cairo makes a copy of the pattern
2664 * if it needs to. You are free to modify or free @pattern after this call.
2666 * Creates a new font face for the FreeType font backend based on a
2667 * fontconfig pattern. This font can then be used with
2668 * cairo_set_font_face() or cairo_scaled_font_create(). The
2669 * #cairo_scaled_font_t returned from cairo_scaled_font_create() is
2670 * also for the FreeType backend and can be used with functions such
2671 * as cairo_ft_scaled_font_lock_face().
2673 * Font rendering options are represented both here and when you
2674 * call cairo_scaled_font_create(). Font options that have a representation
2675 * in a #FcPattern must be passed in here; to modify #FcPattern
2676 * appropriately to reflect the options in a #cairo_font_options_t, call
2677 * cairo_ft_font_options_substitute().
2679 * The pattern's FC_FT_FACE element is inspected first and if that is set,
2680 * that will be the FreeType font face associated with the returned cairo
2681 * font face. Otherwise the FC_FILE element is checked. If it's set,
2682 * that and the value of the FC_INDEX element (defaults to zero) of @pattern
2683 * are used to load a font face from file.
2685 * If both steps from the previous paragraph fails, @pattern will be passed
2686 * to FcConfigSubstitute, FcDefaultSubstitute, and finally FcFontMatch,
2687 * and the resulting font pattern is used.
2689 * If the FC_FT_FACE element of @pattern is set, the user is responsible
2690 * for making sure that the referenced FT_Face remains valid for the life
2691 * time of the returned #cairo_font_face_t. See
2692 * cairo_ft_font_face_create_for_ft_face() for an exmaple of how to couple
2693 * the life time of the FT_Face to that of the cairo font-face.
2695 * Return value: a newly created #cairo_font_face_t. Free with
2696 * cairo_font_face_destroy() when you are done using it.
2698 cairo_font_face_t *
2699 cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
2701 cairo_ft_unscaled_font_t *unscaled;
2702 cairo_font_face_t *font_face;
2703 cairo_ft_options_t ft_options;
2704 cairo_status_t status;
2706 status = _cairo_ft_unscaled_font_create_for_pattern (pattern, &unscaled);
2707 if (unlikely (status))
2708 return (cairo_font_face_t *) &_cairo_font_face_nil;
2709 if (unlikely (unscaled == NULL)) {
2710 /* Store the pattern. We will resolve it and create unscaled
2711 * font when creating scaled fonts */
2712 status = _cairo_ft_font_face_create_for_pattern (pattern,
2713 &font_face);
2714 if (unlikely (status))
2715 return (cairo_font_face_t *) &_cairo_font_face_nil;
2717 return font_face;
2720 _get_pattern_ft_options (pattern, &ft_options);
2721 font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
2722 _cairo_unscaled_font_destroy (&unscaled->base);
2724 return font_face;
2726 #endif
2729 * cairo_ft_font_face_create_for_ft_face:
2730 * @face: A FreeType face object, already opened. This must
2731 * be kept around until the face's ref_count drops to
2732 * zero and it is freed. Since the face may be referenced
2733 * internally to Cairo, the best way to determine when it
2734 * is safe to free the face is to pass a
2735 * #cairo_destroy_func_t to cairo_font_face_set_user_data()
2736 * @load_flags: flags to pass to FT_Load_Glyph when loading
2737 * glyphs from the font. These flags are OR'ed together with
2738 * the flags derived from the #cairo_font_options_t passed
2739 * to cairo_scaled_font_create(), so only a few values such
2740 * as %FT_LOAD_VERTICAL_LAYOUT, and %FT_LOAD_FORCE_AUTOHINT
2741 * are useful. You should not pass any of the flags affecting
2742 * the load target, such as %FT_LOAD_TARGET_LIGHT.
2744 * Creates a new font face for the FreeType font backend from a
2745 * pre-opened FreeType face. This font can then be used with
2746 * cairo_set_font_face() or cairo_scaled_font_create(). The
2747 * #cairo_scaled_font_t returned from cairo_scaled_font_create() is
2748 * also for the FreeType backend and can be used with functions such
2749 * as cairo_ft_scaled_font_lock_face(). Note that Cairo may keep a reference
2750 * to the FT_Face alive in a font-cache and the exact lifetime of the reference
2751 * depends highly upon the exact usage pattern and is subject to external
2752 * factors. You must not call FT_Done_Face() before the last reference to the
2753 * #cairo_font_face_t has been dropped.
2755 * As an example, below is how one might correctly couple the lifetime of
2756 * the FreeType face object to the #cairo_font_face_t.
2758 * <informalexample><programlisting>
2759 * static const cairo_user_data_key_t key;
2761 * font_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
2762 * status = cairo_font_face_set_user_data (font_face, &key,
2763 * ft_face, (cairo_destroy_func_t) FT_Done_Face);
2764 * if (status) {
2765 * cairo_font_face_destroy (font_face);
2766 * FT_Done_Face (ft_face);
2767 * return ERROR;
2769 * </programlisting></informalexample>
2771 * Return value: a newly created #cairo_font_face_t. Free with
2772 * cairo_font_face_destroy() when you are done using it.
2774 cairo_font_face_t *
2775 cairo_ft_font_face_create_for_ft_face (FT_Face face,
2776 int load_flags)
2778 cairo_ft_unscaled_font_t *unscaled;
2779 cairo_font_face_t *font_face;
2780 cairo_ft_options_t ft_options;
2781 cairo_status_t status;
2783 status = _cairo_ft_unscaled_font_create_from_face (face, &unscaled);
2784 if (unlikely (status))
2785 return (cairo_font_face_t *)&_cairo_font_face_nil;
2787 ft_options.load_flags = load_flags;
2788 ft_options.extra_flags = 0;
2789 _cairo_font_options_init_default (&ft_options.base);
2791 font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
2792 _cairo_unscaled_font_destroy (&unscaled->base);
2794 return font_face;
2798 * cairo_ft_scaled_font_lock_face:
2799 * @scaled_font: A #cairo_scaled_font_t from the FreeType font backend. Such an
2800 * object can be created by calling cairo_scaled_font_create() on a
2801 * FreeType backend font face (see cairo_ft_font_face_create_for_pattern(),
2802 * cairo_ft_font_face_create_for_ft_face()).
2804 * cairo_ft_scaled_font_lock_face() gets the #FT_Face object from a FreeType
2805 * backend font and scales it appropriately for the font. You must
2806 * release the face with cairo_ft_scaled_font_unlock_face()
2807 * when you are done using it. Since the #FT_Face object can be
2808 * shared between multiple #cairo_scaled_font_t objects, you must not
2809 * lock any other font objects until you unlock this one. A count is
2810 * kept of the number of times cairo_ft_scaled_font_lock_face() is
2811 * called. cairo_ft_scaled_font_unlock_face() must be called the same number
2812 * of times.
2814 * You must be careful when using this function in a library or in a
2815 * threaded application, because freetype's design makes it unsafe to
2816 * call freetype functions simultaneously from multiple threads, (even
2817 * if using distinct FT_Face objects). Because of this, application
2818 * code that acquires an FT_Face object with this call must add its
2819 * own locking to protect any use of that object, (and which also must
2820 * protect any other calls into cairo as almost any cairo function
2821 * might result in a call into the freetype library).
2823 * Return value: The #FT_Face object for @font, scaled appropriately,
2824 * or %NULL if @scaled_font is in an error state (see
2825 * cairo_scaled_font_status()) or there is insufficient memory.
2827 FT_Face
2828 cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font)
2830 cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
2831 FT_Face face;
2832 cairo_status_t status;
2834 if (! _cairo_scaled_font_is_ft (abstract_font)) {
2835 _cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH);
2836 return NULL;
2839 if (scaled_font->base.status)
2840 return NULL;
2842 face = _cairo_ft_unscaled_font_lock_face (scaled_font->unscaled);
2843 if (unlikely (face == NULL)) {
2844 status = _cairo_scaled_font_set_error (&scaled_font->base, CAIRO_STATUS_NO_MEMORY);
2845 return NULL;
2848 status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
2849 &scaled_font->base.scale);
2850 if (unlikely (status)) {
2851 _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
2852 status = _cairo_scaled_font_set_error (&scaled_font->base, status);
2853 return NULL;
2856 /* Note: We deliberately release the unscaled font's mutex here,
2857 * so that we are not holding a lock across two separate calls to
2858 * cairo function, (which would give the application some
2859 * opportunity for creating deadlock. This is obviously unsafe,
2860 * but as documented, the user must add manual locking when using
2861 * this function. */
2862 CAIRO_MUTEX_UNLOCK (scaled_font->unscaled->mutex);
2864 return face;
2868 * cairo_ft_scaled_font_unlock_face:
2869 * @scaled_font: A #cairo_scaled_font_t from the FreeType font backend. Such an
2870 * object can be created by calling cairo_scaled_font_create() on a
2871 * FreeType backend font face (see cairo_ft_font_face_create_for_pattern(),
2872 * cairo_ft_font_face_create_for_ft_face()).
2874 * Releases a face obtained with cairo_ft_scaled_font_lock_face().
2876 void
2877 cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t *abstract_font)
2879 cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
2881 if (! _cairo_scaled_font_is_ft (abstract_font)) {
2882 _cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH);
2883 return;
2886 if (scaled_font->base.status)
2887 return;
2889 /* Note: We released the unscaled font's mutex at the end of
2890 * cairo_ft_scaled_font_lock_face, so we have to acquire it again
2891 * as _cairo_ft_unscaled_font_unlock_face expects it to be held
2892 * when we call into it. */
2893 CAIRO_MUTEX_LOCK (scaled_font->unscaled->mutex);
2895 _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
2898 /* We expose our unscaled font implementation internally for the the
2899 * PDF backend, which needs to keep track of the the different
2900 * fonts-on-disk used by a document, so it can embed them.
2902 cairo_unscaled_font_t *
2903 _cairo_ft_scaled_font_get_unscaled_font (cairo_scaled_font_t *abstract_font)
2905 cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
2907 return &scaled_font->unscaled->base;
2910 cairo_bool_t
2911 _cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font)
2913 cairo_ft_scaled_font_t *ft_scaled_font;
2915 if (!_cairo_scaled_font_is_ft (scaled_font))
2916 return FALSE;
2918 ft_scaled_font = (cairo_ft_scaled_font_t *) scaled_font;
2919 if (ft_scaled_font->ft_options.load_flags & FT_LOAD_VERTICAL_LAYOUT)
2920 return TRUE;
2921 return FALSE;
2924 unsigned int
2925 _cairo_ft_scaled_font_get_load_flags (cairo_scaled_font_t *scaled_font)
2927 cairo_ft_scaled_font_t *ft_scaled_font;
2929 if (! _cairo_scaled_font_is_ft (scaled_font))
2930 return 0;
2932 ft_scaled_font = (cairo_ft_scaled_font_t *) scaled_font;
2933 return ft_scaled_font->ft_options.load_flags;
2936 void
2937 _cairo_ft_font_reset_static_data (void)
2939 _cairo_ft_unscaled_font_map_destroy ();