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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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.
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() */
44 #include "cairo-error-private.h"
45 #include "cairo-image-surface-private.h"
46 #include "cairo-ft-private.h"
47 #include "cairo-pattern-private.h"
48 #include "cairo-pixman-private.h"
52 #include "cairo-fontconfig-private.h"
55 #include FT_FREETYPE_H
59 #include FT_TRUETYPE_TABLES_H
61 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
62 #include FT_SYNTHESIS_H
65 #if HAVE_FT_LIBRARY_SETLCDFILTER
66 #include FT_LCD_FILTER_H
72 #define access(p, m) 0
75 /* Fontconfig version older than 2.6 didn't have these options */
77 #define FC_LCD_FILTER "lcdfilter"
79 /* Some Ubuntu versions defined FC_LCD_FILTER without defining the following */
82 #define FC_LCD_DEFAULT 1
83 #define FC_LCD_LIGHT 2
84 #define FC_LCD_LEGACY 3
87 /* FreeType version older than 2.3.5(?) didn't have these options */
88 #ifndef FT_LCD_FILTER_NONE
89 #define FT_LCD_FILTER_NONE 0
90 #define FT_LCD_FILTER_DEFAULT 1
91 #define FT_LCD_FILTER_LIGHT 2
92 #define FT_LCD_FILTER_LEGACY 16
95 #define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
96 #define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
97 #define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
98 #define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0)
100 /* This is the max number of FT_face objects we keep open at once
102 #define MAX_OPEN_FACES 10
106 * @Title: FreeType Fonts
107 * @Short_Description: Font support for FreeType
108 * @See_Also: #cairo_font_face_t
110 * The FreeType font backend is primarily used to render text on GNU/Linux
111 * systems, but can be used on other platforms too.
117 * Defined if the FreeType font backend is available.
118 * This macro can be used to conditionally compile backend-specific code.
126 * Defined if the Fontconfig-specific functions of the FreeType font backend
128 * This macro can be used to conditionally compile backend-specific code.
134 * The simple 2x2 matrix is converted into separate scale and shape
135 * factors so that hinting works right
138 typedef struct _cairo_ft_font_transform
{
139 double x_scale
, y_scale
;
141 } cairo_ft_font_transform_t
;
144 * We create an object that corresponds to a single font on the disk;
145 * (identified by a filename/id pair) these are shared between all
146 * fonts using that file. For cairo_ft_font_face_create_for_ft_face(), we
147 * just create a one-off version with a permanent face value.
150 typedef struct _cairo_ft_font_face cairo_ft_font_face_t
;
152 struct _cairo_ft_unscaled_font
{
153 cairo_unscaled_font_t base
;
155 cairo_bool_t from_face
; /* was the FT_Face provided by user? */
156 FT_Face face
; /* provided or cached face */
158 /* only set if from_face is false */
162 /* We temporarily scale the unscaled font as needed */
163 cairo_bool_t have_scale
;
164 cairo_matrix_t current_scale
;
165 double x_scale
; /* Extracted X scale factor */
166 double y_scale
; /* Extracted Y scale factor */
167 cairo_bool_t have_shape
; /* true if the current scale has a non-scale component*/
168 cairo_matrix_t current_shape
;
169 FT_Matrix Current_Shape
;
174 cairo_ft_font_face_t
*faces
; /* Linked list of faces for this font */
178 _cairo_ft_unscaled_font_keys_equal (const void *key_a
,
182 _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t
*unscaled
);
184 typedef struct _cairo_ft_options
{
185 cairo_font_options_t base
;
186 unsigned int load_flags
; /* flags for FT_Load_Glyph */
187 unsigned int synth_flags
;
188 } cairo_ft_options_t
;
190 struct _cairo_ft_font_face
{
191 cairo_font_face_t base
;
193 cairo_ft_unscaled_font_t
*unscaled
;
194 cairo_ft_options_t ft_options
;
195 cairo_ft_font_face_t
*next
;
197 #if CAIRO_HAS_FC_FONT
198 FcPattern
*pattern
; /* if pattern is set, the above fields will be NULL */
199 cairo_font_face_t
*resolved_font_face
;
200 FcConfig
*resolved_config
;
204 static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend
;
206 #if CAIRO_HAS_FC_FONT
207 static cairo_status_t
208 _cairo_ft_font_options_substitute (const cairo_font_options_t
*options
,
211 static cairo_font_face_t
*
212 _cairo_ft_resolve_pattern (FcPattern
*pattern
,
213 const cairo_matrix_t
*font_matrix
,
214 const cairo_matrix_t
*ctm
,
215 const cairo_font_options_t
*options
);
219 static cairo_status_t
220 _ft_to_cairo_error (FT_Error error
)
222 /* Currently we don't get many (any?) useful statuses here.
223 * Populate as needed. */
226 default: return CAIRO_STATUS_NO_MEMORY
;
231 * We maintain a hash table to map file/id => #cairo_ft_unscaled_font_t.
232 * The hash table itself isn't limited in size. However, we limit the
233 * number of FT_Face objects we keep around; when we've exceeded that
234 * limit and need to create a new FT_Face, we dump the FT_Face from a
235 * random #cairo_ft_unscaled_font_t which has an unlocked FT_Face, (if
239 typedef struct _cairo_ft_unscaled_font_map
{
240 cairo_hash_table_t
*hash_table
;
241 FT_Library ft_library
;
243 } cairo_ft_unscaled_font_map_t
;
245 static cairo_ft_unscaled_font_map_t
*cairo_ft_unscaled_font_map
= NULL
;
249 _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t
*unscaled
);
252 _cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t
*unscaled
);
255 _cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t
*scaled_font
);
259 _font_map_release_face_lock_held (cairo_ft_unscaled_font_map_t
*font_map
,
260 cairo_ft_unscaled_font_t
*unscaled
)
262 if (unscaled
->face
) {
263 FT_Done_Face (unscaled
->face
);
264 unscaled
->face
= NULL
;
265 unscaled
->have_scale
= FALSE
;
267 font_map
->num_open_faces
--;
271 static cairo_status_t
272 _cairo_ft_unscaled_font_map_create (void)
274 cairo_ft_unscaled_font_map_t
*font_map
;
276 /* This function is only intended to be called from
277 * _cairo_ft_unscaled_font_map_lock. So we'll crash if we can
278 * detect some other call path. */
279 assert (cairo_ft_unscaled_font_map
== NULL
);
281 font_map
= malloc (sizeof (cairo_ft_unscaled_font_map_t
));
282 if (unlikely (font_map
== NULL
))
283 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
285 font_map
->hash_table
=
286 _cairo_hash_table_create (_cairo_ft_unscaled_font_keys_equal
);
288 if (unlikely (font_map
->hash_table
== NULL
))
291 if (unlikely (FT_Init_FreeType (&font_map
->ft_library
)))
294 font_map
->num_open_faces
= 0;
296 cairo_ft_unscaled_font_map
= font_map
;
297 return CAIRO_STATUS_SUCCESS
;
300 if (font_map
->hash_table
)
301 _cairo_hash_table_destroy (font_map
->hash_table
);
304 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
309 _cairo_ft_unscaled_font_map_pluck_entry (void *entry
, void *closure
)
311 cairo_ft_unscaled_font_t
*unscaled
= entry
;
312 cairo_ft_unscaled_font_map_t
*font_map
= closure
;
314 _cairo_hash_table_remove (font_map
->hash_table
,
315 &unscaled
->base
.hash_entry
);
317 if (! unscaled
->from_face
)
318 _font_map_release_face_lock_held (font_map
, unscaled
);
320 _cairo_ft_unscaled_font_fini (unscaled
);
325 _cairo_ft_unscaled_font_map_destroy (void)
327 cairo_ft_unscaled_font_map_t
*font_map
;
329 CAIRO_MUTEX_LOCK (_cairo_ft_unscaled_font_map_mutex
);
330 font_map
= cairo_ft_unscaled_font_map
;
331 cairo_ft_unscaled_font_map
= NULL
;
332 CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex
);
334 if (font_map
!= NULL
) {
335 _cairo_hash_table_foreach (font_map
->hash_table
,
336 _cairo_ft_unscaled_font_map_pluck_entry
,
338 assert (font_map
->num_open_faces
== 0);
340 FT_Done_FreeType (font_map
->ft_library
);
342 _cairo_hash_table_destroy (font_map
->hash_table
);
348 static cairo_ft_unscaled_font_map_t
*
349 _cairo_ft_unscaled_font_map_lock (void)
351 CAIRO_MUTEX_LOCK (_cairo_ft_unscaled_font_map_mutex
);
353 if (unlikely (cairo_ft_unscaled_font_map
== NULL
)) {
354 if (unlikely (_cairo_ft_unscaled_font_map_create ())) {
355 CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex
);
360 return cairo_ft_unscaled_font_map
;
364 _cairo_ft_unscaled_font_map_unlock (void)
366 CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex
);
370 _cairo_ft_unscaled_font_init_key (cairo_ft_unscaled_font_t
*key
,
371 cairo_bool_t from_face
,
378 key
->from_face
= from_face
;
379 key
->filename
= filename
;
383 hash
= _cairo_hash_string (filename
);
384 /* the constants are just arbitrary primes */
385 hash
+= ((unsigned long) id
) * 1607;
386 hash
+= ((unsigned long) face
) * 2137;
388 key
->base
.hash_entry
.hash
= hash
;
392 * _cairo_ft_unscaled_font_init:
394 * Initialize a #cairo_ft_unscaled_font_t.
396 * There are two basic flavors of #cairo_ft_unscaled_font_t, one
397 * created from an FT_Face and the other created from a filename/id
398 * pair. These two flavors are identified as from_face and !from_face.
400 * To initialize a from_face font, pass filename==%NULL, id=0 and the
403 * To initialize a !from_face font, pass the filename/id as desired
406 * Note that the code handles these two flavors in very distinct
407 * ways. For example there is a hash_table mapping
408 * filename/id->#cairo_unscaled_font_t in the !from_face case, but no
409 * parallel in the from_face case, (where the calling code would have
410 * to do its own mapping to ensure similar sharing).
412 static cairo_status_t
413 _cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t
*unscaled
,
414 cairo_bool_t from_face
,
415 const char *filename
,
419 _cairo_unscaled_font_init (&unscaled
->base
,
420 &cairo_ft_unscaled_font_backend
);
423 unscaled
->from_face
= TRUE
;
424 _cairo_ft_unscaled_font_init_key (unscaled
, TRUE
, NULL
, 0, face
);
428 unscaled
->from_face
= FALSE
;
429 unscaled
->face
= NULL
;
431 filename_copy
= strdup (filename
);
432 if (unlikely (filename_copy
== NULL
))
433 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
435 _cairo_ft_unscaled_font_init_key (unscaled
, FALSE
, filename_copy
, id
, NULL
);
438 unscaled
->have_scale
= FALSE
;
439 CAIRO_MUTEX_INIT (unscaled
->mutex
);
440 unscaled
->lock_count
= 0;
442 unscaled
->faces
= NULL
;
444 return CAIRO_STATUS_SUCCESS
;
448 * _cairo_ft_unscaled_font_fini:
450 * Free all data associated with a #cairo_ft_unscaled_font_t.
452 * CAUTION: The unscaled->face field must be %NULL before calling this
453 * function. This is because the #cairo_ft_unscaled_font_t_map keeps a
454 * count of these faces (font_map->num_open_faces) so it maintains the
455 * unscaled->face field while it has its lock held. See
456 * _font_map_release_face_lock_held().
459 _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t
*unscaled
)
461 assert (unscaled
->face
== NULL
);
463 free (unscaled
->filename
);
464 unscaled
->filename
= NULL
;
466 CAIRO_MUTEX_FINI (unscaled
->mutex
);
470 _cairo_ft_unscaled_font_keys_equal (const void *key_a
,
473 const cairo_ft_unscaled_font_t
*unscaled_a
= key_a
;
474 const cairo_ft_unscaled_font_t
*unscaled_b
= key_b
;
476 if (unscaled_a
->id
== unscaled_b
->id
&&
477 unscaled_a
->from_face
== unscaled_b
->from_face
)
479 if (unscaled_a
->from_face
)
480 return unscaled_a
->face
== unscaled_b
->face
;
482 if (unscaled_a
->filename
== NULL
&& unscaled_b
->filename
== NULL
)
484 else if (unscaled_a
->filename
== NULL
|| unscaled_b
->filename
== NULL
)
487 return (strcmp (unscaled_a
->filename
, unscaled_b
->filename
) == 0);
493 /* Finds or creates a #cairo_ft_unscaled_font_t for the filename/id from
494 * pattern. Returns a new reference to the unscaled font.
496 static cairo_status_t
497 _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face
,
501 cairo_ft_unscaled_font_t
**out
)
503 cairo_ft_unscaled_font_t key
, *unscaled
;
504 cairo_ft_unscaled_font_map_t
*font_map
;
505 cairo_status_t status
;
507 font_map
= _cairo_ft_unscaled_font_map_lock ();
508 if (unlikely (font_map
== NULL
))
509 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
511 _cairo_ft_unscaled_font_init_key (&key
, from_face
, filename
, id
, font_face
);
513 /* Return existing unscaled font if it exists in the hash table. */
514 unscaled
= _cairo_hash_table_lookup (font_map
->hash_table
,
515 &key
.base
.hash_entry
);
516 if (unscaled
!= NULL
) {
517 _cairo_unscaled_font_reference (&unscaled
->base
);
521 /* Otherwise create it and insert into hash table. */
522 unscaled
= malloc (sizeof (cairo_ft_unscaled_font_t
));
523 if (unlikely (unscaled
== NULL
)) {
524 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
525 goto UNWIND_FONT_MAP_LOCK
;
528 status
= _cairo_ft_unscaled_font_init (unscaled
, from_face
, filename
, id
, font_face
);
529 if (unlikely (status
))
530 goto UNWIND_UNSCALED_MALLOC
;
532 assert (unscaled
->base
.hash_entry
.hash
== key
.base
.hash_entry
.hash
);
533 status
= _cairo_hash_table_insert (font_map
->hash_table
,
534 &unscaled
->base
.hash_entry
);
535 if (unlikely (status
))
536 goto UNWIND_UNSCALED_FONT_INIT
;
539 _cairo_ft_unscaled_font_map_unlock ();
541 return CAIRO_STATUS_SUCCESS
;
543 UNWIND_UNSCALED_FONT_INIT
:
544 _cairo_ft_unscaled_font_fini (unscaled
);
545 UNWIND_UNSCALED_MALLOC
:
547 UNWIND_FONT_MAP_LOCK
:
548 _cairo_ft_unscaled_font_map_unlock ();
553 #if CAIRO_HAS_FC_FONT
554 static cairo_status_t
555 _cairo_ft_unscaled_font_create_for_pattern (FcPattern
*pattern
,
556 cairo_ft_unscaled_font_t
**out
)
558 FT_Face font_face
= NULL
;
559 char *filename
= NULL
;
563 ret
= FcPatternGetFTFace (pattern
, FC_FT_FACE
, 0, &font_face
);
564 if (ret
== FcResultMatch
)
566 if (ret
== FcResultOutOfMemory
)
567 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
569 ret
= FcPatternGetString (pattern
, FC_FILE
, 0, (FcChar8
**) &filename
);
570 if (ret
== FcResultOutOfMemory
)
571 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
572 if (ret
== FcResultMatch
) {
573 if (access (filename
, R_OK
) == 0) {
574 /* If FC_INDEX is not set, we just use 0 */
575 ret
= FcPatternGetInteger (pattern
, FC_INDEX
, 0, &id
);
576 if (ret
== FcResultOutOfMemory
)
577 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
581 return _cairo_error (CAIRO_STATUS_FILE_NOT_FOUND
);
584 /* The pattern contains neither a face nor a filename, resolve it later. */
586 return CAIRO_STATUS_SUCCESS
;
589 return _cairo_ft_unscaled_font_create_internal (font_face
!= NULL
,
590 filename
, id
, font_face
,
595 static cairo_status_t
596 _cairo_ft_unscaled_font_create_from_face (FT_Face face
,
597 cairo_ft_unscaled_font_t
**out
)
599 return _cairo_ft_unscaled_font_create_internal (TRUE
, NULL
, 0, face
, out
);
603 _cairo_ft_unscaled_font_destroy (void *abstract_font
)
605 cairo_ft_unscaled_font_t
*unscaled
= abstract_font
;
606 cairo_ft_unscaled_font_map_t
*font_map
;
608 font_map
= _cairo_ft_unscaled_font_map_lock ();
609 /* All created objects must have been mapped in the font map. */
610 assert (font_map
!= NULL
);
612 if (! _cairo_reference_count_dec_and_test (&unscaled
->base
.ref_count
)) {
613 /* somebody recreated the font whilst we waited for the lock */
614 _cairo_ft_unscaled_font_map_unlock ();
618 _cairo_hash_table_remove (font_map
->hash_table
,
619 &unscaled
->base
.hash_entry
);
621 if (unscaled
->from_face
) {
622 /* See comments in _ft_font_face_destroy about the "zombie" state
623 * for a _ft_font_face.
625 if (unscaled
->faces
&& unscaled
->faces
->unscaled
== NULL
) {
626 assert (unscaled
->faces
->next
== NULL
);
627 cairo_font_face_destroy (&unscaled
->faces
->base
);
630 _font_map_release_face_lock_held (font_map
, unscaled
);
632 unscaled
->face
= NULL
;
634 _cairo_ft_unscaled_font_map_unlock ();
636 _cairo_ft_unscaled_font_fini (unscaled
);
641 _has_unlocked_face (const void *entry
)
643 const cairo_ft_unscaled_font_t
*unscaled
= entry
;
645 return (!unscaled
->from_face
&& unscaled
->lock_count
== 0 && unscaled
->face
);
648 /* Ensures that an unscaled font has a face object. If we exceed
649 * MAX_OPEN_FACES, try to close some.
651 * This differs from _cairo_ft_scaled_font_lock_face in that it doesn't
652 * set the scale on the face, but just returns it at the last scale.
654 static cairo_warn FT_Face
655 _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t
*unscaled
)
657 cairo_ft_unscaled_font_map_t
*font_map
;
661 CAIRO_MUTEX_LOCK (unscaled
->mutex
);
662 unscaled
->lock_count
++;
665 return unscaled
->face
;
667 /* If this unscaled font was created from an FT_Face then we just
668 * returned it above. */
669 assert (!unscaled
->from_face
);
671 font_map
= _cairo_ft_unscaled_font_map_lock ();
673 assert (font_map
!= NULL
);
675 while (font_map
->num_open_faces
>= MAX_OPEN_FACES
)
677 cairo_ft_unscaled_font_t
*entry
;
679 entry
= _cairo_hash_table_random_entry (font_map
->hash_table
,
684 _font_map_release_face_lock_held (font_map
, entry
);
687 _cairo_ft_unscaled_font_map_unlock ();
689 error
= FT_New_Face (font_map
->ft_library
,
695 unscaled
->lock_count
--;
696 CAIRO_MUTEX_UNLOCK (unscaled
->mutex
);
697 _cairo_error_throw (_ft_to_cairo_error (error
));
701 unscaled
->face
= face
;
703 font_map
->num_open_faces
++;
709 /* Unlock unscaled font locked with _cairo_ft_unscaled_font_lock_face
712 _cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t
*unscaled
)
714 assert (unscaled
->lock_count
> 0);
716 unscaled
->lock_count
--;
718 CAIRO_MUTEX_UNLOCK (unscaled
->mutex
);
722 static cairo_status_t
723 _compute_transform (cairo_ft_font_transform_t
*sf
,
724 cairo_matrix_t
*scale
,
725 cairo_ft_unscaled_font_t
*unscaled
)
727 cairo_status_t status
;
728 double x_scale
, y_scale
;
729 cairo_matrix_t normalized
= *scale
;
731 /* The font matrix has x and y "scale" components which we extract and
732 * use as character scale values. These influence the way freetype
733 * chooses hints, as well as selecting different bitmaps in
734 * hand-rendered fonts. We also copy the normalized matrix to
735 * freetype's transformation.
738 status
= _cairo_matrix_compute_basis_scale_factors (scale
,
741 if (unlikely (status
))
744 /* FreeType docs say this about x_scale and y_scale:
745 * "A character width or height smaller than 1pt is set to 1pt;"
746 * So, we cap them from below at 1.0 and let the FT transform
747 * take care of sub-1.0 scaling. */
753 if (unscaled
&& (unscaled
->face
->face_flags
& FT_FACE_FLAG_SCALABLE
) == 0) {
754 double min_distance
= DBL_MAX
;
755 cairo_bool_t magnify
= TRUE
;
757 double best_x_size
= 0;
758 double best_y_size
= 0;
760 for (i
= 0; i
< unscaled
->face
->num_fixed_sizes
; i
++) {
761 double x_size
= unscaled
->face
->available_sizes
[i
].x_ppem
/ 64.;
762 double y_size
= unscaled
->face
->available_sizes
[i
].y_ppem
/ 64.;
763 double distance
= y_size
- y_scale
;
766 * distance is positive if current strike is larger than desired
767 * size, and negative if smaller.
769 * We like to prefer down-scaling to upscaling.
772 if ((magnify
&& distance
>= 0) || fabs (distance
) <= min_distance
) {
773 magnify
= distance
< 0;
774 min_distance
= fabs (distance
);
775 best_x_size
= x_size
;
776 best_y_size
= y_size
;
780 x_scale
= best_x_size
;
781 y_scale
= best_y_size
;
784 sf
->x_scale
= x_scale
;
785 sf
->y_scale
= y_scale
;
787 cairo_matrix_scale (&normalized
, 1.0 / x_scale
, 1.0 / y_scale
);
789 _cairo_matrix_get_affine (&normalized
,
790 &sf
->shape
[0][0], &sf
->shape
[0][1],
791 &sf
->shape
[1][0], &sf
->shape
[1][1],
794 return CAIRO_STATUS_SUCCESS
;
797 /* Temporarily scales an unscaled font to the give scale. We catch
798 * scaling to the same size, since changing a FT_Face is expensive.
800 static cairo_status_t
801 _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t
*unscaled
,
802 cairo_matrix_t
*scale
)
804 cairo_status_t status
;
805 cairo_ft_font_transform_t sf
;
809 assert (unscaled
->face
!= NULL
);
811 if (unscaled
->have_scale
&&
812 scale
->xx
== unscaled
->current_scale
.xx
&&
813 scale
->yx
== unscaled
->current_scale
.yx
&&
814 scale
->xy
== unscaled
->current_scale
.xy
&&
815 scale
->yy
== unscaled
->current_scale
.yy
)
816 return CAIRO_STATUS_SUCCESS
;
818 unscaled
->have_scale
= TRUE
;
819 unscaled
->current_scale
= *scale
;
821 status
= _compute_transform (&sf
, scale
, unscaled
);
822 if (unlikely (status
))
825 unscaled
->x_scale
= sf
.x_scale
;
826 unscaled
->y_scale
= sf
.y_scale
;
828 mat
.xx
= DOUBLE_TO_16_16(sf
.shape
[0][0]);
829 mat
.yx
= - DOUBLE_TO_16_16(sf
.shape
[0][1]);
830 mat
.xy
= - DOUBLE_TO_16_16(sf
.shape
[1][0]);
831 mat
.yy
= DOUBLE_TO_16_16(sf
.shape
[1][1]);
833 unscaled
->have_shape
= (mat
.xx
!= 0x10000 ||
838 unscaled
->Current_Shape
= mat
;
839 cairo_matrix_init (&unscaled
->current_shape
,
840 sf
.shape
[0][0], sf
.shape
[0][1],
841 sf
.shape
[1][0], sf
.shape
[1][1],
844 FT_Set_Transform(unscaled
->face
, &mat
, NULL
);
846 error
= FT_Set_Char_Size (unscaled
->face
,
847 sf
.x_scale
* 64.0 + .5,
848 sf
.y_scale
* 64.0 + .5,
851 return _cairo_error (_ft_to_cairo_error (error
));
853 return CAIRO_STATUS_SUCCESS
;
856 /* we sometimes need to convert the glyph bitmap in a FT_GlyphSlot
857 * into a different format. For example, we want to convert a
858 * FT_PIXEL_MODE_LCD or FT_PIXEL_MODE_LCD_V bitmap into a 32-bit
859 * ARGB or ABGR bitmap.
861 * this function prepares a target descriptor for this operation.
863 * input :: target bitmap descriptor. The function will set its
864 * 'width', 'rows' and 'pitch' fields, and only these
866 * slot :: the glyph slot containing the source bitmap. this
867 * function assumes that slot->format == FT_GLYPH_FORMAT_BITMAP
869 * mode :: the requested final rendering mode. supported values are
870 * MONO, NORMAL (i.e. gray), LCD and LCD_V
872 * the function returns the size in bytes of the corresponding buffer,
873 * it's up to the caller to allocate the corresponding memory block
874 * before calling _fill_xrender_bitmap
876 * it also returns -1 in case of error (e.g. incompatible arguments,
877 * like trying to convert a gray bitmap into a monochrome one)
880 _compute_xrender_bitmap_size(FT_Bitmap
*target
,
885 int width
, height
, pitch
;
887 if (slot
->format
!= FT_GLYPH_FORMAT_BITMAP
)
890 /* compute the size of the final bitmap */
891 ftbit
= &slot
->bitmap
;
893 width
= ftbit
->width
;
894 height
= ftbit
->rows
;
895 pitch
= (width
+ 3) & ~3;
897 switch (ftbit
->pixel_mode
) {
898 case FT_PIXEL_MODE_MONO
:
899 if (mode
== FT_RENDER_MODE_MONO
) {
900 pitch
= (((width
+ 31) & ~31) >> 3);
905 case FT_PIXEL_MODE_GRAY
:
906 if (mode
== FT_RENDER_MODE_LCD
||
907 mode
== FT_RENDER_MODE_LCD_V
)
909 /* each pixel is replicated into a 32-bit ARGB value */
914 case FT_PIXEL_MODE_LCD
:
915 if (mode
!= FT_RENDER_MODE_LCD
)
918 /* horz pixel triplets are packed into 32-bit ARGB values */
923 case FT_PIXEL_MODE_LCD_V
:
924 if (mode
!= FT_RENDER_MODE_LCD_V
)
927 /* vert pixel triplets are packed into 32-bit ARGB values */
932 default: /* unsupported source format */
936 target
->width
= width
;
937 target
->rows
= height
;
938 target
->pitch
= pitch
;
939 target
->buffer
= NULL
;
941 return pitch
* height
;
944 /* this functions converts the glyph bitmap found in a FT_GlyphSlot
945 * into a different format (see _compute_xrender_bitmap_size)
947 * you should call this function after _compute_xrender_bitmap_size
949 * target :: target bitmap descriptor. Note that its 'buffer' pointer
950 * must point to memory allocated by the caller
952 * slot :: the glyph slot containing the source bitmap
954 * mode :: the requested final rendering mode
956 * bgr :: boolean, set if BGR or VBGR pixel ordering is needed
959 _fill_xrender_bitmap(FT_Bitmap
*target
,
964 FT_Bitmap
*ftbit
= &slot
->bitmap
;
965 unsigned char *srcLine
= ftbit
->buffer
;
966 unsigned char *dstLine
= target
->buffer
;
967 int src_pitch
= ftbit
->pitch
;
968 int width
= target
->width
;
969 int height
= target
->rows
;
970 int pitch
= target
->pitch
;
974 subpixel
= (mode
== FT_RENDER_MODE_LCD
||
975 mode
== FT_RENDER_MODE_LCD_V
);
978 srcLine
-= src_pitch
* (ftbit
->rows
- 1);
980 target
->pixel_mode
= ftbit
->pixel_mode
;
982 switch (ftbit
->pixel_mode
) {
983 case FT_PIXEL_MODE_MONO
:
985 /* convert mono to ARGB32 values */
987 for (h
= height
; h
> 0; h
--, srcLine
+= src_pitch
, dstLine
+= pitch
) {
990 for (x
= 0; x
< width
; x
++) {
991 if (srcLine
[(x
>> 3)] & (0x80 >> (x
& 7)))
992 ((unsigned int *) dstLine
)[x
] = 0xffffffffU
;
995 target
->pixel_mode
= FT_PIXEL_MODE_LCD
;
997 } else if (mode
== FT_RENDER_MODE_NORMAL
) {
998 /* convert mono to 8-bit gray */
1000 for (h
= height
; h
> 0; h
--, srcLine
+= src_pitch
, dstLine
+= pitch
) {
1003 for (x
= 0; x
< width
; x
++) {
1004 if (srcLine
[(x
>> 3)] & (0x80 >> (x
& 7)))
1008 target
->pixel_mode
= FT_PIXEL_MODE_GRAY
;
1011 /* copy mono to mono */
1013 int bytes
= (width
+ 7) >> 3;
1015 for (h
= height
; h
> 0; h
--, srcLine
+= src_pitch
, dstLine
+= pitch
)
1016 memcpy (dstLine
, srcLine
, bytes
);
1020 case FT_PIXEL_MODE_GRAY
:
1022 /* convert gray to ARGB32 values */
1024 for (h
= height
; h
> 0; h
--, srcLine
+= src_pitch
, dstLine
+= pitch
) {
1026 unsigned int *dst
= (unsigned int *) dstLine
;
1028 for (x
= 0; x
< width
; x
++) {
1029 unsigned int pix
= srcLine
[x
];
1037 target
->pixel_mode
= FT_PIXEL_MODE_LCD
;
1039 /* copy gray into gray */
1041 for (h
= height
; h
> 0; h
--, srcLine
+= src_pitch
, dstLine
+= pitch
)
1042 memcpy (dstLine
, srcLine
, width
);
1046 case FT_PIXEL_MODE_LCD
:
1048 /* convert horizontal RGB into ARGB32 */
1050 for (h
= height
; h
> 0; h
--, srcLine
+= src_pitch
, dstLine
+= pitch
) {
1052 unsigned char *src
= srcLine
;
1053 unsigned int *dst
= (unsigned int *) dstLine
;
1055 for (x
= 0; x
< width
; x
++, src
+= 3) {
1058 pix
= ((unsigned int)src
[0] << 16) |
1059 ((unsigned int)src
[1] << 8) |
1060 ((unsigned int)src
[2] ) |
1061 ((unsigned int)src
[1] << 24) ;
1067 /* convert horizontal BGR into ARGB32 */
1069 for (h
= height
; h
> 0; h
--, srcLine
+= src_pitch
, dstLine
+= pitch
) {
1072 unsigned char *src
= srcLine
;
1073 unsigned int *dst
= (unsigned int *) dstLine
;
1075 for (x
= 0; x
< width
; x
++, src
+= 3) {
1078 pix
= ((unsigned int)src
[2] << 16) |
1079 ((unsigned int)src
[1] << 8) |
1080 ((unsigned int)src
[0] ) |
1081 ((unsigned int)src
[1] << 24) ;
1089 default: /* FT_PIXEL_MODE_LCD_V */
1090 /* convert vertical RGB into ARGB32 */
1093 for (h
= height
; h
> 0; h
--, srcLine
+= 3 * src_pitch
, dstLine
+= pitch
) {
1095 unsigned char* src
= srcLine
;
1096 unsigned int* dst
= (unsigned int *) dstLine
;
1098 for (x
= 0; x
< width
; x
++, src
+= 1) {
1100 pix
= ((unsigned int)src
[0] << 16) |
1101 ((unsigned int)src
[src_pitch
] << 8) |
1102 ((unsigned int)src
[src_pitch
*2] ) |
1103 ((unsigned int)src
[src_pitch
] << 24) ;
1109 for (h
= height
; h
> 0; h
--, srcLine
+= 3*src_pitch
, dstLine
+= pitch
) {
1111 unsigned char *src
= srcLine
;
1112 unsigned int *dst
= (unsigned int *) dstLine
;
1114 for (x
= 0; x
< width
; x
++, src
+= 1) {
1117 pix
= ((unsigned int)src
[src_pitch
* 2] << 16) |
1118 ((unsigned int)src
[src_pitch
] << 8) |
1119 ((unsigned int)src
[0] ) |
1120 ((unsigned int)src
[src_pitch
] << 24) ;
1130 /* Fills in val->image with an image surface created from @bitmap
1132 static cairo_status_t
1133 _get_bitmap_surface (FT_Bitmap
*bitmap
,
1135 cairo_bool_t own_buffer
,
1136 cairo_font_options_t
*font_options
,
1137 cairo_image_surface_t
**surface
)
1139 unsigned int width
, height
;
1140 unsigned char *data
;
1141 int format
= CAIRO_FORMAT_A8
;
1143 cairo_image_surface_t
*image
;
1144 cairo_bool_t component_alpha
= FALSE
;
1146 width
= bitmap
->width
;
1147 height
= bitmap
->rows
;
1149 if (width
== 0 || height
== 0) {
1150 *surface
= (cairo_image_surface_t
*)
1151 cairo_image_surface_create_for_data (NULL
, format
, 0, 0, 0);
1152 return (*surface
)->base
.status
;
1155 switch (bitmap
->pixel_mode
) {
1156 case FT_PIXEL_MODE_MONO
:
1157 stride
= (((width
+ 31) & ~31) >> 3);
1159 data
= bitmap
->buffer
;
1160 assert (stride
== bitmap
->pitch
);
1162 data
= _cairo_malloc_ab (height
, stride
);
1164 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1166 if (stride
== bitmap
->pitch
) {
1167 memcpy (data
, bitmap
->buffer
, stride
* height
);
1170 unsigned char *source
, *dest
;
1172 source
= bitmap
->buffer
;
1174 for (i
= height
; i
; i
--) {
1175 memcpy (dest
, source
, bitmap
->pitch
);
1176 memset (dest
+ bitmap
->pitch
, '\0', stride
- bitmap
->pitch
);
1178 source
+= bitmap
->pitch
;
1184 #ifndef WORDS_BIGENDIAN
1187 int count
= stride
* height
;
1190 *d
= CAIRO_BITSWAP8 (*d
);
1195 format
= CAIRO_FORMAT_A1
;
1198 case FT_PIXEL_MODE_LCD
:
1199 case FT_PIXEL_MODE_LCD_V
:
1200 case FT_PIXEL_MODE_GRAY
:
1201 if (font_options
->antialias
!= CAIRO_ANTIALIAS_SUBPIXEL
||
1202 bitmap
->pixel_mode
== FT_PIXEL_MODE_GRAY
)
1204 stride
= bitmap
->pitch
;
1206 /* We don't support stride not multiple of 4. */
1209 assert (!own_buffer
);
1214 data
= bitmap
->buffer
;
1216 data
= _cairo_malloc_ab (height
, stride
);
1218 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1220 memcpy (data
, bitmap
->buffer
, stride
* height
);
1223 format
= CAIRO_FORMAT_A8
;
1225 data
= bitmap
->buffer
;
1226 stride
= bitmap
->pitch
;
1227 format
= CAIRO_FORMAT_ARGB32
;
1228 component_alpha
= TRUE
;
1231 #ifdef FT_LOAD_COLOR
1232 case FT_PIXEL_MODE_BGRA
:
1235 data
= bitmap
->buffer
;
1237 data
= _cairo_malloc_ab (height
, stride
);
1239 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1241 memcpy (data
, bitmap
->buffer
, stride
* height
);
1243 format
= CAIRO_FORMAT_ARGB32
;
1246 case FT_PIXEL_MODE_GRAY2
:
1247 case FT_PIXEL_MODE_GRAY4
:
1249 if (!own_buffer
&& library
)
1251 /* This is pretty much the only case that we can get in here. */
1252 /* Convert to 8bit grayscale. */
1258 format
= CAIRO_FORMAT_A8
;
1260 align
= cairo_format_stride_for_width (format
, bitmap
->width
);
1262 FT_Bitmap_New( &tmp
);
1264 error
= FT_Bitmap_Convert( library
, bitmap
, &tmp
, align
);
1266 return _cairo_error (_ft_to_cairo_error (error
));
1268 FT_Bitmap_Done( library
, bitmap
);
1271 stride
= bitmap
->pitch
;
1272 data
= _cairo_malloc_ab (height
, stride
);
1274 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1276 if (bitmap
->num_grays
!= 256)
1279 unsigned int mul
= 255 / (bitmap
->num_grays
- 1);
1280 FT_Byte
*p
= bitmap
->buffer
;
1281 for (y
= 0; y
< height
; y
++) {
1282 for (x
= 0; x
< width
; x
++)
1288 memcpy (data
, bitmap
->buffer
, stride
* height
);
1291 /* These could be triggered by very rare types of TrueType fonts */
1294 free (bitmap
->buffer
);
1295 return _cairo_error (CAIRO_STATUS_INVALID_FORMAT
);
1299 *surface
= image
= (cairo_image_surface_t
*)
1300 cairo_image_surface_create_for_data (data
,
1302 width
, height
, stride
);
1303 if (image
->base
.status
) {
1305 return (*surface
)->base
.status
;
1308 if (component_alpha
)
1309 pixman_image_set_component_alpha (image
->pixman_image
, TRUE
);
1311 _cairo_image_surface_assume_ownership_of_data (image
);
1313 _cairo_debug_check_image_surface_is_defined (&image
->base
);
1315 return CAIRO_STATUS_SUCCESS
;
1318 /* Converts an outline FT_GlyphSlot into an image
1320 * This could go through _render_glyph_bitmap as well, letting
1321 * FreeType convert the outline to a bitmap, but doing it ourselves
1322 * has two minor advantages: first, we save a copy of the bitmap
1323 * buffer: we can directly use the buffer that FreeType renders
1326 * Second, it may help when we add support for subpixel
1327 * rendering: the Xft code does it this way. (Keith thinks that
1328 * it may also be possible to get the subpixel rendering with
1329 * FT_Render_Glyph: something worth looking into in more detail
1330 * when we add subpixel support. If so, we may want to eliminate
1331 * this version of the code path entirely.
1333 static cairo_status_t
1334 _render_glyph_outline (FT_Face face
,
1335 cairo_font_options_t
*font_options
,
1336 cairo_image_surface_t
**surface
)
1338 int rgba
= FC_RGBA_UNKNOWN
;
1339 int lcd_filter
= FT_LCD_FILTER_LEGACY
;
1340 FT_GlyphSlot glyphslot
= face
->glyph
;
1341 FT_Outline
*outline
= &glyphslot
->outline
;
1344 unsigned int width
, height
;
1345 cairo_status_t status
;
1347 FT_Library library
= glyphslot
->library
;
1348 FT_Render_Mode render_mode
= FT_RENDER_MODE_NORMAL
;
1350 switch (font_options
->antialias
) {
1351 case CAIRO_ANTIALIAS_NONE
:
1352 render_mode
= FT_RENDER_MODE_MONO
;
1355 case CAIRO_ANTIALIAS_SUBPIXEL
:
1356 case CAIRO_ANTIALIAS_BEST
:
1357 switch (font_options
->subpixel_order
) {
1358 case CAIRO_SUBPIXEL_ORDER_DEFAULT
:
1359 case CAIRO_SUBPIXEL_ORDER_RGB
:
1360 case CAIRO_SUBPIXEL_ORDER_BGR
:
1361 render_mode
= FT_RENDER_MODE_LCD
;
1364 case CAIRO_SUBPIXEL_ORDER_VRGB
:
1365 case CAIRO_SUBPIXEL_ORDER_VBGR
:
1366 render_mode
= FT_RENDER_MODE_LCD_V
;
1370 switch (font_options
->lcd_filter
) {
1371 case CAIRO_LCD_FILTER_NONE
:
1372 lcd_filter
= FT_LCD_FILTER_NONE
;
1374 case CAIRO_LCD_FILTER_DEFAULT
:
1375 case CAIRO_LCD_FILTER_INTRA_PIXEL
:
1376 lcd_filter
= FT_LCD_FILTER_LEGACY
;
1378 case CAIRO_LCD_FILTER_FIR3
:
1379 lcd_filter
= FT_LCD_FILTER_LIGHT
;
1381 case CAIRO_LCD_FILTER_FIR5
:
1382 lcd_filter
= FT_LCD_FILTER_DEFAULT
;
1388 case CAIRO_ANTIALIAS_DEFAULT
:
1389 case CAIRO_ANTIALIAS_GRAY
:
1390 case CAIRO_ANTIALIAS_GOOD
:
1391 case CAIRO_ANTIALIAS_FAST
:
1392 render_mode
= FT_RENDER_MODE_NORMAL
;
1395 FT_Outline_Get_CBox (outline
, &cbox
);
1399 cbox
.xMax
= (cbox
.xMax
+ 63) & -64;
1400 cbox
.yMax
= (cbox
.yMax
+ 63) & -64;
1402 width
= (unsigned int) ((cbox
.xMax
- cbox
.xMin
) >> 6);
1403 height
= (unsigned int) ((cbox
.yMax
- cbox
.yMin
) >> 6);
1405 if (width
* height
== 0) {
1406 cairo_format_t format
;
1407 /* Looks like fb handles zero-sized images just fine */
1408 switch (render_mode
) {
1409 case FT_RENDER_MODE_MONO
:
1410 format
= CAIRO_FORMAT_A1
;
1412 case FT_RENDER_MODE_LCD
:
1413 case FT_RENDER_MODE_LCD_V
:
1414 format
= CAIRO_FORMAT_ARGB32
;
1416 case FT_RENDER_MODE_LIGHT
:
1417 case FT_RENDER_MODE_NORMAL
:
1418 case FT_RENDER_MODE_MAX
:
1420 format
= CAIRO_FORMAT_A8
;
1424 (*surface
) = (cairo_image_surface_t
*)
1425 cairo_image_surface_create_for_data (NULL
, format
, 0, 0, 0);
1426 if ((*surface
)->base
.status
)
1427 return (*surface
)->base
.status
;
1432 switch (render_mode
) {
1433 case FT_RENDER_MODE_LCD
:
1434 if (font_options
->subpixel_order
== CAIRO_SUBPIXEL_ORDER_BGR
)
1440 case FT_RENDER_MODE_LCD_V
:
1441 if (font_options
->subpixel_order
== CAIRO_SUBPIXEL_ORDER_VBGR
)
1442 rgba
= FC_RGBA_VBGR
;
1444 rgba
= FC_RGBA_VRGB
;
1447 case FT_RENDER_MODE_MONO
:
1448 case FT_RENDER_MODE_LIGHT
:
1449 case FT_RENDER_MODE_NORMAL
:
1450 case FT_RENDER_MODE_MAX
:
1455 #if HAVE_FT_LIBRARY_SETLCDFILTER
1456 FT_Library_SetLcdFilter (library
, lcd_filter
);
1459 error
= FT_Render_Glyph (face
->glyph
, render_mode
);
1461 #if HAVE_FT_LIBRARY_SETLCDFILTER
1462 FT_Library_SetLcdFilter (library
, FT_LCD_FILTER_NONE
);
1466 return _cairo_error (_ft_to_cairo_error (error
));
1468 bitmap_size
= _compute_xrender_bitmap_size (&bitmap
,
1471 if (bitmap_size
< 0)
1472 return _cairo_error (CAIRO_STATUS_INVALID_FORMAT
);
1474 bitmap
.buffer
= calloc (1, bitmap_size
);
1475 if (bitmap
.buffer
== NULL
)
1476 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1478 _fill_xrender_bitmap (&bitmap
, face
->glyph
, render_mode
,
1479 (rgba
== FC_RGBA_BGR
|| rgba
== FC_RGBA_VBGR
));
1482 * _get_bitmap_surface will free bitmap.buffer if there is an error
1484 status
= _get_bitmap_surface (&bitmap
, NULL
, TRUE
, font_options
, surface
);
1485 if (unlikely (status
))
1488 /* Note: the font's coordinate system is upside down from ours, so the
1489 * Y coordinate of the control box needs to be negated. Moreover, device
1490 * offsets are position of glyph origin relative to top left while xMin
1491 * and yMax are offsets of top left relative to origin. Another negation.
1493 cairo_surface_set_device_offset (&(*surface
)->base
,
1494 (double)-glyphslot
->bitmap_left
,
1495 (double)+glyphslot
->bitmap_top
);
1498 return CAIRO_STATUS_SUCCESS
;
1501 /* Converts a bitmap (or other) FT_GlyphSlot into an image */
1502 static cairo_status_t
1503 _render_glyph_bitmap (FT_Face face
,
1504 cairo_font_options_t
*font_options
,
1505 cairo_image_surface_t
**surface
)
1507 FT_GlyphSlot glyphslot
= face
->glyph
;
1508 cairo_status_t status
;
1511 /* According to the FreeType docs, glyphslot->format could be
1512 * something other than FT_GLYPH_FORMAT_OUTLINE or
1513 * FT_GLYPH_FORMAT_BITMAP. Calling FT_Render_Glyph gives FreeType
1514 * the opportunity to convert such to
1515 * bitmap. FT_GLYPH_FORMAT_COMPOSITE will not be encountered since
1516 * we avoid the FT_LOAD_NO_RECURSE flag.
1518 error
= FT_Render_Glyph (glyphslot
, FT_RENDER_MODE_NORMAL
);
1519 /* XXX ignoring all other errors for now. They are not fatal, typically
1520 * just a glyph-not-found. */
1521 if (error
== FT_Err_Out_Of_Memory
)
1522 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1524 status
= _get_bitmap_surface (&glyphslot
->bitmap
,
1526 FALSE
, font_options
,
1528 if (unlikely (status
))
1532 * Note: the font's coordinate system is upside down from ours, so the
1533 * Y coordinate of the control box needs to be negated. Moreover, device
1534 * offsets are position of glyph origin relative to top left while
1535 * bitmap_left and bitmap_top are offsets of top left relative to origin.
1538 cairo_surface_set_device_offset (&(*surface
)->base
,
1539 -glyphslot
->bitmap_left
,
1540 +glyphslot
->bitmap_top
);
1542 return CAIRO_STATUS_SUCCESS
;
1545 static cairo_status_t
1546 _transform_glyph_bitmap (cairo_matrix_t
* shape
,
1547 cairo_image_surface_t
** surface
)
1549 cairo_matrix_t original_to_transformed
;
1550 cairo_matrix_t transformed_to_original
;
1551 cairo_image_surface_t
*old_image
;
1552 cairo_surface_t
*image
;
1554 double origin_x
, origin_y
;
1555 int orig_width
, orig_height
;
1557 int x_min
, y_min
, x_max
, y_max
;
1559 cairo_status_t status
;
1560 cairo_surface_pattern_t pattern
;
1562 /* We want to compute a transform that takes the origin
1563 * (device_x_offset, device_y_offset) to 0,0, then applies
1564 * the "shape" portion of the font transform
1566 original_to_transformed
= *shape
;
1568 cairo_surface_get_device_offset (&(*surface
)->base
, &origin_x
, &origin_y
);
1569 orig_width
= (*surface
)->width
;
1570 orig_height
= (*surface
)->height
;
1572 cairo_matrix_translate (&original_to_transformed
,
1573 -origin_x
, -origin_y
);
1575 /* Find the bounding box of the original bitmap under that
1579 x
[1] = orig_width
; y
[1] = 0;
1580 x
[2] = orig_width
; y
[2] = orig_height
;
1581 x
[3] = 0; y
[3] = orig_height
;
1583 for (i
= 0; i
< 4; i
++)
1584 cairo_matrix_transform_point (&original_to_transformed
,
1587 x_min
= floor (x
[0]); y_min
= floor (y
[0]);
1588 x_max
= ceil (x
[0]); y_max
= ceil (y
[0]);
1590 for (i
= 1; i
< 4; i
++) {
1592 x_min
= floor (x
[i
]);
1593 else if (x
[i
] > x_max
)
1594 x_max
= ceil (x
[i
]);
1596 y_min
= floor (y
[i
]);
1597 else if (y
[i
] > y_max
)
1598 y_max
= ceil (y
[i
]);
1601 /* Adjust the transform so that the bounding box starts at 0,0 ...
1602 * this gives our final transform from original bitmap to transformed
1605 original_to_transformed
.x0
-= x_min
;
1606 original_to_transformed
.y0
-= y_min
;
1608 /* Create the transformed bitmap */
1609 width
= x_max
- x_min
;
1610 height
= y_max
- y_min
;
1612 transformed_to_original
= original_to_transformed
;
1613 status
= cairo_matrix_invert (&transformed_to_original
);
1614 if (unlikely (status
))
1617 if ((*surface
)->format
== CAIRO_FORMAT_ARGB32
&&
1618 !pixman_image_get_component_alpha ((*surface
)->pixman_image
))
1619 image
= cairo_image_surface_create (CAIRO_FORMAT_ARGB32
, width
, height
);
1621 image
= cairo_image_surface_create (CAIRO_FORMAT_A8
, width
, height
);
1622 if (unlikely (image
->status
))
1623 return image
->status
;
1625 /* Draw the original bitmap transformed into the new bitmap
1627 _cairo_pattern_init_for_surface (&pattern
, &(*surface
)->base
);
1628 cairo_pattern_set_matrix (&pattern
.base
, &transformed_to_original
);
1630 status
= _cairo_surface_paint (image
,
1631 CAIRO_OPERATOR_SOURCE
,
1635 _cairo_pattern_fini (&pattern
.base
);
1637 if (unlikely (status
)) {
1638 cairo_surface_destroy (image
);
1642 /* Now update the cache entry for the new bitmap, recomputing
1643 * the origin based on the final transform.
1645 cairo_matrix_transform_point (&original_to_transformed
,
1646 &origin_x
, &origin_y
);
1648 old_image
= (*surface
);
1649 (*surface
) = (cairo_image_surface_t
*)image
;
1650 cairo_surface_destroy (&old_image
->base
);
1652 cairo_surface_set_device_offset (&(*surface
)->base
,
1653 _cairo_lround (origin_x
),
1654 _cairo_lround (origin_y
));
1655 return CAIRO_STATUS_SUCCESS
;
1658 static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend
= {
1659 _cairo_ft_unscaled_font_destroy
,
1661 _cairo_ft_unscaled_font_create_glyph
1665 /* #cairo_ft_scaled_font_t */
1667 typedef struct _cairo_ft_scaled_font
{
1668 cairo_scaled_font_t base
;
1669 cairo_ft_unscaled_font_t
*unscaled
;
1670 cairo_ft_options_t ft_options
;
1671 } cairo_ft_scaled_font_t
;
1673 static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend
;
1675 #if CAIRO_HAS_FC_FONT
1676 /* The load flags passed to FT_Load_Glyph control aspects like hinting and
1677 * antialiasing. Here we compute them from the fields of a FcPattern.
1680 _get_pattern_ft_options (FcPattern
*pattern
, cairo_ft_options_t
*ret
)
1682 FcBool antialias
, vertical_layout
, hinting
, autohint
, bitmap
, embolden
;
1683 cairo_ft_options_t ft_options
;
1685 #ifdef FC_HINT_STYLE
1689 _cairo_font_options_init_default (&ft_options
.base
);
1690 ft_options
.load_flags
= FT_LOAD_DEFAULT
;
1691 ft_options
.synth_flags
= 0;
1693 #ifndef FC_EMBEDDED_BITMAP
1694 #define FC_EMBEDDED_BITMAP "embeddedbitmap"
1697 /* Check whether to force use of embedded bitmaps */
1698 if (FcPatternGetBool (pattern
,
1699 FC_EMBEDDED_BITMAP
, 0, &bitmap
) != FcResultMatch
)
1702 /* disable antialiasing if requested */
1703 if (FcPatternGetBool (pattern
,
1704 FC_ANTIALIAS
, 0, &antialias
) != FcResultMatch
)
1708 cairo_subpixel_order_t subpixel_order
;
1711 /* disable hinting if requested */
1712 if (FcPatternGetBool (pattern
,
1713 FC_HINTING
, 0, &hinting
) != FcResultMatch
)
1716 if (FcPatternGetInteger (pattern
,
1717 FC_RGBA
, 0, &rgba
) != FcResultMatch
)
1718 rgba
= FC_RGBA_UNKNOWN
;
1722 subpixel_order
= CAIRO_SUBPIXEL_ORDER_RGB
;
1725 subpixel_order
= CAIRO_SUBPIXEL_ORDER_BGR
;
1728 subpixel_order
= CAIRO_SUBPIXEL_ORDER_VRGB
;
1731 subpixel_order
= CAIRO_SUBPIXEL_ORDER_VBGR
;
1733 case FC_RGBA_UNKNOWN
:
1736 subpixel_order
= CAIRO_SUBPIXEL_ORDER_DEFAULT
;
1740 if (subpixel_order
!= CAIRO_SUBPIXEL_ORDER_DEFAULT
) {
1741 ft_options
.base
.subpixel_order
= subpixel_order
;
1742 ft_options
.base
.antialias
= CAIRO_ANTIALIAS_SUBPIXEL
;
1745 if (FcPatternGetInteger (pattern
,
1746 FC_LCD_FILTER
, 0, &lcd_filter
) == FcResultMatch
)
1748 switch (lcd_filter
) {
1750 ft_options
.base
.lcd_filter
= CAIRO_LCD_FILTER_NONE
;
1752 case FC_LCD_DEFAULT
:
1753 ft_options
.base
.lcd_filter
= CAIRO_LCD_FILTER_FIR5
;
1756 ft_options
.base
.lcd_filter
= CAIRO_LCD_FILTER_FIR3
;
1759 ft_options
.base
.lcd_filter
= CAIRO_LCD_FILTER_INTRA_PIXEL
;
1764 #ifdef FC_HINT_STYLE
1765 if (FcPatternGetInteger (pattern
,
1766 FC_HINT_STYLE
, 0, &hintstyle
) != FcResultMatch
)
1767 hintstyle
= FC_HINT_FULL
;
1770 hintstyle
= FC_HINT_NONE
;
1772 switch (hintstyle
) {
1774 ft_options
.base
.hint_style
= CAIRO_HINT_STYLE_NONE
;
1776 case FC_HINT_SLIGHT
:
1777 ft_options
.base
.hint_style
= CAIRO_HINT_STYLE_SLIGHT
;
1779 case FC_HINT_MEDIUM
:
1781 ft_options
.base
.hint_style
= CAIRO_HINT_STYLE_MEDIUM
;
1784 ft_options
.base
.hint_style
= CAIRO_HINT_STYLE_FULL
;
1787 #else /* !FC_HINT_STYLE */
1789 ft_options
.base
.hint_style
= CAIRO_HINT_STYLE_NONE
;
1791 #endif /* FC_HINT_STYLE */
1793 /* Force embedded bitmaps off if no hinting requested */
1794 if (ft_options
.base
.hint_style
== CAIRO_HINT_STYLE_NONE
)
1798 ft_options
.load_flags
|= FT_LOAD_NO_BITMAP
;
1801 ft_options
.base
.antialias
= CAIRO_ANTIALIAS_NONE
;
1804 /* force autohinting if requested */
1805 if (FcPatternGetBool (pattern
,
1806 FC_AUTOHINT
, 0, &autohint
) != FcResultMatch
)
1810 ft_options
.load_flags
|= FT_LOAD_FORCE_AUTOHINT
;
1812 if (FcPatternGetBool (pattern
,
1813 FC_VERTICAL_LAYOUT
, 0, &vertical_layout
) != FcResultMatch
)
1814 vertical_layout
= FcFalse
;
1816 if (vertical_layout
)
1817 ft_options
.load_flags
|= FT_LOAD_VERTICAL_LAYOUT
;
1820 #define FC_EMBOLDEN "embolden"
1822 if (FcPatternGetBool (pattern
,
1823 FC_EMBOLDEN
, 0, &embolden
) != FcResultMatch
)
1827 ft_options
.synth_flags
|= CAIRO_FT_SYNTHESIZE_BOLD
;
1834 _cairo_ft_options_merge (cairo_ft_options_t
*options
,
1835 cairo_ft_options_t
*other
)
1837 int load_flags
= other
->load_flags
;
1838 int load_target
= FT_LOAD_TARGET_NORMAL
;
1840 /* clear load target mode */
1841 load_flags
&= ~(FT_LOAD_TARGET_(FT_LOAD_TARGET_MODE(other
->load_flags
)));
1843 if (load_flags
& FT_LOAD_NO_HINTING
)
1844 other
->base
.hint_style
= CAIRO_HINT_STYLE_NONE
;
1846 if (other
->base
.antialias
== CAIRO_ANTIALIAS_NONE
||
1847 options
->base
.antialias
== CAIRO_ANTIALIAS_NONE
) {
1848 options
->base
.antialias
= CAIRO_ANTIALIAS_NONE
;
1849 options
->base
.subpixel_order
= CAIRO_SUBPIXEL_ORDER_DEFAULT
;
1852 if (other
->base
.antialias
== CAIRO_ANTIALIAS_SUBPIXEL
&&
1853 (options
->base
.antialias
== CAIRO_ANTIALIAS_DEFAULT
||
1854 options
->base
.antialias
== CAIRO_ANTIALIAS_GRAY
)) {
1855 options
->base
.antialias
= CAIRO_ANTIALIAS_SUBPIXEL
;
1856 options
->base
.subpixel_order
= other
->base
.subpixel_order
;
1859 if (options
->base
.hint_style
== CAIRO_HINT_STYLE_DEFAULT
)
1860 options
->base
.hint_style
= other
->base
.hint_style
;
1862 if (other
->base
.hint_style
== CAIRO_HINT_STYLE_NONE
)
1863 options
->base
.hint_style
= CAIRO_HINT_STYLE_NONE
;
1865 if (options
->base
.lcd_filter
== CAIRO_LCD_FILTER_DEFAULT
)
1866 options
->base
.lcd_filter
= other
->base
.lcd_filter
;
1868 if (other
->base
.lcd_filter
== CAIRO_LCD_FILTER_NONE
)
1869 options
->base
.lcd_filter
= CAIRO_LCD_FILTER_NONE
;
1871 if (options
->base
.antialias
== CAIRO_ANTIALIAS_NONE
) {
1872 if (options
->base
.hint_style
== CAIRO_HINT_STYLE_NONE
)
1873 load_flags
|= FT_LOAD_NO_HINTING
;
1875 load_target
= FT_LOAD_TARGET_MONO
;
1876 load_flags
|= FT_LOAD_MONOCHROME
;
1878 switch (options
->base
.hint_style
) {
1879 case CAIRO_HINT_STYLE_NONE
:
1880 load_flags
|= FT_LOAD_NO_HINTING
;
1882 case CAIRO_HINT_STYLE_SLIGHT
:
1883 load_target
= FT_LOAD_TARGET_LIGHT
;
1885 case CAIRO_HINT_STYLE_MEDIUM
:
1887 case CAIRO_HINT_STYLE_FULL
:
1888 case CAIRO_HINT_STYLE_DEFAULT
:
1889 if (options
->base
.antialias
== CAIRO_ANTIALIAS_SUBPIXEL
) {
1890 switch (options
->base
.subpixel_order
) {
1891 case CAIRO_SUBPIXEL_ORDER_DEFAULT
:
1892 case CAIRO_SUBPIXEL_ORDER_RGB
:
1893 case CAIRO_SUBPIXEL_ORDER_BGR
:
1894 load_target
= FT_LOAD_TARGET_LCD
;
1896 case CAIRO_SUBPIXEL_ORDER_VRGB
:
1897 case CAIRO_SUBPIXEL_ORDER_VBGR
:
1898 load_target
= FT_LOAD_TARGET_LCD_V
;
1906 options
->load_flags
= load_flags
| load_target
;
1907 options
->synth_flags
= other
->synth_flags
;
1910 static cairo_status_t
1911 _cairo_ft_font_face_scaled_font_create (void *abstract_font_face
,
1912 const cairo_matrix_t
*font_matrix
,
1913 const cairo_matrix_t
*ctm
,
1914 const cairo_font_options_t
*options
,
1915 cairo_scaled_font_t
**font_out
)
1917 cairo_ft_font_face_t
*font_face
= abstract_font_face
;
1918 cairo_ft_scaled_font_t
*scaled_font
;
1920 FT_Size_Metrics
*metrics
;
1921 cairo_font_extents_t fs_metrics
;
1922 cairo_status_t status
;
1923 cairo_ft_unscaled_font_t
*unscaled
;
1925 assert (font_face
->unscaled
);
1927 face
= _cairo_ft_unscaled_font_lock_face (font_face
->unscaled
);
1928 if (unlikely (face
== NULL
)) /* backend error */
1929 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1931 scaled_font
= malloc (sizeof (cairo_ft_scaled_font_t
));
1932 if (unlikely (scaled_font
== NULL
)) {
1933 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1937 scaled_font
->unscaled
= unscaled
= font_face
->unscaled
;
1938 _cairo_unscaled_font_reference (&unscaled
->base
);
1940 _cairo_font_options_init_copy (&scaled_font
->ft_options
.base
, options
);
1941 _cairo_ft_options_merge (&scaled_font
->ft_options
, &font_face
->ft_options
);
1943 status
= _cairo_scaled_font_init (&scaled_font
->base
,
1945 font_matrix
, ctm
, options
,
1946 &_cairo_ft_scaled_font_backend
);
1947 if (unlikely (status
))
1948 goto CLEANUP_SCALED_FONT
;
1950 status
= _cairo_ft_unscaled_font_set_scale (unscaled
,
1951 &scaled_font
->base
.scale
);
1952 if (unlikely (status
)) {
1953 /* This can only fail if we encounter an error with the underlying
1954 * font, so propagate the error back to the font-face. */
1955 _cairo_ft_unscaled_font_unlock_face (unscaled
);
1956 _cairo_unscaled_font_destroy (&unscaled
->base
);
1962 metrics
= &face
->size
->metrics
;
1965 * Get to unscaled metrics so that the upper level can get back to
1968 * Also use this path for bitmap-only fonts. The other branch uses
1969 * face members that are only relevant for scalable fonts. This is
1970 * detected by simply checking for units_per_EM==0.
1972 if (scaled_font
->base
.options
.hint_metrics
!= CAIRO_HINT_METRICS_OFF
||
1973 face
->units_per_EM
== 0) {
1974 double x_factor
, y_factor
;
1976 if (unscaled
->x_scale
== 0)
1979 x_factor
= 1 / unscaled
->x_scale
;
1981 if (unscaled
->y_scale
== 0)
1984 y_factor
= 1 / unscaled
->y_scale
;
1986 fs_metrics
.ascent
= DOUBLE_FROM_26_6(metrics
->ascender
) * y_factor
;
1987 fs_metrics
.descent
= DOUBLE_FROM_26_6(- metrics
->descender
) * y_factor
;
1988 fs_metrics
.height
= DOUBLE_FROM_26_6(metrics
->height
) * y_factor
;
1989 if (!_cairo_ft_scaled_font_is_vertical (&scaled_font
->base
)) {
1990 fs_metrics
.max_x_advance
= DOUBLE_FROM_26_6(metrics
->max_advance
) * x_factor
;
1991 fs_metrics
.max_y_advance
= 0;
1993 fs_metrics
.max_x_advance
= 0;
1994 fs_metrics
.max_y_advance
= DOUBLE_FROM_26_6(metrics
->max_advance
) * y_factor
;
1997 double scale
= face
->units_per_EM
;
1999 fs_metrics
.ascent
= face
->ascender
/ scale
;
2000 fs_metrics
.descent
= - face
->descender
/ scale
;
2001 fs_metrics
.height
= face
->height
/ scale
;
2002 if (!_cairo_ft_scaled_font_is_vertical (&scaled_font
->base
)) {
2003 fs_metrics
.max_x_advance
= face
->max_advance_width
/ scale
;
2004 fs_metrics
.max_y_advance
= 0;
2006 fs_metrics
.max_x_advance
= 0;
2007 fs_metrics
.max_y_advance
= face
->max_advance_height
/ scale
;
2011 status
= _cairo_scaled_font_set_metrics (&scaled_font
->base
, &fs_metrics
);
2012 if (unlikely (status
))
2013 goto CLEANUP_SCALED_FONT
;
2015 _cairo_ft_unscaled_font_unlock_face (unscaled
);
2017 *font_out
= &scaled_font
->base
;
2018 return CAIRO_STATUS_SUCCESS
;
2020 CLEANUP_SCALED_FONT
:
2021 _cairo_unscaled_font_destroy (&unscaled
->base
);
2024 _cairo_ft_unscaled_font_unlock_face (font_face
->unscaled
);
2025 *font_out
= _cairo_scaled_font_create_in_error (status
);
2026 return CAIRO_STATUS_SUCCESS
; /* non-backend error */
2030 _cairo_scaled_font_is_ft (cairo_scaled_font_t
*scaled_font
)
2032 return scaled_font
->backend
== &_cairo_ft_scaled_font_backend
;
2036 _cairo_ft_scaled_font_fini (void *abstract_font
)
2038 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
2040 if (scaled_font
== NULL
)
2043 _cairo_unscaled_font_destroy (&scaled_font
->unscaled
->base
);
2047 _move_to (FT_Vector
*to
, void *closure
)
2049 cairo_path_fixed_t
*path
= closure
;
2052 x
= _cairo_fixed_from_26_6 (to
->x
);
2053 y
= _cairo_fixed_from_26_6 (to
->y
);
2055 if (_cairo_path_fixed_close_path (path
) != CAIRO_STATUS_SUCCESS
)
2057 if (_cairo_path_fixed_move_to (path
, x
, y
) != CAIRO_STATUS_SUCCESS
)
2064 _line_to (FT_Vector
*to
, void *closure
)
2066 cairo_path_fixed_t
*path
= closure
;
2069 x
= _cairo_fixed_from_26_6 (to
->x
);
2070 y
= _cairo_fixed_from_26_6 (to
->y
);
2072 if (_cairo_path_fixed_line_to (path
, x
, y
) != CAIRO_STATUS_SUCCESS
)
2079 _conic_to (FT_Vector
*control
, FT_Vector
*to
, void *closure
)
2081 cairo_path_fixed_t
*path
= closure
;
2083 cairo_fixed_t x0
, y0
;
2084 cairo_fixed_t x1
, y1
;
2085 cairo_fixed_t x2
, y2
;
2086 cairo_fixed_t x3
, y3
;
2087 cairo_point_t conic
;
2089 if (! _cairo_path_fixed_get_current_point (path
, &x0
, &y0
))
2092 conic
.x
= _cairo_fixed_from_26_6 (control
->x
);
2093 conic
.y
= _cairo_fixed_from_26_6 (control
->y
);
2095 x3
= _cairo_fixed_from_26_6 (to
->x
);
2096 y3
= _cairo_fixed_from_26_6 (to
->y
);
2098 x1
= x0
+ 2.0/3.0 * (conic
.x
- x0
);
2099 y1
= y0
+ 2.0/3.0 * (conic
.y
- y0
);
2101 x2
= x3
+ 2.0/3.0 * (conic
.x
- x3
);
2102 y2
= y3
+ 2.0/3.0 * (conic
.y
- y3
);
2104 if (_cairo_path_fixed_curve_to (path
,
2107 x3
, y3
) != CAIRO_STATUS_SUCCESS
)
2114 _cubic_to (FT_Vector
*control1
, FT_Vector
*control2
,
2115 FT_Vector
*to
, void *closure
)
2117 cairo_path_fixed_t
*path
= closure
;
2118 cairo_fixed_t x0
, y0
;
2119 cairo_fixed_t x1
, y1
;
2120 cairo_fixed_t x2
, y2
;
2122 x0
= _cairo_fixed_from_26_6 (control1
->x
);
2123 y0
= _cairo_fixed_from_26_6 (control1
->y
);
2125 x1
= _cairo_fixed_from_26_6 (control2
->x
);
2126 y1
= _cairo_fixed_from_26_6 (control2
->y
);
2128 x2
= _cairo_fixed_from_26_6 (to
->x
);
2129 y2
= _cairo_fixed_from_26_6 (to
->y
);
2131 if (_cairo_path_fixed_curve_to (path
,
2134 x2
, y2
) != CAIRO_STATUS_SUCCESS
)
2140 static cairo_status_t
2141 _decompose_glyph_outline (FT_Face face
,
2142 cairo_font_options_t
*options
,
2143 cairo_path_fixed_t
**pathp
)
2145 static const FT_Outline_Funcs outline_funcs
= {
2146 (FT_Outline_MoveToFunc
)_move_to
,
2147 (FT_Outline_LineToFunc
)_line_to
,
2148 (FT_Outline_ConicToFunc
)_conic_to
,
2149 (FT_Outline_CubicToFunc
)_cubic_to
,
2153 static const FT_Matrix invert_y
= {
2154 DOUBLE_TO_16_16 (1.0), 0,
2155 0, DOUBLE_TO_16_16 (-1.0),
2159 cairo_path_fixed_t
*path
;
2160 cairo_status_t status
;
2162 path
= _cairo_path_fixed_create ();
2164 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2166 glyph
= face
->glyph
;
2168 /* Font glyphs have an inverted Y axis compared to cairo. */
2169 FT_Outline_Transform (&glyph
->outline
, &invert_y
);
2170 if (FT_Outline_Decompose (&glyph
->outline
, &outline_funcs
, path
)) {
2171 _cairo_path_fixed_destroy (path
);
2172 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2175 status
= _cairo_path_fixed_close_path (path
);
2176 if (unlikely (status
)) {
2177 _cairo_path_fixed_destroy (path
);
2183 return CAIRO_STATUS_SUCCESS
;
2187 * Translate glyph to match its metrics.
2190 _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (void *abstract_font
,
2193 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
2196 vector
.x
= glyph
->metrics
.vertBearingX
- glyph
->metrics
.horiBearingX
;
2197 vector
.y
= -glyph
->metrics
.vertBearingY
- glyph
->metrics
.horiBearingY
;
2199 if (glyph
->format
== FT_GLYPH_FORMAT_OUTLINE
) {
2200 FT_Vector_Transform (&vector
, &scaled_font
->unscaled
->Current_Shape
);
2201 FT_Outline_Translate(&glyph
->outline
, vector
.x
, vector
.y
);
2202 } else if (glyph
->format
== FT_GLYPH_FORMAT_BITMAP
) {
2203 glyph
->bitmap_left
+= vector
.x
/ 64;
2204 glyph
->bitmap_top
+= vector
.y
/ 64;
2208 static cairo_int_status_t
2209 _cairo_ft_scaled_glyph_init (void *abstract_font
,
2210 cairo_scaled_glyph_t
*scaled_glyph
,
2211 cairo_scaled_glyph_info_t info
)
2213 cairo_text_extents_t fs_metrics
;
2214 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
2215 cairo_ft_unscaled_font_t
*unscaled
= scaled_font
->unscaled
;
2219 int load_flags
= scaled_font
->ft_options
.load_flags
;
2220 FT_Glyph_Metrics
*metrics
;
2221 double x_factor
, y_factor
;
2222 cairo_bool_t vertical_layout
= FALSE
;
2223 cairo_status_t status
;
2225 face
= _cairo_ft_unscaled_font_lock_face (unscaled
);
2227 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2229 status
= _cairo_ft_unscaled_font_set_scale (scaled_font
->unscaled
,
2230 &scaled_font
->base
.scale
);
2231 if (unlikely (status
))
2234 /* Ignore global advance unconditionally */
2235 load_flags
|= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
;
2237 if ((info
& CAIRO_SCALED_GLYPH_INFO_PATH
) != 0 &&
2238 (info
& CAIRO_SCALED_GLYPH_INFO_SURFACE
) == 0)
2239 load_flags
|= FT_LOAD_NO_BITMAP
;
2242 * Don't pass FT_LOAD_VERTICAL_LAYOUT to FT_Load_Glyph here as
2243 * suggested by freetype people.
2245 if (load_flags
& FT_LOAD_VERTICAL_LAYOUT
) {
2246 load_flags
&= ~FT_LOAD_VERTICAL_LAYOUT
;
2247 vertical_layout
= TRUE
;
2250 #ifdef FT_LOAD_COLOR
2251 /* Color-glyph support:
2253 * This flags needs plumbing through fontconfig (does it?), and
2254 * maybe we should cache color and grayscale bitmaps separately
2255 * such that users of the font (ie. the surface) can choose which
2256 * version to use based on target content type.
2258 * Moreover, none of our backends and compositors currently support
2259 * color glyphs. As such, this is currently disabled.
2261 /* load_flags |= FT_LOAD_COLOR; */
2264 error
= FT_Load_Glyph (face
,
2265 _cairo_scaled_glyph_index(scaled_glyph
),
2267 /* XXX ignoring all other errors for now. They are not fatal, typically
2268 * just a glyph-not-found. */
2269 if (error
== FT_Err_Out_Of_Memory
) {
2270 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2274 glyph
= face
->glyph
;
2277 * synthesize glyphs if requested
2279 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
2280 if (scaled_font
->ft_options
.synth_flags
& CAIRO_FT_SYNTHESIZE_BOLD
)
2281 FT_GlyphSlot_Embolden (glyph
);
2284 #if HAVE_FT_GLYPHSLOT_OBLIQUE
2285 if (scaled_font
->ft_options
.synth_flags
& CAIRO_FT_SYNTHESIZE_OBLIQUE
)
2286 FT_GlyphSlot_Oblique (glyph
);
2289 if (vertical_layout
)
2290 _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font
, glyph
);
2292 if (info
& CAIRO_SCALED_GLYPH_INFO_METRICS
) {
2294 cairo_bool_t hint_metrics
= scaled_font
->base
.options
.hint_metrics
!= CAIRO_HINT_METRICS_OFF
;
2296 * Compute font-space metrics
2298 metrics
= &glyph
->metrics
;
2300 if (unscaled
->x_scale
== 0)
2303 x_factor
= 1 / unscaled
->x_scale
;
2305 if (unscaled
->y_scale
== 0)
2308 y_factor
= 1 / unscaled
->y_scale
;
2311 * Note: Y coordinates of the horizontal bearing need to be negated.
2313 * Scale metrics back to glyph space from the scaled glyph space returned
2316 * If we want hinted metrics but aren't asking for hinted glyphs from
2317 * FreeType, then we need to do the metric hinting ourselves.
2320 if (hint_metrics
&& (load_flags
& FT_LOAD_NO_HINTING
))
2326 if (!vertical_layout
) {
2327 x1
= (metrics
->horiBearingX
) & -64;
2328 x2
= (metrics
->horiBearingX
+ metrics
->width
+ 63) & -64;
2329 y1
= (-metrics
->horiBearingY
) & -64;
2330 y2
= (-metrics
->horiBearingY
+ metrics
->height
+ 63) & -64;
2332 advance
= ((metrics
->horiAdvance
+ 32) & -64);
2334 fs_metrics
.x_bearing
= DOUBLE_FROM_26_6 (x1
) * x_factor
;
2335 fs_metrics
.y_bearing
= DOUBLE_FROM_26_6 (y1
) * y_factor
;
2337 fs_metrics
.width
= DOUBLE_FROM_26_6 (x2
- x1
) * x_factor
;
2338 fs_metrics
.height
= DOUBLE_FROM_26_6 (y2
- y1
) * y_factor
;
2340 fs_metrics
.x_advance
= DOUBLE_FROM_26_6 (advance
) * x_factor
;
2341 fs_metrics
.y_advance
= 0;
2343 x1
= (metrics
->vertBearingX
) & -64;
2344 x2
= (metrics
->vertBearingX
+ metrics
->width
+ 63) & -64;
2345 y1
= (metrics
->vertBearingY
) & -64;
2346 y2
= (metrics
->vertBearingY
+ metrics
->height
+ 63) & -64;
2348 advance
= ((metrics
->vertAdvance
+ 32) & -64);
2350 fs_metrics
.x_bearing
= DOUBLE_FROM_26_6 (x1
) * x_factor
;
2351 fs_metrics
.y_bearing
= DOUBLE_FROM_26_6 (y1
) * y_factor
;
2353 fs_metrics
.width
= DOUBLE_FROM_26_6 (x2
- x1
) * x_factor
;
2354 fs_metrics
.height
= DOUBLE_FROM_26_6 (y2
- y1
) * y_factor
;
2356 fs_metrics
.x_advance
= 0;
2357 fs_metrics
.y_advance
= DOUBLE_FROM_26_6 (advance
) * y_factor
;
2360 fs_metrics
.width
= DOUBLE_FROM_26_6 (metrics
->width
) * x_factor
;
2361 fs_metrics
.height
= DOUBLE_FROM_26_6 (metrics
->height
) * y_factor
;
2363 if (!vertical_layout
) {
2364 fs_metrics
.x_bearing
= DOUBLE_FROM_26_6 (metrics
->horiBearingX
) * x_factor
;
2365 fs_metrics
.y_bearing
= DOUBLE_FROM_26_6 (-metrics
->horiBearingY
) * y_factor
;
2367 if (hint_metrics
|| glyph
->format
!= FT_GLYPH_FORMAT_OUTLINE
)
2368 fs_metrics
.x_advance
= DOUBLE_FROM_26_6 (metrics
->horiAdvance
) * x_factor
;
2370 fs_metrics
.x_advance
= DOUBLE_FROM_16_16 (glyph
->linearHoriAdvance
) * x_factor
;
2371 fs_metrics
.y_advance
= 0 * y_factor
;
2373 fs_metrics
.x_bearing
= DOUBLE_FROM_26_6 (metrics
->vertBearingX
) * x_factor
;
2374 fs_metrics
.y_bearing
= DOUBLE_FROM_26_6 (metrics
->vertBearingY
) * y_factor
;
2376 fs_metrics
.x_advance
= 0 * x_factor
;
2377 if (hint_metrics
|| glyph
->format
!= FT_GLYPH_FORMAT_OUTLINE
)
2378 fs_metrics
.y_advance
= DOUBLE_FROM_26_6 (metrics
->vertAdvance
) * y_factor
;
2380 fs_metrics
.y_advance
= DOUBLE_FROM_16_16 (glyph
->linearVertAdvance
) * y_factor
;
2384 _cairo_scaled_glyph_set_metrics (scaled_glyph
,
2389 if ((info
& CAIRO_SCALED_GLYPH_INFO_SURFACE
) != 0) {
2390 cairo_image_surface_t
*surface
;
2392 if (glyph
->format
== FT_GLYPH_FORMAT_OUTLINE
) {
2393 status
= _render_glyph_outline (face
, &scaled_font
->ft_options
.base
,
2396 status
= _render_glyph_bitmap (face
, &scaled_font
->ft_options
.base
,
2398 if (likely (status
== CAIRO_STATUS_SUCCESS
) &&
2399 unscaled
->have_shape
)
2401 status
= _transform_glyph_bitmap (&unscaled
->current_shape
,
2403 if (unlikely (status
))
2404 cairo_surface_destroy (&surface
->base
);
2407 if (unlikely (status
))
2410 _cairo_scaled_glyph_set_surface (scaled_glyph
,
2415 if (info
& CAIRO_SCALED_GLYPH_INFO_PATH
) {
2416 cairo_path_fixed_t
*path
= NULL
; /* hide compiler warning */
2419 * A kludge -- the above code will trash the outline,
2420 * so reload it. This will probably never occur though
2422 if ((info
& CAIRO_SCALED_GLYPH_INFO_SURFACE
) != 0) {
2423 error
= FT_Load_Glyph (face
,
2424 _cairo_scaled_glyph_index(scaled_glyph
),
2425 load_flags
| FT_LOAD_NO_BITMAP
);
2426 /* XXX ignoring all other errors for now. They are not fatal, typically
2427 * just a glyph-not-found. */
2428 if (error
== FT_Err_Out_Of_Memory
) {
2429 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2432 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
2433 if (scaled_font
->ft_options
.synth_flags
& CAIRO_FT_SYNTHESIZE_BOLD
)
2434 FT_GlyphSlot_Embolden (glyph
);
2436 #if HAVE_FT_GLYPHSLOT_OBLIQUE
2437 if (scaled_font
->ft_options
.synth_flags
& CAIRO_FT_SYNTHESIZE_OBLIQUE
)
2438 FT_GlyphSlot_Oblique (glyph
);
2440 if (vertical_layout
)
2441 _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font
, glyph
);
2444 if (glyph
->format
== FT_GLYPH_FORMAT_OUTLINE
)
2445 status
= _decompose_glyph_outline (face
, &scaled_font
->ft_options
.base
,
2448 status
= CAIRO_INT_STATUS_UNSUPPORTED
;
2450 if (unlikely (status
))
2453 _cairo_scaled_glyph_set_path (scaled_glyph
,
2458 _cairo_ft_unscaled_font_unlock_face (unscaled
);
2463 static unsigned long
2464 _cairo_ft_ucs4_to_index (void *abstract_font
,
2467 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
2468 cairo_ft_unscaled_font_t
*unscaled
= scaled_font
->unscaled
;
2472 face
= _cairo_ft_unscaled_font_lock_face (unscaled
);
2476 #if CAIRO_HAS_FC_FONT
2477 index
= FcFreeTypeCharIndex (face
, ucs4
);
2479 index
= FT_Get_Char_Index (face
, ucs4
);
2482 _cairo_ft_unscaled_font_unlock_face (unscaled
);
2486 static cairo_int_status_t
2487 _cairo_ft_load_truetype_table (void *abstract_font
,
2490 unsigned char *buffer
,
2491 unsigned long *length
)
2493 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
2494 cairo_ft_unscaled_font_t
*unscaled
= scaled_font
->unscaled
;
2496 cairo_status_t status
= CAIRO_INT_STATUS_UNSUPPORTED
;
2498 /* We don't support the FreeType feature of loading a table
2499 * without specifying the size since this may overflow our
2501 assert (length
!= NULL
);
2503 if (_cairo_ft_scaled_font_is_vertical (&scaled_font
->base
))
2504 return CAIRO_INT_STATUS_UNSUPPORTED
;
2506 #if HAVE_FT_LOAD_SFNT_TABLE
2507 face
= _cairo_ft_unscaled_font_lock_face (unscaled
);
2509 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2511 if (FT_IS_SFNT (face
)) {
2515 if (FT_Load_Sfnt_Table (face
, tag
, offset
, buffer
, length
) == 0)
2516 status
= CAIRO_STATUS_SUCCESS
;
2519 _cairo_ft_unscaled_font_unlock_face (unscaled
);
2525 static cairo_int_status_t
2526 _cairo_ft_index_to_ucs4(void *abstract_font
,
2527 unsigned long index
,
2530 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
2531 cairo_ft_unscaled_font_t
*unscaled
= scaled_font
->unscaled
;
2536 face
= _cairo_ft_unscaled_font_lock_face (unscaled
);
2538 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2540 *ucs4
= (uint32_t) -1;
2541 charcode
= FT_Get_First_Char(face
, &gindex
);
2542 while (gindex
!= 0) {
2543 if (gindex
== index
) {
2547 charcode
= FT_Get_Next_Char (face
, charcode
, &gindex
);
2550 _cairo_ft_unscaled_font_unlock_face (unscaled
);
2552 return CAIRO_STATUS_SUCCESS
;
2556 _cairo_ft_is_synthetic (void *abstract_font
)
2558 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
2559 return scaled_font
->ft_options
.synth_flags
!= 0;
2562 static cairo_int_status_t
2563 _cairo_index_to_glyph_name (void *abstract_font
,
2565 int num_glyph_names
,
2566 unsigned long glyph_index
,
2567 unsigned long *glyph_array_index
)
2569 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
2570 cairo_ft_unscaled_font_t
*unscaled
= scaled_font
->unscaled
;
2572 char buffer
[256]; /* PLRM spcifies max name length of 127 */
2576 face
= _cairo_ft_unscaled_font_lock_face (unscaled
);
2578 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2580 error
= FT_Get_Glyph_Name (face
, glyph_index
, buffer
, sizeof buffer
);
2582 _cairo_ft_unscaled_font_unlock_face (unscaled
);
2584 if (error
!= FT_Err_Ok
) {
2585 /* propagate fatal errors from FreeType */
2586 if (error
== FT_Err_Out_Of_Memory
)
2587 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2589 return CAIRO_INT_STATUS_UNSUPPORTED
;
2592 /* FT first numbers the glyphs in the order they are read from the
2593 * Type 1 font. Then if .notdef is not the first glyph, the first
2594 * glyph is swapped with .notdef to ensure that .notdef is at
2597 * As all but two glyphs in glyph_names already have the same
2598 * index as the FT glyph index, we first check if
2599 * glyph_names[glyph_index] is the name we are looking for. If not
2600 * we fall back to searching the entire array.
2603 if ((long)glyph_index
< num_glyph_names
&&
2604 strcmp (glyph_names
[glyph_index
], buffer
) == 0)
2606 *glyph_array_index
= glyph_index
;
2608 return CAIRO_STATUS_SUCCESS
;
2611 for (i
= 0; i
< num_glyph_names
; i
++) {
2612 if (strcmp (glyph_names
[i
], buffer
) == 0) {
2613 *glyph_array_index
= i
;
2615 return CAIRO_STATUS_SUCCESS
;
2619 return CAIRO_INT_STATUS_UNSUPPORTED
;
2623 _ft_is_type1 (FT_Face face
)
2625 #if HAVE_FT_GET_X11_FONT_FORMAT
2626 const char *font_format
= FT_Get_X11_Font_Format (face
);
2628 (strcmp (font_format
, "Type 1") == 0 ||
2629 strcmp (font_format
, "CFF") == 0))
2638 static cairo_int_status_t
2639 _cairo_ft_load_type1_data (void *abstract_font
,
2641 unsigned char *buffer
,
2642 unsigned long *length
)
2644 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
2645 cairo_ft_unscaled_font_t
*unscaled
= scaled_font
->unscaled
;
2647 cairo_status_t status
= CAIRO_STATUS_SUCCESS
;
2648 unsigned long available_length
;
2651 assert (length
!= NULL
);
2653 if (_cairo_ft_scaled_font_is_vertical (&scaled_font
->base
))
2654 return CAIRO_INT_STATUS_UNSUPPORTED
;
2656 face
= _cairo_ft_unscaled_font_lock_face (unscaled
);
2658 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2660 #if HAVE_FT_LOAD_SFNT_TABLE
2661 if (FT_IS_SFNT (face
)) {
2662 status
= CAIRO_INT_STATUS_UNSUPPORTED
;
2667 if (! _ft_is_type1 (face
)) {
2668 status
= CAIRO_INT_STATUS_UNSUPPORTED
;
2672 available_length
= MAX (face
->stream
->size
- offset
, 0);
2674 *length
= available_length
;
2676 if (*length
> available_length
) {
2677 status
= CAIRO_INT_STATUS_UNSUPPORTED
;
2678 } else if (face
->stream
->read
!= NULL
) {
2679 /* Note that read() may be implemented as a macro, thanks POSIX!, so we
2680 * need to wrap the following usage in parentheses in order to
2681 * disambiguate it for the pre-processor - using the verbose function
2682 * pointer dereference for clarity.
2684 ret
= (* face
->stream
->read
) (face
->stream
,
2689 status
= _cairo_error (CAIRO_STATUS_READ_ERROR
);
2691 memcpy (buffer
, face
->stream
->base
+ offset
, *length
);
2696 _cairo_ft_unscaled_font_unlock_face (unscaled
);
2701 static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend
= {
2703 _cairo_ft_scaled_font_fini
,
2704 _cairo_ft_scaled_glyph_init
,
2705 NULL
, /* text_to_glyphs */
2706 _cairo_ft_ucs4_to_index
,
2707 _cairo_ft_load_truetype_table
,
2708 _cairo_ft_index_to_ucs4
,
2709 _cairo_ft_is_synthetic
,
2710 _cairo_index_to_glyph_name
,
2711 _cairo_ft_load_type1_data
2714 /* #cairo_ft_font_face_t */
2716 #if CAIRO_HAS_FC_FONT
2717 static cairo_font_face_t
*
2718 _cairo_ft_font_face_create_for_pattern (FcPattern
*pattern
);
2720 static cairo_status_t
2721 _cairo_ft_font_face_create_for_toy (cairo_toy_font_face_t
*toy_face
,
2722 cairo_font_face_t
**font_face_out
)
2724 cairo_font_face_t
*font_face
= (cairo_font_face_t
*) &_cairo_font_face_nil
;
2729 pattern
= FcPatternCreate ();
2731 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
2732 return font_face
->status
;
2735 if (!FcPatternAddString (pattern
,
2736 FC_FAMILY
, (unsigned char *) toy_face
->family
))
2738 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
2742 switch (toy_face
->slant
)
2744 case CAIRO_FONT_SLANT_ITALIC
:
2745 fcslant
= FC_SLANT_ITALIC
;
2747 case CAIRO_FONT_SLANT_OBLIQUE
:
2748 fcslant
= FC_SLANT_OBLIQUE
;
2750 case CAIRO_FONT_SLANT_NORMAL
:
2752 fcslant
= FC_SLANT_ROMAN
;
2756 if (!FcPatternAddInteger (pattern
, FC_SLANT
, fcslant
)) {
2757 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
2761 switch (toy_face
->weight
)
2763 case CAIRO_FONT_WEIGHT_BOLD
:
2764 fcweight
= FC_WEIGHT_BOLD
;
2766 case CAIRO_FONT_WEIGHT_NORMAL
:
2768 fcweight
= FC_WEIGHT_MEDIUM
;
2772 if (!FcPatternAddInteger (pattern
, FC_WEIGHT
, fcweight
)) {
2773 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
2777 font_face
= _cairo_ft_font_face_create_for_pattern (pattern
);
2780 FcPatternDestroy (pattern
);
2782 *font_face_out
= font_face
;
2783 return font_face
->status
;
2788 _cairo_ft_font_face_destroy (void *abstract_face
)
2790 cairo_ft_font_face_t
*font_face
= abstract_face
;
2792 /* When destroying a face created by cairo_ft_font_face_create_for_ft_face,
2793 * we have a special "zombie" state for the face when the unscaled font
2794 * is still alive but there are no other references to a font face with
2799 * font_face ------> unscaled
2804 * font_face <------- unscaled
2807 if (font_face
->unscaled
&&
2808 font_face
->unscaled
->from_face
&&
2809 font_face
->next
== NULL
&&
2810 font_face
->unscaled
->faces
== font_face
&&
2811 CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face
->unscaled
->base
.ref_count
) > 1)
2813 _cairo_unscaled_font_destroy (&font_face
->unscaled
->base
);
2814 font_face
->unscaled
= NULL
;
2819 if (font_face
->unscaled
) {
2820 cairo_ft_font_face_t
*tmp_face
= NULL
;
2821 cairo_ft_font_face_t
*last_face
= NULL
;
2823 /* Remove face from linked list */
2824 for (tmp_face
= font_face
->unscaled
->faces
;
2826 tmp_face
= tmp_face
->next
)
2828 if (tmp_face
== font_face
) {
2830 last_face
->next
= tmp_face
->next
;
2832 font_face
->unscaled
->faces
= tmp_face
->next
;
2835 last_face
= tmp_face
;
2838 _cairo_unscaled_font_destroy (&font_face
->unscaled
->base
);
2839 font_face
->unscaled
= NULL
;
2842 #if CAIRO_HAS_FC_FONT
2843 if (font_face
->pattern
) {
2844 FcPatternDestroy (font_face
->pattern
);
2845 cairo_font_face_destroy (font_face
->resolved_font_face
);
2852 static cairo_font_face_t
*
2853 _cairo_ft_font_face_get_implementation (void *abstract_face
,
2854 const cairo_matrix_t
*font_matrix
,
2855 const cairo_matrix_t
*ctm
,
2856 const cairo_font_options_t
*options
)
2858 cairo_ft_font_face_t
*font_face
= abstract_face
;
2860 /* The handling of font options is different depending on how the
2861 * font face was created. When the user creates a font face with
2862 * cairo_ft_font_face_create_for_ft_face(), then the load flags
2863 * passed in augment the load flags for the options. But for
2864 * cairo_ft_font_face_create_for_pattern(), the load flags are
2865 * derived from a pattern where the user has called
2866 * cairo_ft_font_options_substitute(), so *just* use those load
2867 * flags and ignore the options.
2870 #if CAIRO_HAS_FC_FONT
2871 /* If we have an unresolved pattern, resolve it and create
2872 * unscaled font. Otherwise, use the ones stored in font_face.
2874 if (font_face
->pattern
) {
2875 cairo_font_face_t
*resolved
;
2877 /* Cache the resolved font whilst the FcConfig remains consistent. */
2878 resolved
= font_face
->resolved_font_face
;
2879 if (resolved
!= NULL
) {
2880 if (! FcInitBringUptoDate ()) {
2881 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
2882 return (cairo_font_face_t
*) &_cairo_font_face_nil
;
2885 if (font_face
->resolved_config
== FcConfigGetCurrent ())
2886 return cairo_font_face_reference (resolved
);
2888 cairo_font_face_destroy (resolved
);
2889 font_face
->resolved_font_face
= NULL
;
2892 resolved
= _cairo_ft_resolve_pattern (font_face
->pattern
,
2896 if (unlikely (resolved
->status
))
2899 font_face
->resolved_font_face
= cairo_font_face_reference (resolved
);
2900 font_face
->resolved_config
= FcConfigGetCurrent ();
2906 return abstract_face
;
2909 const cairo_font_face_backend_t _cairo_ft_font_face_backend
= {
2911 #if CAIRO_HAS_FC_FONT
2912 _cairo_ft_font_face_create_for_toy
,
2916 _cairo_ft_font_face_destroy
,
2917 _cairo_ft_font_face_scaled_font_create
,
2918 _cairo_ft_font_face_get_implementation
2921 #if CAIRO_HAS_FC_FONT
2922 static cairo_font_face_t
*
2923 _cairo_ft_font_face_create_for_pattern (FcPattern
*pattern
)
2925 cairo_ft_font_face_t
*font_face
;
2927 font_face
= malloc (sizeof (cairo_ft_font_face_t
));
2928 if (unlikely (font_face
== NULL
)) {
2929 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
2930 return (cairo_font_face_t
*) &_cairo_font_face_nil
;
2933 font_face
->unscaled
= NULL
;
2934 font_face
->next
= NULL
;
2936 font_face
->pattern
= FcPatternDuplicate (pattern
);
2937 if (unlikely (font_face
->pattern
== NULL
)) {
2939 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
2940 return (cairo_font_face_t
*) &_cairo_font_face_nil
;
2943 font_face
->resolved_font_face
= NULL
;
2944 font_face
->resolved_config
= NULL
;
2946 _cairo_font_face_init (&font_face
->base
, &_cairo_ft_font_face_backend
);
2948 return &font_face
->base
;
2952 static cairo_font_face_t
*
2953 _cairo_ft_font_face_create (cairo_ft_unscaled_font_t
*unscaled
,
2954 cairo_ft_options_t
*ft_options
)
2956 cairo_ft_font_face_t
*font_face
, **prev_font_face
;
2958 /* Looked for an existing matching font face */
2959 for (font_face
= unscaled
->faces
, prev_font_face
= &unscaled
->faces
;
2961 prev_font_face
= &font_face
->next
, font_face
= font_face
->next
)
2963 if (font_face
->ft_options
.load_flags
== ft_options
->load_flags
&&
2964 font_face
->ft_options
.synth_flags
== ft_options
->synth_flags
&&
2965 cairo_font_options_equal (&font_face
->ft_options
.base
, &ft_options
->base
))
2967 if (font_face
->base
.status
) {
2968 /* The font_face has been left in an error state, abandon it. */
2969 *prev_font_face
= font_face
->next
;
2973 if (font_face
->unscaled
== NULL
) {
2974 /* Resurrect this "zombie" font_face (from
2975 * _cairo_ft_font_face_destroy), switching its unscaled_font
2976 * from owner to ownee. */
2977 font_face
->unscaled
= unscaled
;
2978 _cairo_unscaled_font_reference (&unscaled
->base
);
2979 return &font_face
->base
;
2981 return cairo_font_face_reference (&font_face
->base
);
2985 /* No match found, create a new one */
2986 font_face
= malloc (sizeof (cairo_ft_font_face_t
));
2987 if (unlikely (!font_face
)) {
2988 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
2989 return (cairo_font_face_t
*)&_cairo_font_face_nil
;
2992 font_face
->unscaled
= unscaled
;
2993 _cairo_unscaled_font_reference (&unscaled
->base
);
2995 font_face
->ft_options
= *ft_options
;
2997 if (unscaled
->faces
&& unscaled
->faces
->unscaled
== NULL
) {
2998 /* This "zombie" font_face (from _cairo_ft_font_face_destroy)
2999 * is no longer needed. */
3000 assert (unscaled
->from_face
&& unscaled
->faces
->next
== NULL
);
3001 cairo_font_face_destroy (&unscaled
->faces
->base
);
3002 unscaled
->faces
= NULL
;
3005 font_face
->next
= unscaled
->faces
;
3006 unscaled
->faces
= font_face
;
3008 #if CAIRO_HAS_FC_FONT
3009 font_face
->pattern
= NULL
;
3012 _cairo_font_face_init (&font_face
->base
, &_cairo_ft_font_face_backend
);
3014 return &font_face
->base
;
3017 /* implement the platform-specific interface */
3019 #if CAIRO_HAS_FC_FONT
3020 static cairo_status_t
3021 _cairo_ft_font_options_substitute (const cairo_font_options_t
*options
,
3026 if (options
->antialias
!= CAIRO_ANTIALIAS_DEFAULT
)
3028 if (FcPatternGet (pattern
, FC_ANTIALIAS
, 0, &v
) == FcResultNoMatch
)
3030 if (! FcPatternAddBool (pattern
,
3032 options
->antialias
!= CAIRO_ANTIALIAS_NONE
))
3033 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
3035 if (options
->antialias
!= CAIRO_ANTIALIAS_SUBPIXEL
) {
3036 FcPatternDel (pattern
, FC_RGBA
);
3037 if (! FcPatternAddInteger (pattern
, FC_RGBA
, FC_RGBA_NONE
))
3038 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
3043 if (options
->antialias
!= CAIRO_ANTIALIAS_DEFAULT
)
3045 if (FcPatternGet (pattern
, FC_RGBA
, 0, &v
) == FcResultNoMatch
)
3049 if (options
->antialias
== CAIRO_ANTIALIAS_SUBPIXEL
) {
3050 switch (options
->subpixel_order
) {
3051 case CAIRO_SUBPIXEL_ORDER_DEFAULT
:
3052 case CAIRO_SUBPIXEL_ORDER_RGB
:
3056 case CAIRO_SUBPIXEL_ORDER_BGR
:
3059 case CAIRO_SUBPIXEL_ORDER_VRGB
:
3060 rgba
= FC_RGBA_VRGB
;
3062 case CAIRO_SUBPIXEL_ORDER_VBGR
:
3063 rgba
= FC_RGBA_VBGR
;
3067 rgba
= FC_RGBA_NONE
;
3070 if (! FcPatternAddInteger (pattern
, FC_RGBA
, rgba
))
3071 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
3075 if (options
->lcd_filter
!= CAIRO_LCD_FILTER_DEFAULT
)
3077 if (FcPatternGet (pattern
, FC_LCD_FILTER
, 0, &v
) == FcResultNoMatch
)
3081 switch (options
->lcd_filter
) {
3082 case CAIRO_LCD_FILTER_NONE
:
3083 lcd_filter
= FT_LCD_FILTER_NONE
;
3085 case CAIRO_LCD_FILTER_DEFAULT
:
3086 case CAIRO_LCD_FILTER_INTRA_PIXEL
:
3087 lcd_filter
= FT_LCD_FILTER_LEGACY
;
3089 case CAIRO_LCD_FILTER_FIR3
:
3090 lcd_filter
= FT_LCD_FILTER_LIGHT
;
3093 case CAIRO_LCD_FILTER_FIR5
:
3094 lcd_filter
= FT_LCD_FILTER_DEFAULT
;
3098 if (! FcPatternAddInteger (pattern
, FC_LCD_FILTER
, lcd_filter
))
3099 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
3103 if (options
->hint_style
!= CAIRO_HINT_STYLE_DEFAULT
)
3105 if (FcPatternGet (pattern
, FC_HINTING
, 0, &v
) == FcResultNoMatch
)
3107 if (! FcPatternAddBool (pattern
,
3109 options
->hint_style
!= CAIRO_HINT_STYLE_NONE
))
3110 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
3113 #ifdef FC_HINT_STYLE
3114 if (FcPatternGet (pattern
, FC_HINT_STYLE
, 0, &v
) == FcResultNoMatch
)
3118 switch (options
->hint_style
) {
3119 case CAIRO_HINT_STYLE_NONE
:
3120 hint_style
= FC_HINT_NONE
;
3122 case CAIRO_HINT_STYLE_SLIGHT
:
3123 hint_style
= FC_HINT_SLIGHT
;
3125 case CAIRO_HINT_STYLE_MEDIUM
:
3126 hint_style
= FC_HINT_MEDIUM
;
3128 case CAIRO_HINT_STYLE_FULL
:
3129 case CAIRO_HINT_STYLE_DEFAULT
:
3131 hint_style
= FC_HINT_FULL
;
3135 if (! FcPatternAddInteger (pattern
, FC_HINT_STYLE
, hint_style
))
3136 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
3141 return CAIRO_STATUS_SUCCESS
;
3145 * cairo_ft_font_options_substitute:
3146 * @options: a #cairo_font_options_t object
3147 * @pattern: an existing #FcPattern
3149 * Add options to a #FcPattern based on a #cairo_font_options_t font
3150 * options object. Options that are already in the pattern, are not overridden,
3151 * so you should call this function after calling FcConfigSubstitute() (the
3152 * user's settings should override options based on the surface type), but
3153 * before calling FcDefaultSubstitute().
3158 cairo_ft_font_options_substitute (const cairo_font_options_t
*options
,
3161 if (cairo_font_options_status ((cairo_font_options_t
*) options
))
3164 _cairo_ft_font_options_substitute (options
, pattern
);
3167 static cairo_font_face_t
*
3168 _cairo_ft_resolve_pattern (FcPattern
*pattern
,
3169 const cairo_matrix_t
*font_matrix
,
3170 const cairo_matrix_t
*ctm
,
3171 const cairo_font_options_t
*font_options
)
3173 cairo_status_t status
;
3175 cairo_matrix_t scale
;
3176 FcPattern
*resolved
;
3177 cairo_ft_font_transform_t sf
;
3179 cairo_ft_unscaled_font_t
*unscaled
;
3180 cairo_ft_options_t ft_options
;
3181 cairo_font_face_t
*font_face
;
3184 scale
.x0
= scale
.y0
= 0;
3185 cairo_matrix_multiply (&scale
,
3189 status
= _compute_transform (&sf
, &scale
, NULL
);
3190 if (unlikely (status
))
3191 return (cairo_font_face_t
*)&_cairo_font_face_nil
;
3193 pattern
= FcPatternDuplicate (pattern
);
3194 if (pattern
== NULL
)
3195 return (cairo_font_face_t
*)&_cairo_font_face_nil
;
3197 if (! FcPatternAddDouble (pattern
, FC_PIXEL_SIZE
, sf
.y_scale
)) {
3198 font_face
= (cairo_font_face_t
*)&_cairo_font_face_nil
;
3202 if (! FcConfigSubstitute (NULL
, pattern
, FcMatchPattern
)) {
3203 font_face
= (cairo_font_face_t
*)&_cairo_font_face_nil
;
3207 status
= _cairo_ft_font_options_substitute (font_options
, pattern
);
3209 font_face
= (cairo_font_face_t
*)&_cairo_font_face_nil
;
3213 FcDefaultSubstitute (pattern
);
3215 status
= _cairo_ft_unscaled_font_create_for_pattern (pattern
, &unscaled
);
3216 if (unlikely (status
)) {
3217 font_face
= (cairo_font_face_t
*)&_cairo_font_face_nil
;
3221 if (unscaled
== NULL
) {
3222 resolved
= FcFontMatch (NULL
, pattern
, &result
);
3224 /* We failed to find any font. Substitute twin so that the user can
3225 * see something (and hopefully recognise that the font is missing)
3226 * and not just receive a NO_MEMORY error during rendering.
3228 font_face
= _cairo_font_face_twin_create_fallback ();
3232 status
= _cairo_ft_unscaled_font_create_for_pattern (resolved
, &unscaled
);
3233 if (unlikely (status
|| unscaled
== NULL
)) {
3234 font_face
= (cairo_font_face_t
*)&_cairo_font_face_nil
;
3240 _get_pattern_ft_options (resolved
, &ft_options
);
3241 font_face
= _cairo_ft_font_face_create (unscaled
, &ft_options
);
3242 _cairo_unscaled_font_destroy (&unscaled
->base
);
3245 if (resolved
!= pattern
)
3246 FcPatternDestroy (resolved
);
3249 FcPatternDestroy (pattern
);
3255 * cairo_ft_font_face_create_for_pattern:
3256 * @pattern: A fontconfig pattern. Cairo makes a copy of the pattern
3257 * if it needs to. You are free to modify or free @pattern after this call.
3259 * Creates a new font face for the FreeType font backend based on a
3260 * fontconfig pattern. This font can then be used with
3261 * cairo_set_font_face() or cairo_scaled_font_create(). The
3262 * #cairo_scaled_font_t returned from cairo_scaled_font_create() is
3263 * also for the FreeType backend and can be used with functions such
3264 * as cairo_ft_scaled_font_lock_face().
3266 * Font rendering options are represented both here and when you
3267 * call cairo_scaled_font_create(). Font options that have a representation
3268 * in a #FcPattern must be passed in here; to modify #FcPattern
3269 * appropriately to reflect the options in a #cairo_font_options_t, call
3270 * cairo_ft_font_options_substitute().
3272 * The pattern's FC_FT_FACE element is inspected first and if that is set,
3273 * that will be the FreeType font face associated with the returned cairo
3274 * font face. Otherwise the FC_FILE element is checked. If it's set,
3275 * that and the value of the FC_INDEX element (defaults to zero) of @pattern
3276 * are used to load a font face from file.
3278 * If both steps from the previous paragraph fails, @pattern will be passed
3279 * to FcConfigSubstitute, FcDefaultSubstitute, and finally FcFontMatch,
3280 * and the resulting font pattern is used.
3282 * If the FC_FT_FACE element of @pattern is set, the user is responsible
3283 * for making sure that the referenced FT_Face remains valid for the life
3284 * time of the returned #cairo_font_face_t. See
3285 * cairo_ft_font_face_create_for_ft_face() for an example of how to couple
3286 * the life time of the FT_Face to that of the cairo font-face.
3288 * Return value: a newly created #cairo_font_face_t. Free with
3289 * cairo_font_face_destroy() when you are done using it.
3294 cairo_ft_font_face_create_for_pattern (FcPattern
*pattern
)
3296 cairo_ft_unscaled_font_t
*unscaled
;
3297 cairo_font_face_t
*font_face
;
3298 cairo_ft_options_t ft_options
;
3299 cairo_status_t status
;
3301 status
= _cairo_ft_unscaled_font_create_for_pattern (pattern
, &unscaled
);
3302 if (unlikely (status
)) {
3303 if (status
== CAIRO_STATUS_FILE_NOT_FOUND
)
3304 return (cairo_font_face_t
*) &_cairo_font_face_nil_file_not_found
;
3306 return (cairo_font_face_t
*) &_cairo_font_face_nil
;
3308 if (unlikely (unscaled
== NULL
)) {
3309 /* Store the pattern. We will resolve it and create unscaled
3310 * font when creating scaled fonts */
3311 return _cairo_ft_font_face_create_for_pattern (pattern
);
3314 _get_pattern_ft_options (pattern
, &ft_options
);
3315 font_face
= _cairo_ft_font_face_create (unscaled
, &ft_options
);
3316 _cairo_unscaled_font_destroy (&unscaled
->base
);
3323 * cairo_ft_font_face_create_for_ft_face:
3324 * @face: A FreeType face object, already opened. This must
3325 * be kept around until the face's ref_count drops to
3326 * zero and it is freed. Since the face may be referenced
3327 * internally to Cairo, the best way to determine when it
3328 * is safe to free the face is to pass a
3329 * #cairo_destroy_func_t to cairo_font_face_set_user_data()
3330 * @load_flags: flags to pass to FT_Load_Glyph when loading
3331 * glyphs from the font. These flags are OR'ed together with
3332 * the flags derived from the #cairo_font_options_t passed
3333 * to cairo_scaled_font_create(), so only a few values such
3334 * as %FT_LOAD_VERTICAL_LAYOUT, and %FT_LOAD_FORCE_AUTOHINT
3335 * are useful. You should not pass any of the flags affecting
3336 * the load target, such as %FT_LOAD_TARGET_LIGHT.
3338 * Creates a new font face for the FreeType font backend from a
3339 * pre-opened FreeType face. This font can then be used with
3340 * cairo_set_font_face() or cairo_scaled_font_create(). The
3341 * #cairo_scaled_font_t returned from cairo_scaled_font_create() is
3342 * also for the FreeType backend and can be used with functions such
3343 * as cairo_ft_scaled_font_lock_face(). Note that Cairo may keep a reference
3344 * to the FT_Face alive in a font-cache and the exact lifetime of the reference
3345 * depends highly upon the exact usage pattern and is subject to external
3346 * factors. You must not call FT_Done_Face() before the last reference to the
3347 * #cairo_font_face_t has been dropped.
3349 * As an example, below is how one might correctly couple the lifetime of
3350 * the FreeType face object to the #cairo_font_face_t.
3352 * <informalexample><programlisting>
3353 * static const cairo_user_data_key_t key;
3355 * font_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
3356 * status = cairo_font_face_set_user_data (font_face, &key,
3357 * ft_face, (cairo_destroy_func_t) FT_Done_Face);
3359 * cairo_font_face_destroy (font_face);
3360 * FT_Done_Face (ft_face);
3363 * </programlisting></informalexample>
3365 * Return value: a newly created #cairo_font_face_t. Free with
3366 * cairo_font_face_destroy() when you are done using it.
3371 cairo_ft_font_face_create_for_ft_face (FT_Face face
,
3374 cairo_ft_unscaled_font_t
*unscaled
;
3375 cairo_font_face_t
*font_face
;
3376 cairo_ft_options_t ft_options
;
3377 cairo_status_t status
;
3379 status
= _cairo_ft_unscaled_font_create_from_face (face
, &unscaled
);
3380 if (unlikely (status
))
3381 return (cairo_font_face_t
*)&_cairo_font_face_nil
;
3383 ft_options
.load_flags
= load_flags
;
3384 ft_options
.synth_flags
= 0;
3385 _cairo_font_options_init_default (&ft_options
.base
);
3387 font_face
= _cairo_ft_font_face_create (unscaled
, &ft_options
);
3388 _cairo_unscaled_font_destroy (&unscaled
->base
);
3394 * cairo_ft_font_face_set_synthesize:
3395 * @font_face: The #cairo_ft_font_face_t object to modify
3396 * @synth_flags: the set of synthesis options to enable
3398 * FreeType provides the ability to synthesize different glyphs from a base
3399 * font, which is useful if you lack those glyphs from a true bold or oblique
3400 * font. See also #cairo_ft_synthesize_t.
3405 cairo_ft_font_face_set_synthesize (cairo_font_face_t
*font_face
,
3406 unsigned int synth_flags
)
3408 cairo_ft_font_face_t
*ft
;
3410 if (font_face
->backend
->type
!= CAIRO_FONT_TYPE_FT
)
3413 ft
= (cairo_ft_font_face_t
*) font_face
;
3414 ft
->ft_options
.synth_flags
|= synth_flags
;
3418 * cairo_ft_font_face_unset_synthesize:
3419 * @font_face: The #cairo_ft_font_face_t object to modify
3420 * @synth_flags: the set of synthesis options to disable
3422 * See cairo_ft_font_face_set_synthesize().
3427 cairo_ft_font_face_unset_synthesize (cairo_font_face_t
*font_face
,
3428 unsigned int synth_flags
)
3430 cairo_ft_font_face_t
*ft
;
3432 if (font_face
->backend
->type
!= CAIRO_FONT_TYPE_FT
)
3435 ft
= (cairo_ft_font_face_t
*) font_face
;
3436 ft
->ft_options
.synth_flags
&= ~synth_flags
;
3440 * cairo_ft_font_face_get_synthesize:
3441 * @font_face: The #cairo_ft_font_face_t object to query
3443 * See #cairo_ft_synthesize_t.
3445 * Returns: the current set of synthesis options.
3450 cairo_ft_font_face_get_synthesize (cairo_font_face_t
*font_face
)
3452 cairo_ft_font_face_t
*ft
;
3454 if (font_face
->backend
->type
!= CAIRO_FONT_TYPE_FT
)
3457 ft
= (cairo_ft_font_face_t
*) font_face
;
3458 return ft
->ft_options
.synth_flags
;
3462 * cairo_ft_scaled_font_lock_face:
3463 * @scaled_font: A #cairo_scaled_font_t from the FreeType font backend. Such an
3464 * object can be created by calling cairo_scaled_font_create() on a
3465 * FreeType backend font face (see cairo_ft_font_face_create_for_pattern(),
3466 * cairo_ft_font_face_create_for_ft_face()).
3468 * cairo_ft_scaled_font_lock_face() gets the #FT_Face object from a FreeType
3469 * backend font and scales it appropriately for the font. You must
3470 * release the face with cairo_ft_scaled_font_unlock_face()
3471 * when you are done using it. Since the #FT_Face object can be
3472 * shared between multiple #cairo_scaled_font_t objects, you must not
3473 * lock any other font objects until you unlock this one. A count is
3474 * kept of the number of times cairo_ft_scaled_font_lock_face() is
3475 * called. cairo_ft_scaled_font_unlock_face() must be called the same number
3478 * You must be careful when using this function in a library or in a
3479 * threaded application, because freetype's design makes it unsafe to
3480 * call freetype functions simultaneously from multiple threads, (even
3481 * if using distinct FT_Face objects). Because of this, application
3482 * code that acquires an FT_Face object with this call must add its
3483 * own locking to protect any use of that object, (and which also must
3484 * protect any other calls into cairo as almost any cairo function
3485 * might result in a call into the freetype library).
3487 * Return value: The #FT_Face object for @font, scaled appropriately,
3488 * or %NULL if @scaled_font is in an error state (see
3489 * cairo_scaled_font_status()) or there is insufficient memory.
3494 cairo_ft_scaled_font_lock_face (cairo_scaled_font_t
*abstract_font
)
3496 cairo_ft_scaled_font_t
*scaled_font
= (cairo_ft_scaled_font_t
*) abstract_font
;
3498 cairo_status_t status
;
3500 if (! _cairo_scaled_font_is_ft (abstract_font
)) {
3501 _cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH
);
3505 if (scaled_font
->base
.status
)
3508 face
= _cairo_ft_unscaled_font_lock_face (scaled_font
->unscaled
);
3509 if (unlikely (face
== NULL
)) {
3510 status
= _cairo_scaled_font_set_error (&scaled_font
->base
, CAIRO_STATUS_NO_MEMORY
);
3514 status
= _cairo_ft_unscaled_font_set_scale (scaled_font
->unscaled
,
3515 &scaled_font
->base
.scale
);
3516 if (unlikely (status
)) {
3517 _cairo_ft_unscaled_font_unlock_face (scaled_font
->unscaled
);
3518 status
= _cairo_scaled_font_set_error (&scaled_font
->base
, status
);
3522 /* Note: We deliberately release the unscaled font's mutex here,
3523 * so that we are not holding a lock across two separate calls to
3524 * cairo function, (which would give the application some
3525 * opportunity for creating deadlock. This is obviously unsafe,
3526 * but as documented, the user must add manual locking when using
3528 CAIRO_MUTEX_UNLOCK (scaled_font
->unscaled
->mutex
);
3534 * cairo_ft_scaled_font_unlock_face:
3535 * @scaled_font: A #cairo_scaled_font_t from the FreeType font backend. Such an
3536 * object can be created by calling cairo_scaled_font_create() on a
3537 * FreeType backend font face (see cairo_ft_font_face_create_for_pattern(),
3538 * cairo_ft_font_face_create_for_ft_face()).
3540 * Releases a face obtained with cairo_ft_scaled_font_lock_face().
3545 cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t
*abstract_font
)
3547 cairo_ft_scaled_font_t
*scaled_font
= (cairo_ft_scaled_font_t
*) abstract_font
;
3549 if (! _cairo_scaled_font_is_ft (abstract_font
)) {
3550 _cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH
);
3554 if (scaled_font
->base
.status
)
3557 /* Note: We released the unscaled font's mutex at the end of
3558 * cairo_ft_scaled_font_lock_face, so we have to acquire it again
3559 * as _cairo_ft_unscaled_font_unlock_face expects it to be held
3560 * when we call into it. */
3561 CAIRO_MUTEX_LOCK (scaled_font
->unscaled
->mutex
);
3563 _cairo_ft_unscaled_font_unlock_face (scaled_font
->unscaled
);
3567 _cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t
*scaled_font
)
3569 cairo_ft_scaled_font_t
*ft_scaled_font
;
3571 if (!_cairo_scaled_font_is_ft (scaled_font
))
3574 ft_scaled_font
= (cairo_ft_scaled_font_t
*) scaled_font
;
3575 if (ft_scaled_font
->ft_options
.load_flags
& FT_LOAD_VERTICAL_LAYOUT
)
3581 _cairo_ft_scaled_font_get_load_flags (cairo_scaled_font_t
*scaled_font
)
3583 cairo_ft_scaled_font_t
*ft_scaled_font
;
3585 if (! _cairo_scaled_font_is_ft (scaled_font
))
3588 ft_scaled_font
= (cairo_ft_scaled_font_t
*) scaled_font
;
3589 return ft_scaled_font
->ft_options
.load_flags
;
3593 _cairo_ft_font_reset_static_data (void)
3595 _cairo_ft_unscaled_font_map_destroy ();