1 /* cairo - a vector graphics library with display and print output
3 * Copyright © 2000 Keith Packard
4 * Copyright © 2005 Red Hat, Inc
6 * This library is free software; you can redistribute it and/or
7 * modify it either under the terms of the GNU Lesser General Public
8 * License version 2.1 as published by the Free Software Foundation
9 * (the "LGPL") or, at your option, under the terms of the Mozilla
10 * Public License Version 1.1 (the "MPL"). If you do not alter this
11 * notice, a recipient may use your version of this file under either
12 * the MPL or the LGPL.
14 * You should have received a copy of the LGPL along with this library
15 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * You should have received a copy of the MPL along with this library
18 * in the file COPYING-MPL-1.1
20 * The contents of this file are subject to the Mozilla Public License
21 * Version 1.1 (the "License"); you may not use this file except in
22 * compliance with the License. You may obtain a copy of the License at
23 * http://www.mozilla.org/MPL/
25 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27 * the specific language governing rights and limitations.
29 * The Original Code is the cairo graphics library.
31 * The Initial Developer of the Original Code is Red Hat, Inc.
34 * Graydon Hoare <graydon@redhat.com>
35 * Owen Taylor <otaylor@redhat.com>
36 * Keith Packard <keithp@keithp.com>
37 * Carl Worth <cworth@cworth.org>
40 #define _BSD_SOURCE /* for strdup() */
43 #include "cairo-ft-private.h"
47 #include <fontconfig/fontconfig.h>
48 #include <fontconfig/fcfreetype.h>
51 #include FT_FREETYPE_H
54 #include FT_TRUETYPE_TABLES_H
55 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
56 #include FT_SYNTHESIS_H
59 #define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
60 #define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
61 #define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
62 #define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0)
64 /* This is the max number of FT_face objects we keep open at once
66 #define MAX_OPEN_FACES 10
69 * The simple 2x2 matrix is converted into separate scale and shape
70 * factors so that hinting works right
73 typedef struct _cairo_ft_font_transform
{
74 double x_scale
, y_scale
;
76 } cairo_ft_font_transform_t
;
79 * We create an object that corresponds to a single font on the disk;
80 * (identified by a filename/id pair) these are shared between all
81 * fonts using that file. For cairo_ft_font_face_create_for_ft_face(), we
82 * just create a one-off version with a permanent face value.
85 typedef struct _cairo_ft_font_face cairo_ft_font_face_t
;
87 struct _cairo_ft_unscaled_font
{
88 cairo_unscaled_font_t base
;
90 cairo_bool_t from_face
; /* from cairo_ft_font_face_create_for_ft_face()? */
91 FT_Face face
; /* provided or cached face */
93 /* only set if from_face is false */
97 /* We temporarily scale the unscaled font as needed */
98 cairo_bool_t have_scale
;
99 cairo_matrix_t current_scale
;
100 double x_scale
; /* Extracted X scale factor */
101 double y_scale
; /* Extracted Y scale factor */
102 cairo_bool_t have_shape
; /* true if the current scale has a non-scale component*/
103 cairo_matrix_t current_shape
;
104 FT_Matrix Current_Shape
;
109 cairo_ft_font_face_t
*faces
; /* Linked list of faces for this font */
113 _cairo_ft_unscaled_font_keys_equal (const void *key_a
,
117 _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t
*unscaled
);
119 static cairo_status_t
120 _cairo_ft_font_options_substitute (const cairo_font_options_t
*options
,
123 typedef enum _cairo_ft_extra_flags
{
124 CAIRO_FT_OPTIONS_HINT_METRICS
= (1 << 0),
125 CAIRO_FT_OPTIONS_EMBOLDEN
= (1 << 1)
126 } cairo_ft_extra_flags_t
;
128 typedef struct _cairo_ft_options
{
129 cairo_font_options_t base
;
130 int load_flags
; /* flags for FT_Load_Glyph */
131 cairo_ft_extra_flags_t extra_flags
; /* other flags that affect results */
132 } cairo_ft_options_t
;
134 struct _cairo_ft_font_face
{
135 cairo_font_face_t base
;
136 cairo_ft_unscaled_font_t
*unscaled
;
137 cairo_ft_options_t ft_options
;
138 cairo_ft_font_face_t
*next
;
141 static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend
;
144 * We maintain a hash table to map file/id => #cairo_ft_unscaled_font_t.
145 * The hash table itself isn't limited in size. However, we limit the
146 * number of FT_Face objects we keep around; when we've exceeded that
147 * limit and need to create a new FT_Face, we dump the FT_Face from a
148 * random #cairo_ft_unscaled_font_t which has an unlocked FT_Face, (if
152 typedef struct _cairo_ft_unscaled_font_map
{
153 cairo_hash_table_t
*hash_table
;
154 FT_Library ft_library
;
156 } cairo_ft_unscaled_font_map_t
;
158 static cairo_ft_unscaled_font_map_t
*cairo_ft_unscaled_font_map
= NULL
;
161 _font_map_release_face_lock_held (cairo_ft_unscaled_font_map_t
*font_map
,
162 cairo_ft_unscaled_font_t
*unscaled
)
164 if (unscaled
->face
) {
165 FT_Done_Face (unscaled
->face
);
166 unscaled
->face
= NULL
;
167 unscaled
->have_scale
= FALSE
;
169 font_map
->num_open_faces
--;
174 _cairo_ft_unscaled_font_map_create (void)
176 cairo_ft_unscaled_font_map_t
*font_map
;
178 /* This function is only intended to be called from
179 * _cairo_ft_unscaled_font_map_lock. So we'll crash if we can
180 * detect some other call path. */
181 assert (cairo_ft_unscaled_font_map
== NULL
);
183 font_map
= malloc (sizeof (cairo_ft_unscaled_font_map_t
));
184 if (font_map
== NULL
) {
185 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
189 font_map
->hash_table
=
190 _cairo_hash_table_create (_cairo_ft_unscaled_font_keys_equal
);
192 if (font_map
->hash_table
== NULL
)
195 if (FT_Init_FreeType (&font_map
->ft_library
))
198 font_map
->num_open_faces
= 0;
200 cairo_ft_unscaled_font_map
= font_map
;
205 if (font_map
->hash_table
)
206 _cairo_hash_table_destroy (font_map
->hash_table
);
209 cairo_ft_unscaled_font_map
= NULL
;
213 _cairo_ft_unscaled_font_map_destroy (void)
215 cairo_ft_unscaled_font_t
*unscaled
;
216 cairo_ft_unscaled_font_map_t
*font_map
;
218 CAIRO_MUTEX_LOCK (_cairo_ft_unscaled_font_map_mutex
);
220 if (cairo_ft_unscaled_font_map
) {
221 font_map
= cairo_ft_unscaled_font_map
;
223 /* This is rather inefficient, but destroying the hash table
224 * is something we only do during debugging, (during
225 * cairo_debug_reset_static_data), when efficiency is not
228 unscaled
= _cairo_hash_table_random_entry (font_map
->hash_table
,
230 if (unscaled
== NULL
)
232 _cairo_hash_table_remove (font_map
->hash_table
,
233 &unscaled
->base
.hash_entry
);
235 _font_map_release_face_lock_held (font_map
, unscaled
);
236 _cairo_ft_unscaled_font_fini (unscaled
);
240 assert (font_map
->num_open_faces
== 0);
242 FT_Done_FreeType (font_map
->ft_library
);
244 _cairo_hash_table_destroy (font_map
->hash_table
);
248 cairo_ft_unscaled_font_map
= NULL
;
251 CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex
);
254 static cairo_ft_unscaled_font_map_t
*
255 _cairo_ft_unscaled_font_map_lock (void)
257 CAIRO_MUTEX_LOCK (_cairo_ft_unscaled_font_map_mutex
);
259 if (cairo_ft_unscaled_font_map
== NULL
)
261 _cairo_ft_unscaled_font_map_create ();
263 if (cairo_ft_unscaled_font_map
== NULL
) {
264 CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex
);
265 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
270 return cairo_ft_unscaled_font_map
;
274 _cairo_ft_unscaled_font_map_unlock (void)
276 CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex
);
280 _cairo_ft_unscaled_font_init_key (cairo_ft_unscaled_font_t
*key
,
286 key
->filename
= filename
;
289 /* 1607 is just an arbitrary prime. */
290 hash
= _cairo_hash_string (filename
);
291 hash
+= ((unsigned long) id
) * 1607;
293 key
->base
.hash_entry
.hash
= hash
;
297 * _cairo_ft_unscaled_font_init:
299 * Initialize a #cairo_ft_unscaled_font_t.
301 * There are two basic flavors of #cairo_ft_unscaled_font_t, one
302 * created from an FT_Face and the other created from a filename/id
303 * pair. These two flavors are identified as from_face and !from_face.
305 * To initialize a from_face font, pass filename==%NULL, id=0 and the
308 * To initialize a !from_face font, pass the filename/id as desired
311 * Note that the code handles these two flavors in very distinct
312 * ways. For example there is a hash_table mapping
313 * filename/id->#cairo_unscaled_font_t in the !from_face case, but no
314 * parallel in the from_face case, (where the calling code would have
315 * to do its own mapping to ensure similar sharing).
317 static cairo_status_t
318 _cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t
*unscaled
,
319 const char *filename
,
323 _cairo_unscaled_font_init (&unscaled
->base
,
324 &cairo_ft_unscaled_font_backend
);
327 unscaled
->from_face
= TRUE
;
328 unscaled
->face
= face
;
329 unscaled
->filename
= NULL
;
334 unscaled
->from_face
= FALSE
;
335 unscaled
->face
= NULL
;
337 filename_copy
= strdup (filename
);
338 if (filename_copy
== NULL
)
339 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
341 _cairo_ft_unscaled_font_init_key (unscaled
, filename_copy
, id
);
344 unscaled
->have_scale
= FALSE
;
345 CAIRO_MUTEX_INIT (unscaled
->mutex
);
346 unscaled
->lock_count
= 0;
348 unscaled
->faces
= NULL
;
350 return CAIRO_STATUS_SUCCESS
;
354 _cairo_unscaled_font_is_ft (cairo_unscaled_font_t
*unscaled_font
)
356 return unscaled_font
->backend
== &cairo_ft_unscaled_font_backend
;
360 * _cairo_ft_unscaled_font_fini:
362 * Free all data associated with a #cairo_ft_unscaled_font_t.
364 * CAUTION: The unscaled->face field must be %NULL before calling this
365 * function. This is because the #cairo_ft_unscaled_font_t_map keeps a
366 * count of these faces (font_map->num_open_faces) so it maintains the
367 * unscaled->face field while it has its lock held. See
368 * _font_map_release_face_lock_held().
371 _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t
*unscaled
)
373 assert (unscaled
->face
== NULL
);
375 if (unscaled
->filename
) {
376 free (unscaled
->filename
);
377 unscaled
->filename
= NULL
;
380 CAIRO_MUTEX_FINI (unscaled
->mutex
);
384 _cairo_ft_unscaled_font_keys_equal (const void *key_a
,
387 const cairo_ft_unscaled_font_t
*unscaled_a
= key_a
;
388 const cairo_ft_unscaled_font_t
*unscaled_b
= key_b
;
390 return (strcmp (unscaled_a
->filename
, unscaled_b
->filename
) == 0 &&
391 unscaled_a
->id
== unscaled_b
->id
);
394 /* Finds or creates a #cairo_ft_unscaled_font_t for the filename/id from
395 * pattern. Returns a new reference to the unscaled font.
397 static cairo_ft_unscaled_font_t
*
398 _cairo_ft_unscaled_font_create_for_pattern (FcPattern
*pattern
)
400 cairo_ft_unscaled_font_t key
, *unscaled
;
401 cairo_ft_unscaled_font_map_t
*font_map
;
402 cairo_status_t status
;
403 FcChar8
*fc_filename
;
407 if (FcPatternGetString (pattern
, FC_FILE
, 0, &fc_filename
) != FcResultMatch
)
409 filename
= (char *) fc_filename
;
411 if (FcPatternGetInteger (pattern
, FC_INDEX
, 0, &id
) != FcResultMatch
)
414 font_map
= _cairo_ft_unscaled_font_map_lock ();
415 if (font_map
== NULL
)
418 _cairo_ft_unscaled_font_init_key (&key
, filename
, id
);
420 /* Return existing unscaled font if it exists in the hash table. */
421 if (_cairo_hash_table_lookup (font_map
->hash_table
, &key
.base
.hash_entry
,
422 (cairo_hash_entry_t
**) &unscaled
))
424 _cairo_unscaled_font_reference (&unscaled
->base
);
425 _cairo_ft_unscaled_font_map_unlock ();
429 /* Otherwise create it and insert into hash table. */
430 unscaled
= malloc (sizeof (cairo_ft_unscaled_font_t
));
431 if (unscaled
== NULL
) {
432 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
433 goto UNWIND_FONT_MAP_LOCK
;
436 status
= _cairo_ft_unscaled_font_init (unscaled
, filename
, id
, NULL
);
438 goto UNWIND_UNSCALED_MALLOC
;
440 status
= _cairo_hash_table_insert (font_map
->hash_table
,
441 &unscaled
->base
.hash_entry
);
443 goto UNWIND_UNSCALED_FONT_INIT
;
445 _cairo_ft_unscaled_font_map_unlock ();
449 UNWIND_UNSCALED_FONT_INIT
:
450 _cairo_ft_unscaled_font_fini (unscaled
);
451 UNWIND_UNSCALED_MALLOC
:
453 UNWIND_FONT_MAP_LOCK
:
454 _cairo_ft_unscaled_font_map_unlock ();
459 static cairo_ft_unscaled_font_t
*
460 _cairo_ft_unscaled_font_create_from_face (FT_Face face
)
462 cairo_status_t status
;
463 cairo_ft_unscaled_font_t
*unscaled
;
465 unscaled
= malloc (sizeof (cairo_ft_unscaled_font_t
));
466 if (unscaled
== NULL
) {
467 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
471 status
= _cairo_ft_unscaled_font_init (unscaled
, NULL
, 0, face
);
481 _cairo_ft_unscaled_font_destroy (void *abstract_font
)
483 cairo_ft_unscaled_font_t
*unscaled
= abstract_font
;
485 if (unscaled
== NULL
)
488 if (unscaled
->from_face
) {
489 /* See comments in _ft_font_face_destroy about the "zombie" state
490 * for a _ft_font_face.
492 if (unscaled
->faces
&& !unscaled
->faces
->unscaled
)
493 cairo_font_face_destroy (&unscaled
->faces
->base
);
495 unscaled
->face
= NULL
;
497 cairo_ft_unscaled_font_map_t
*font_map
;
499 font_map
= _cairo_ft_unscaled_font_map_lock ();
500 /* All created objects must have been mapped in the font map. */
501 assert (font_map
!= NULL
);
503 _cairo_hash_table_remove (font_map
->hash_table
,
504 &unscaled
->base
.hash_entry
);
506 _font_map_release_face_lock_held (font_map
, unscaled
);
508 _cairo_ft_unscaled_font_map_unlock ();
510 _cairo_ft_unscaled_font_fini (unscaled
);
514 _has_unlocked_face (void *entry
)
516 cairo_ft_unscaled_font_t
*unscaled
= entry
;
518 return (unscaled
->lock_count
== 0 && unscaled
->face
);
521 /* Ensures that an unscaled font has a face object. If we exceed
522 * MAX_OPEN_FACES, try to close some.
524 * This differs from _cairo_ft_scaled_font_lock_face in that it doesn't
525 * set the scale on the face, but just returns it at the last scale.
528 _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t
*unscaled
)
530 cairo_ft_unscaled_font_map_t
*font_map
;
533 CAIRO_MUTEX_LOCK (unscaled
->mutex
);
534 unscaled
->lock_count
++;
537 return unscaled
->face
;
539 /* If this unscaled font was created from an FT_Face then we just
540 * returned it above. */
541 assert (!unscaled
->from_face
);
543 font_map
= _cairo_ft_unscaled_font_map_lock ();
545 assert (font_map
!= NULL
);
547 while (font_map
->num_open_faces
>= MAX_OPEN_FACES
)
549 cairo_ft_unscaled_font_t
*entry
;
551 entry
= _cairo_hash_table_random_entry (font_map
->hash_table
,
556 _font_map_release_face_lock_held (font_map
, entry
);
559 _cairo_ft_unscaled_font_map_unlock ();
561 if (FT_New_Face (font_map
->ft_library
,
566 unscaled
->lock_count
--;
567 CAIRO_MUTEX_UNLOCK (unscaled
->mutex
);
568 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
572 unscaled
->face
= face
;
574 font_map
->num_open_faces
++;
580 /* Unlock unscaled font locked with _cairo_ft_unscaled_font_lock_face
583 _cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t
*unscaled
)
585 assert (unscaled
->lock_count
> 0);
587 unscaled
->lock_count
--;
589 CAIRO_MUTEX_UNLOCK (unscaled
->mutex
);
593 static cairo_status_t
594 _compute_transform (cairo_ft_font_transform_t
*sf
,
595 cairo_matrix_t
*scale
)
597 cairo_status_t status
;
598 double x_scale
, y_scale
;
599 cairo_matrix_t normalized
= *scale
;
601 /* The font matrix has x and y "scale" components which we extract and
602 * use as character scale values. These influence the way freetype
603 * chooses hints, as well as selecting different bitmaps in
604 * hand-rendered fonts. We also copy the normalized matrix to
605 * freetype's transformation.
608 status
= _cairo_matrix_compute_scale_factors (scale
,
614 /* FreeType docs say this about x_scale and y_scale:
615 * "A character width or height smaller than 1pt is set to 1pt;"
616 * So, we cap them from below at 1.0 and let the FT transform
617 * take care of sub-1.0 scaling. */
623 sf
->x_scale
= x_scale
;
624 sf
->y_scale
= y_scale
;
626 cairo_matrix_scale (&normalized
, 1.0 / x_scale
, 1.0 / y_scale
);
628 _cairo_matrix_get_affine (&normalized
,
629 &sf
->shape
[0][0], &sf
->shape
[0][1],
630 &sf
->shape
[1][0], &sf
->shape
[1][1],
633 return CAIRO_STATUS_SUCCESS
;
636 /* Temporarily scales an unscaled font to the give scale. We catch
637 * scaling to the same size, since changing a FT_Face is expensive.
639 static cairo_status_t
640 _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t
*unscaled
,
641 cairo_matrix_t
*scale
)
643 cairo_status_t status
;
644 cairo_ft_font_transform_t sf
;
648 assert (unscaled
->face
!= NULL
);
650 if (unscaled
->have_scale
&&
651 scale
->xx
== unscaled
->current_scale
.xx
&&
652 scale
->yx
== unscaled
->current_scale
.yx
&&
653 scale
->xy
== unscaled
->current_scale
.xy
&&
654 scale
->yy
== unscaled
->current_scale
.yy
)
655 return CAIRO_STATUS_SUCCESS
;
657 unscaled
->have_scale
= TRUE
;
658 unscaled
->current_scale
= *scale
;
660 status
= _compute_transform (&sf
, scale
);
664 unscaled
->x_scale
= sf
.x_scale
;
665 unscaled
->y_scale
= sf
.y_scale
;
667 mat
.xx
= DOUBLE_TO_16_16(sf
.shape
[0][0]);
668 mat
.yx
= - DOUBLE_TO_16_16(sf
.shape
[0][1]);
669 mat
.xy
= - DOUBLE_TO_16_16(sf
.shape
[1][0]);
670 mat
.yy
= DOUBLE_TO_16_16(sf
.shape
[1][1]);
672 unscaled
->have_shape
= (mat
.xx
!= 0x10000 ||
677 unscaled
->Current_Shape
= mat
;
678 cairo_matrix_init (&unscaled
->current_shape
,
679 sf
.shape
[0][0], sf
.shape
[0][1],
680 sf
.shape
[1][0], sf
.shape
[1][1],
683 FT_Set_Transform(unscaled
->face
, &mat
, NULL
);
685 if ((unscaled
->face
->face_flags
& FT_FACE_FLAG_SCALABLE
) != 0) {
686 error
= FT_Set_Char_Size (unscaled
->face
,
687 sf
.x_scale
* 64.0 + .5,
688 sf
.y_scale
* 64.0 + .5,
691 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
693 double min_distance
= DBL_MAX
;
697 for (i
= 0; i
< unscaled
->face
->num_fixed_sizes
; i
++) {
698 #if HAVE_FT_BITMAP_SIZE_Y_PPEM
699 double size
= unscaled
->face
->available_sizes
[i
].y_ppem
/ 64.;
701 double size
= unscaled
->face
->available_sizes
[i
].height
;
703 double distance
= fabs (size
- sf
.y_scale
);
705 if (distance
<= min_distance
) {
706 min_distance
= distance
;
710 #if HAVE_FT_BITMAP_SIZE_Y_PPEM
711 error
= FT_Set_Char_Size (unscaled
->face
,
712 unscaled
->face
->available_sizes
[best_i
].x_ppem
,
713 unscaled
->face
->available_sizes
[best_i
].y_ppem
,
717 error
= FT_Set_Pixel_Sizes (unscaled
->face
,
718 unscaled
->face
->available_sizes
[best_i
].width
,
719 unscaled
->face
->available_sizes
[best_i
].height
);
721 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
724 return CAIRO_STATUS_SUCCESS
;
727 /* Empirically-derived subpixel filtering values thanks to Keith
728 * Packard and libXft. */
729 static const int filters
[3][3] = {
732 { 65538*4/7,65538*2/7,65538*1/7 },
734 { 65536*1/4, 65536*2/4, 65537*1/4 },
736 { 65538*1/7,65538*2/7,65538*4/7 },
738 { 65538*9/13,65538*3/13,65538*1/13 },
740 { 65538*1/6, 65538*4/6, 65538*1/6 },
742 { 65538*1/13,65538*3/13,65538*9/13 },
745 /* Fills in val->image with an image surface created from @bitmap
747 static cairo_status_t
748 _get_bitmap_surface (FT_Bitmap
*bitmap
,
749 cairo_bool_t own_buffer
,
750 cairo_font_options_t
*font_options
,
751 cairo_image_surface_t
**surface
)
753 int width
, height
, stride
;
755 int format
= CAIRO_FORMAT_A8
;
756 cairo_bool_t subpixel
= FALSE
;
758 width
= bitmap
->width
;
759 height
= bitmap
->rows
;
761 if (width
== 0 || height
== 0) {
762 *surface
= (cairo_image_surface_t
*)
763 cairo_image_surface_create_for_data (NULL
, format
, 0, 0, 0);
764 return (*surface
)->base
.status
;
767 switch (bitmap
->pixel_mode
) {
768 case FT_PIXEL_MODE_MONO
:
769 stride
= (((width
+ 31) & ~31) >> 3);
771 data
= bitmap
->buffer
;
772 assert (stride
== bitmap
->pitch
);
774 data
= _cairo_malloc_ab (height
, stride
);
776 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
778 if (stride
== bitmap
->pitch
) {
779 memcpy (data
, bitmap
->buffer
, stride
* height
);
782 unsigned char *source
, *dest
;
784 source
= bitmap
->buffer
;
786 for (i
= height
; i
; i
--) {
787 memcpy (dest
, source
, bitmap
->pitch
);
788 memset (dest
+ bitmap
->pitch
, '\0', stride
- bitmap
->pitch
);
790 source
+= bitmap
->pitch
;
796 #ifndef WORDS_BIGENDIAN
798 unsigned char *d
= data
;
799 int count
= stride
* height
;
802 *d
= CAIRO_BITSWAP8 (*d
);
807 format
= CAIRO_FORMAT_A1
;
810 case FT_PIXEL_MODE_LCD
:
811 case FT_PIXEL_MODE_LCD_V
:
812 case FT_PIXEL_MODE_GRAY
:
813 switch (font_options
->antialias
) {
814 case CAIRO_ANTIALIAS_DEFAULT
:
815 case CAIRO_ANTIALIAS_GRAY
:
816 case CAIRO_ANTIALIAS_NONE
:
818 stride
= bitmap
->pitch
;
820 data
= bitmap
->buffer
;
822 data
= _cairo_malloc_ab (height
, stride
);
824 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
826 memcpy (data
, bitmap
->buffer
, stride
* height
);
828 format
= CAIRO_FORMAT_A8
;
830 case CAIRO_ANTIALIAS_SUBPIXEL
: {
832 unsigned char *in_line
, *out_line
, *in
;
834 unsigned int red
, green
, blue
;
838 unsigned char *data_rgba
;
839 unsigned int width_rgba
, stride_rgba
;
843 switch (font_options
->subpixel_order
) {
844 case CAIRO_SUBPIXEL_ORDER_DEFAULT
:
845 case CAIRO_SUBPIXEL_ORDER_RGB
:
846 case CAIRO_SUBPIXEL_ORDER_BGR
:
851 case CAIRO_SUBPIXEL_ORDER_VRGB
:
852 case CAIRO_SUBPIXEL_ORDER_VBGR
:
858 * Filter the glyph to soften the color fringes
861 stride
= bitmap
->pitch
;
862 stride_rgba
= (width_rgba
* 4 + 3) & ~3;
863 data_rgba
= calloc (stride_rgba
, height
);
864 if (data_rgba
== NULL
) {
866 free (bitmap
->buffer
);
867 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
871 switch (font_options
->subpixel_order
) {
872 case CAIRO_SUBPIXEL_ORDER_VRGB
:
874 case CAIRO_SUBPIXEL_ORDER_DEFAULT
:
875 case CAIRO_SUBPIXEL_ORDER_RGB
:
881 case CAIRO_SUBPIXEL_ORDER_VBGR
:
883 case CAIRO_SUBPIXEL_ORDER_BGR
:
889 in_line
= bitmap
->buffer
;
890 out_line
= data_rgba
;
891 for (y
= 0; y
< height
; y
++)
894 out
= (unsigned int *) out_line
;
895 in_line
+= stride
* vmul
;
896 out_line
+= stride_rgba
;
897 for (x
= 0; x
< width
* hmul
; x
+= hmul
)
899 red
= green
= blue
= 0;
901 for (s
= 0; s
< 3; s
++)
903 red
+= filters
[rf
][s
]*in
[x
+o
];
904 green
+= filters
[gf
][s
]*in
[x
+o
];
905 blue
+= filters
[bf
][s
]*in
[x
+o
];
909 green
= green
/ 65536;
911 *out
++ = (green
<< 24) | (red
<< 16) | (green
<< 8) | blue
;
915 /* Images here are stored in native format. The
916 * backend must convert to its own format as needed
920 free (bitmap
->buffer
);
922 stride
= stride_rgba
;
923 format
= CAIRO_FORMAT_ARGB32
;
929 case FT_PIXEL_MODE_GRAY2
:
930 case FT_PIXEL_MODE_GRAY4
:
931 /* These could be triggered by very rare types of TrueType fonts */
934 free (bitmap
->buffer
);
935 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
938 *surface
= (cairo_image_surface_t
*)
939 cairo_image_surface_create_for_data (data
,
941 width
, height
, stride
);
942 if ((*surface
)->base
.status
) {
944 return (*surface
)->base
.status
;
948 pixman_image_set_component_alpha ((*surface
)->pixman_image
, TRUE
);
950 _cairo_image_surface_assume_ownership_of_data ((*surface
));
952 return CAIRO_STATUS_SUCCESS
;
955 /* Converts an outline FT_GlyphSlot into an image
957 * This could go through _render_glyph_bitmap as well, letting
958 * FreeType convert the outline to a bitmap, but doing it ourselves
959 * has two minor advantages: first, we save a copy of the bitmap
960 * buffer: we can directly use the buffer that FreeType renders
963 * Second, it may help when we add support for subpixel
964 * rendering: the Xft code does it this way. (Keith thinks that
965 * it may also be possible to get the subpixel rendering with
966 * FT_Render_Glyph: something worth looking into in more detail
967 * when we add subpixel support. If so, we may want to eliminate
968 * this version of the code path entirely.
970 static cairo_status_t
971 _render_glyph_outline (FT_Face face
,
972 cairo_font_options_t
*font_options
,
973 cairo_image_surface_t
**surface
)
975 FT_GlyphSlot glyphslot
= face
->glyph
;
976 FT_Outline
*outline
= &glyphslot
->outline
;
982 unsigned int width
, height
, stride
;
983 cairo_bool_t subpixel
= FALSE
;
984 cairo_status_t status
;
986 FT_Outline_Get_CBox (outline
, &cbox
);
990 cbox
.xMax
= (cbox
.xMax
+ 63) & -64;
991 cbox
.yMax
= (cbox
.yMax
+ 63) & -64;
993 width
= (unsigned int) ((cbox
.xMax
- cbox
.xMin
) >> 6);
994 height
= (unsigned int) ((cbox
.yMax
- cbox
.yMin
) >> 6);
995 stride
= (width
* hmul
+ 3) & ~3;
997 if (width
* height
== 0) {
998 cairo_format_t format
;
999 /* Looks like fb handles zero-sized images just fine */
1000 switch (font_options
->antialias
) {
1001 case CAIRO_ANTIALIAS_NONE
:
1002 format
= CAIRO_FORMAT_A1
;
1004 case CAIRO_ANTIALIAS_SUBPIXEL
:
1005 format
= CAIRO_FORMAT_ARGB32
;
1007 case CAIRO_ANTIALIAS_DEFAULT
:
1008 case CAIRO_ANTIALIAS_GRAY
:
1010 format
= CAIRO_FORMAT_A8
;
1014 (*surface
) = (cairo_image_surface_t
*)
1015 cairo_image_surface_create_for_data (NULL
, format
, 0, 0, 0);
1016 if ((*surface
)->base
.status
)
1017 return (*surface
)->base
.status
;
1020 matrix
.xx
= matrix
.yy
= 0x10000L
;
1021 matrix
.xy
= matrix
.yx
= 0;
1023 switch (font_options
->antialias
) {
1024 case CAIRO_ANTIALIAS_NONE
:
1025 bitmap
.pixel_mode
= FT_PIXEL_MODE_MONO
;
1026 bitmap
.num_grays
= 1;
1027 stride
= ((width
+ 31) & -32) >> 3;
1029 case CAIRO_ANTIALIAS_DEFAULT
:
1030 case CAIRO_ANTIALIAS_GRAY
:
1031 bitmap
.pixel_mode
= FT_PIXEL_MODE_GRAY
;
1032 bitmap
.num_grays
= 256;
1033 stride
= (width
+ 3) & -4;
1035 case CAIRO_ANTIALIAS_SUBPIXEL
:
1036 switch (font_options
->subpixel_order
) {
1037 case CAIRO_SUBPIXEL_ORDER_RGB
:
1038 case CAIRO_SUBPIXEL_ORDER_BGR
:
1039 case CAIRO_SUBPIXEL_ORDER_DEFAULT
:
1045 case CAIRO_SUBPIXEL_ORDER_VRGB
:
1046 case CAIRO_SUBPIXEL_ORDER_VBGR
:
1052 FT_Outline_Transform (outline
, &matrix
);
1054 bitmap
.pixel_mode
= FT_PIXEL_MODE_GRAY
;
1055 bitmap
.num_grays
= 256;
1056 stride
= (width
* hmul
+ 3) & -4;
1059 bitmap
.pitch
= stride
;
1060 bitmap
.width
= width
* hmul
;
1061 bitmap
.rows
= height
* vmul
;
1062 bitmap
.buffer
= calloc (stride
, bitmap
.rows
);
1063 if (bitmap
.buffer
== NULL
)
1064 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1066 FT_Outline_Translate (outline
, -cbox
.xMin
*hmul
, -cbox
.yMin
*vmul
);
1068 if (FT_Outline_Get_Bitmap (glyphslot
->library
, outline
, &bitmap
) != 0) {
1069 free (bitmap
.buffer
);
1070 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1073 status
= _get_bitmap_surface (&bitmap
, TRUE
, font_options
, surface
);
1079 * Note: the font's coordinate system is upside down from ours, so the
1080 * Y coordinate of the control box needs to be negated. Moreover, device
1081 * offsets are position of glyph origin relative to top left while xMin
1082 * and yMax are offsets of top left relative to origin. Another negation.
1084 cairo_surface_set_device_offset (&(*surface
)->base
,
1085 floor (-(double) cbox
.xMin
/ 64.0),
1086 floor (+(double) cbox
.yMax
/ 64.0));
1088 return CAIRO_STATUS_SUCCESS
;
1091 /* Converts a bitmap (or other) FT_GlyphSlot into an image */
1092 static cairo_status_t
1093 _render_glyph_bitmap (FT_Face face
,
1094 cairo_font_options_t
*font_options
,
1095 cairo_image_surface_t
**surface
)
1097 FT_GlyphSlot glyphslot
= face
->glyph
;
1098 cairo_status_t status
= CAIRO_STATUS_SUCCESS
;
1101 /* According to the FreeType docs, glyphslot->format could be
1102 * something other than FT_GLYPH_FORMAT_OUTLINE or
1103 * FT_GLYPH_FORMAT_BITMAP. Calling FT_Render_Glyph gives FreeType
1104 * the opportunity to convert such to
1105 * bitmap. FT_GLYPH_FORMAT_COMPOSITE will not be encountered since
1106 * we avoid the FT_LOAD_NO_RECURSE flag.
1108 error
= FT_Render_Glyph (glyphslot
, FT_RENDER_MODE_NORMAL
);
1109 /* XXX ignoring all other errors for now. They are not fatal, typically
1110 * just a glyph-not-found. */
1111 if (error
== FT_Err_Out_Of_Memory
)
1112 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1114 status
= _get_bitmap_surface (&glyphslot
->bitmap
, FALSE
, font_options
, surface
);
1119 * Note: the font's coordinate system is upside down from ours, so the
1120 * Y coordinate of the control box needs to be negated. Moreover, device
1121 * offsets are position of glyph origin relative to top left while
1122 * bitmap_left and bitmap_top are offsets of top left relative to origin.
1125 cairo_surface_set_device_offset (&(*surface
)->base
,
1126 -glyphslot
->bitmap_left
,
1127 +glyphslot
->bitmap_top
);
1132 static cairo_status_t
1133 _transform_glyph_bitmap (cairo_matrix_t
* shape
,
1134 cairo_image_surface_t
** surface
)
1136 cairo_matrix_t original_to_transformed
;
1137 cairo_matrix_t transformed_to_original
;
1138 cairo_image_surface_t
*old_image
;
1139 cairo_surface_t
*image
;
1141 double origin_x
, origin_y
;
1142 int orig_width
, orig_height
;
1144 int x_min
, y_min
, x_max
, y_max
;
1146 cairo_status_t status
;
1147 cairo_surface_pattern_t pattern
;
1149 /* We want to compute a transform that takes the origin
1150 * (device_x_offset, device_y_offset) to 0,0, then applies
1151 * the "shape" portion of the font transform
1153 original_to_transformed
= *shape
;
1155 cairo_surface_get_device_offset (&(*surface
)->base
, &origin_x
, &origin_y
);
1156 orig_width
= cairo_image_surface_get_width (&(*surface
)->base
);
1157 orig_height
= cairo_image_surface_get_height (&(*surface
)->base
);
1159 cairo_matrix_translate (&original_to_transformed
,
1160 -origin_x
, -origin_y
);
1162 /* Find the bounding box of the original bitmap under that
1166 x
[1] = orig_width
; y
[1] = 0;
1167 x
[2] = orig_width
; y
[2] = orig_height
;
1168 x
[3] = 0; y
[3] = orig_height
;
1170 for (i
= 0; i
< 4; i
++)
1171 cairo_matrix_transform_point (&original_to_transformed
,
1174 x_min
= floor (x
[0]); y_min
= floor (y
[0]);
1175 x_max
= ceil (x
[0]); y_max
= ceil (y
[0]);
1177 for (i
= 1; i
< 4; i
++) {
1179 x_min
= floor (x
[i
]);
1180 else if (x
[i
] > x_max
)
1181 x_max
= ceil (x
[i
]);
1183 y_min
= floor (y
[i
]);
1184 else if (y
[i
] > y_max
)
1185 y_max
= ceil (y
[i
]);
1188 /* Adjust the transform so that the bounding box starts at 0,0 ...
1189 * this gives our final transform from original bitmap to transformed
1192 original_to_transformed
.x0
-= x_min
;
1193 original_to_transformed
.y0
-= y_min
;
1195 /* Create the transformed bitmap
1197 width
= x_max
- x_min
;
1198 height
= y_max
- y_min
;
1200 transformed_to_original
= original_to_transformed
;
1201 status
= cairo_matrix_invert (&transformed_to_original
);
1205 /* We need to pad out the width to 32-bit intervals for cairo-xlib-surface.c */
1206 width
= (width
+ 3) & ~3;
1207 image
= cairo_image_surface_create (CAIRO_FORMAT_A8
, width
, height
);
1209 return image
->status
;
1211 /* Initialize it to empty
1213 status
= _cairo_surface_fill_rectangle (image
, CAIRO_OPERATOR_CLEAR
,
1214 CAIRO_COLOR_TRANSPARENT
,
1218 cairo_surface_destroy (image
);
1222 /* Draw the original bitmap transformed into the new bitmap
1224 _cairo_pattern_init_for_surface (&pattern
, &(*surface
)->base
);
1225 cairo_pattern_set_matrix (&pattern
.base
, &transformed_to_original
);
1227 status
= _cairo_surface_composite (CAIRO_OPERATOR_OVER
,
1228 &pattern
.base
, NULL
, image
,
1233 _cairo_pattern_fini (&pattern
.base
);
1236 cairo_surface_destroy (image
);
1240 /* Now update the cache entry for the new bitmap, recomputing
1241 * the origin based on the final transform.
1243 cairo_matrix_transform_point (&original_to_transformed
,
1244 &origin_x
, &origin_y
);
1246 old_image
= (*surface
);
1247 (*surface
) = (cairo_image_surface_t
*)image
;
1248 cairo_surface_destroy (&old_image
->base
);
1250 cairo_surface_set_device_offset (&(*surface
)->base
,
1251 _cairo_lround (origin_x
),
1252 _cairo_lround (origin_y
));
1256 static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend
= {
1257 _cairo_ft_unscaled_font_destroy
,
1259 _cairo_ft_unscaled_font_create_glyph
1263 /* #cairo_ft_scaled_font_t */
1265 typedef struct _cairo_ft_scaled_font
{
1266 cairo_scaled_font_t base
;
1267 cairo_ft_unscaled_font_t
*unscaled
;
1268 cairo_ft_options_t ft_options
;
1269 } cairo_ft_scaled_font_t
;
1271 const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend
;
1273 /* The load flags passed to FT_Load_Glyph control aspects like hinting and
1274 * antialiasing. Here we compute them from the fields of a FcPattern.
1277 _get_pattern_ft_options (FcPattern
*pattern
, cairo_ft_options_t
*ret
)
1279 FcBool antialias
, vertical_layout
, hinting
, autohint
, bitmap
, embolden
;
1280 cairo_ft_options_t ft_options
;
1282 #ifdef FC_HINT_STYLE
1286 _cairo_font_options_init_default (&ft_options
.base
);
1287 ft_options
.load_flags
= FT_LOAD_DEFAULT
;
1288 ft_options
.extra_flags
= 0;
1290 #ifndef FC_EMBEDDED_BITMAP
1291 #define FC_EMBEDDED_BITMAP "embeddedbitmap"
1294 /* Check whether to force use of embedded bitmaps */
1295 if (FcPatternGetBool (pattern
,
1296 FC_EMBEDDED_BITMAP
, 0, &bitmap
) != FcResultMatch
)
1299 /* disable antialiasing if requested */
1300 if (FcPatternGetBool (pattern
,
1301 FC_ANTIALIAS
, 0, &antialias
) != FcResultMatch
)
1305 cairo_subpixel_order_t subpixel_order
;
1307 /* disable hinting if requested */
1308 if (FcPatternGetBool (pattern
,
1309 FC_HINTING
, 0, &hinting
) != FcResultMatch
)
1312 if (FcPatternGetInteger (pattern
,
1313 FC_RGBA
, 0, &rgba
) != FcResultMatch
)
1314 rgba
= FC_RGBA_UNKNOWN
;
1318 subpixel_order
= CAIRO_SUBPIXEL_ORDER_RGB
;
1321 subpixel_order
= CAIRO_SUBPIXEL_ORDER_BGR
;
1324 subpixel_order
= CAIRO_SUBPIXEL_ORDER_VRGB
;
1327 subpixel_order
= CAIRO_SUBPIXEL_ORDER_VBGR
;
1329 case FC_RGBA_UNKNOWN
:
1332 subpixel_order
= CAIRO_SUBPIXEL_ORDER_DEFAULT
;
1336 if (subpixel_order
!= CAIRO_SUBPIXEL_ORDER_DEFAULT
) {
1337 ft_options
.base
.subpixel_order
= subpixel_order
;
1338 ft_options
.base
.antialias
= CAIRO_ANTIALIAS_SUBPIXEL
;
1341 #ifdef FC_HINT_STYLE
1342 if (FcPatternGetInteger (pattern
,
1343 FC_HINT_STYLE
, 0, &hintstyle
) != FcResultMatch
)
1344 hintstyle
= FC_HINT_FULL
;
1347 hintstyle
= FC_HINT_NONE
;
1349 switch (hintstyle
) {
1351 ft_options
.base
.hint_style
= CAIRO_HINT_STYLE_NONE
;
1353 case FC_HINT_SLIGHT
:
1354 ft_options
.base
.hint_style
= CAIRO_HINT_STYLE_SLIGHT
;
1356 case FC_HINT_MEDIUM
:
1358 ft_options
.base
.hint_style
= CAIRO_HINT_STYLE_MEDIUM
;
1361 ft_options
.base
.hint_style
= CAIRO_HINT_STYLE_FULL
;
1364 #else /* !FC_HINT_STYLE */
1366 ft_options
.base
.hint_style
= CAIRO_HINT_STYLE_NONE
;
1368 #endif /* FC_HINT_STYLE */
1370 /* Force embedded bitmaps off if no hinting requested */
1371 if (ft_options
.base
.hint_style
== CAIRO_HINT_STYLE_NONE
)
1375 ft_options
.load_flags
|= FT_LOAD_NO_BITMAP
;
1378 ft_options
.base
.antialias
= CAIRO_ANTIALIAS_NONE
;
1381 /* force autohinting if requested */
1382 if (FcPatternGetBool (pattern
,
1383 FC_AUTOHINT
, 0, &autohint
) != FcResultMatch
)
1387 ft_options
.load_flags
|= FT_LOAD_FORCE_AUTOHINT
;
1389 if (FcPatternGetBool (pattern
,
1390 FC_VERTICAL_LAYOUT
, 0, &vertical_layout
) != FcResultMatch
)
1391 vertical_layout
= FcFalse
;
1393 if (vertical_layout
)
1394 ft_options
.load_flags
|= FT_LOAD_VERTICAL_LAYOUT
;
1397 #define FC_EMBOLDEN "embolden"
1399 if (FcPatternGetBool (pattern
,
1400 FC_EMBOLDEN
, 0, &embolden
) != FcResultMatch
)
1404 ft_options
.extra_flags
|= CAIRO_FT_OPTIONS_EMBOLDEN
;
1410 _cairo_ft_options_merge (cairo_ft_options_t
*options
,
1411 cairo_ft_options_t
*other
)
1413 int load_flags
= other
->load_flags
;
1414 int load_target
= FT_LOAD_TARGET_NORMAL
;
1416 /* clear load target mode */
1417 load_flags
&= ~(FT_LOAD_TARGET_(FT_LOAD_TARGET_MODE(other
->load_flags
)));
1419 if (load_flags
& FT_LOAD_NO_HINTING
)
1420 other
->base
.hint_style
= CAIRO_HINT_STYLE_NONE
;
1422 if (other
->base
.antialias
== CAIRO_ANTIALIAS_NONE
||
1423 options
->base
.antialias
== CAIRO_ANTIALIAS_NONE
) {
1424 options
->base
.antialias
= CAIRO_ANTIALIAS_NONE
;
1425 options
->base
.subpixel_order
= CAIRO_SUBPIXEL_ORDER_DEFAULT
;
1428 if (other
->base
.antialias
== CAIRO_ANTIALIAS_SUBPIXEL
&&
1429 (options
->base
.antialias
== CAIRO_ANTIALIAS_DEFAULT
||
1430 options
->base
.antialias
== CAIRO_ANTIALIAS_GRAY
)) {
1431 options
->base
.antialias
= CAIRO_ANTIALIAS_SUBPIXEL
;
1432 options
->base
.subpixel_order
= other
->base
.subpixel_order
;
1435 if (options
->base
.hint_style
== CAIRO_HINT_STYLE_DEFAULT
)
1436 options
->base
.hint_style
= other
->base
.hint_style
;
1438 if (other
->base
.hint_style
== CAIRO_HINT_STYLE_NONE
)
1439 options
->base
.hint_style
= CAIRO_HINT_STYLE_NONE
;
1441 if (options
->base
.antialias
== CAIRO_ANTIALIAS_NONE
) {
1442 if (options
->base
.hint_style
== CAIRO_HINT_STYLE_NONE
)
1443 load_flags
|= FT_LOAD_NO_HINTING
;
1445 load_target
= FT_LOAD_TARGET_MONO
;
1446 load_flags
|= FT_LOAD_MONOCHROME
;
1448 switch (options
->base
.hint_style
) {
1449 case CAIRO_HINT_STYLE_NONE
:
1450 load_flags
|= FT_LOAD_NO_HINTING
;
1452 case CAIRO_HINT_STYLE_SLIGHT
:
1453 load_target
= FT_LOAD_TARGET_LIGHT
;
1455 case CAIRO_HINT_STYLE_MEDIUM
:
1457 case CAIRO_HINT_STYLE_FULL
:
1458 case CAIRO_HINT_STYLE_DEFAULT
:
1459 if (options
->base
.antialias
== CAIRO_ANTIALIAS_SUBPIXEL
) {
1460 switch (options
->base
.subpixel_order
) {
1461 case CAIRO_SUBPIXEL_ORDER_DEFAULT
:
1462 case CAIRO_SUBPIXEL_ORDER_RGB
:
1463 case CAIRO_SUBPIXEL_ORDER_BGR
:
1464 load_target
|= FT_LOAD_TARGET_LCD
;
1466 case CAIRO_SUBPIXEL_ORDER_VRGB
:
1467 case CAIRO_SUBPIXEL_ORDER_VBGR
:
1468 load_target
|= FT_LOAD_TARGET_LCD_V
;
1476 options
->load_flags
= load_flags
| load_target
;
1477 options
->extra_flags
= other
->extra_flags
;
1478 if (options
->base
.hint_metrics
!= CAIRO_HINT_METRICS_OFF
)
1479 options
->extra_flags
|= CAIRO_FT_OPTIONS_HINT_METRICS
;
1482 static cairo_status_t
1483 _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t
*unscaled
,
1484 cairo_font_face_t
*font_face
,
1485 const cairo_matrix_t
*font_matrix
,
1486 const cairo_matrix_t
*ctm
,
1487 const cairo_font_options_t
*options
,
1488 cairo_ft_options_t ft_options
,
1489 cairo_scaled_font_t
**font_out
)
1491 cairo_ft_scaled_font_t
*scaled_font
;
1493 FT_Size_Metrics
*metrics
;
1494 cairo_font_extents_t fs_metrics
;
1495 cairo_status_t status
;
1497 face
= _cairo_ft_unscaled_font_lock_face (unscaled
);
1499 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1501 scaled_font
= malloc (sizeof(cairo_ft_scaled_font_t
));
1502 if (scaled_font
== NULL
) {
1503 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1507 _cairo_unscaled_font_reference (&unscaled
->base
);
1508 scaled_font
->unscaled
= unscaled
;
1510 _cairo_font_options_init_copy (&scaled_font
->ft_options
.base
, options
);
1511 _cairo_ft_options_merge (&scaled_font
->ft_options
, &ft_options
);
1513 status
= _cairo_scaled_font_init (&scaled_font
->base
,
1515 font_matrix
, ctm
, options
,
1516 &cairo_ft_scaled_font_backend
);
1518 _cairo_unscaled_font_destroy (&unscaled
->base
);
1523 status
= _cairo_ft_unscaled_font_set_scale (unscaled
,
1524 &scaled_font
->base
.scale
);
1526 _cairo_unscaled_font_destroy (&unscaled
->base
);
1532 metrics
= &face
->size
->metrics
;
1535 * Get to unscaled metrics so that the upper level can get back to
1538 * Also use this path for bitmap-only fonts. The other branch uses
1539 * face members that are only relevant for scalable fonts. This is
1540 * detected by simply checking for units_per_EM==0.
1542 if (scaled_font
->base
.options
.hint_metrics
!= CAIRO_HINT_METRICS_OFF
||
1543 face
->units_per_EM
== 0) {
1544 double x_factor
, y_factor
;
1546 if (unscaled
->x_scale
== 0)
1549 x_factor
= 1 / unscaled
->x_scale
;
1551 if (unscaled
->y_scale
== 0)
1554 y_factor
= 1 / unscaled
->y_scale
;
1556 fs_metrics
.ascent
= DOUBLE_FROM_26_6(metrics
->ascender
) * y_factor
;
1557 fs_metrics
.descent
= DOUBLE_FROM_26_6(- metrics
->descender
) * y_factor
;
1558 fs_metrics
.height
= DOUBLE_FROM_26_6(metrics
->height
) * y_factor
;
1559 if (!_cairo_ft_scaled_font_is_vertical (&scaled_font
->base
)) {
1560 fs_metrics
.max_x_advance
= DOUBLE_FROM_26_6(metrics
->max_advance
) * x_factor
;
1561 fs_metrics
.max_y_advance
= 0;
1563 fs_metrics
.max_x_advance
= 0;
1564 fs_metrics
.max_y_advance
= DOUBLE_FROM_26_6(metrics
->max_advance
) * y_factor
;
1567 double scale
= face
->units_per_EM
;
1569 fs_metrics
.ascent
= face
->ascender
/ scale
;
1570 fs_metrics
.descent
= - face
->descender
/ scale
;
1571 fs_metrics
.height
= face
->height
/ scale
;
1572 if (!_cairo_ft_scaled_font_is_vertical (&scaled_font
->base
)) {
1573 fs_metrics
.max_x_advance
= face
->max_advance_width
/ scale
;
1574 fs_metrics
.max_y_advance
= 0;
1576 fs_metrics
.max_x_advance
= 0;
1577 fs_metrics
.max_y_advance
= face
->max_advance_height
/ scale
;
1581 status
= _cairo_scaled_font_set_metrics (&scaled_font
->base
, &fs_metrics
);
1583 *font_out
= &scaled_font
->base
;
1586 _cairo_ft_unscaled_font_unlock_face (unscaled
);
1592 _cairo_scaled_font_is_ft (cairo_scaled_font_t
*scaled_font
)
1594 return scaled_font
->backend
== &cairo_ft_scaled_font_backend
;
1597 static cairo_status_t
1598 _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t
*toy_face
,
1599 const cairo_matrix_t
*font_matrix
,
1600 const cairo_matrix_t
*ctm
,
1601 const cairo_font_options_t
*font_options
,
1602 cairo_scaled_font_t
**font
)
1604 FcPattern
*pattern
, *resolved
;
1605 cairo_ft_unscaled_font_t
*unscaled
;
1609 cairo_matrix_t scale
;
1610 cairo_status_t status
;
1611 cairo_ft_font_transform_t sf
;
1612 cairo_ft_options_t ft_options
;
1614 cairo_matrix_multiply (&scale
, font_matrix
, ctm
);
1615 status
= _compute_transform (&sf
, &scale
);
1619 pattern
= FcPatternCreate ();
1621 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1623 if (!FcPatternAddString (pattern
,
1624 FC_FAMILY
, (unsigned char *) toy_face
->family
))
1626 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1630 switch (toy_face
->slant
)
1632 case CAIRO_FONT_SLANT_ITALIC
:
1633 fcslant
= FC_SLANT_ITALIC
;
1635 case CAIRO_FONT_SLANT_OBLIQUE
:
1636 fcslant
= FC_SLANT_OBLIQUE
;
1638 case CAIRO_FONT_SLANT_NORMAL
:
1640 fcslant
= FC_SLANT_ROMAN
;
1644 if (!FcPatternAddInteger (pattern
, FC_SLANT
, fcslant
)) {
1645 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1649 switch (toy_face
->weight
)
1651 case CAIRO_FONT_WEIGHT_BOLD
:
1652 fcweight
= FC_WEIGHT_BOLD
;
1654 case CAIRO_FONT_WEIGHT_NORMAL
:
1656 fcweight
= FC_WEIGHT_MEDIUM
;
1660 if (!FcPatternAddInteger (pattern
, FC_WEIGHT
, fcweight
)) {
1661 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1665 if (! FcPatternAddDouble (pattern
, FC_PIXEL_SIZE
, sf
.y_scale
)) {
1666 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1670 if (! FcConfigSubstitute (NULL
, pattern
, FcMatchPattern
)) {
1671 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1675 status
= _cairo_ft_font_options_substitute (font_options
, pattern
);
1679 FcDefaultSubstitute (pattern
);
1681 resolved
= FcFontMatch (NULL
, pattern
, &result
);
1683 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1687 unscaled
= _cairo_ft_unscaled_font_create_for_pattern (resolved
);
1689 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1693 _get_pattern_ft_options (resolved
, &ft_options
);
1695 status
= _cairo_ft_scaled_font_create (unscaled
,
1698 font_options
, ft_options
,
1701 _cairo_unscaled_font_destroy (&unscaled
->base
);
1704 FcPatternDestroy (resolved
);
1707 FcPatternDestroy (pattern
);
1713 _cairo_ft_scaled_font_fini (void *abstract_font
)
1715 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
1717 if (scaled_font
== NULL
)
1720 _cairo_unscaled_font_destroy (&scaled_font
->unscaled
->base
);
1724 _move_to (FT_Vector
*to
, void *closure
)
1726 cairo_path_fixed_t
*path
= closure
;
1729 x
= _cairo_fixed_from_26_6 (to
->x
);
1730 y
= _cairo_fixed_from_26_6 (to
->y
);
1732 if (_cairo_path_fixed_close_path (path
) != CAIRO_STATUS_SUCCESS
)
1734 if (_cairo_path_fixed_move_to (path
, x
, y
) != CAIRO_STATUS_SUCCESS
)
1741 _line_to (FT_Vector
*to
, void *closure
)
1743 cairo_path_fixed_t
*path
= closure
;
1746 x
= _cairo_fixed_from_26_6 (to
->x
);
1747 y
= _cairo_fixed_from_26_6 (to
->y
);
1749 if (_cairo_path_fixed_line_to (path
, x
, y
) != CAIRO_STATUS_SUCCESS
)
1756 _conic_to (FT_Vector
*control
, FT_Vector
*to
, void *closure
)
1758 cairo_path_fixed_t
*path
= closure
;
1760 cairo_fixed_t x0
, y0
;
1761 cairo_fixed_t x1
, y1
;
1762 cairo_fixed_t x2
, y2
;
1763 cairo_fixed_t x3
, y3
;
1764 cairo_point_t conic
;
1766 if (! _cairo_path_fixed_get_current_point (path
, &x0
, &y0
))
1769 conic
.x
= _cairo_fixed_from_26_6 (control
->x
);
1770 conic
.y
= _cairo_fixed_from_26_6 (control
->y
);
1772 x3
= _cairo_fixed_from_26_6 (to
->x
);
1773 y3
= _cairo_fixed_from_26_6 (to
->y
);
1775 x1
= x0
+ 2.0/3.0 * (conic
.x
- x0
);
1776 y1
= y0
+ 2.0/3.0 * (conic
.y
- y0
);
1778 x2
= x3
+ 2.0/3.0 * (conic
.x
- x3
);
1779 y2
= y3
+ 2.0/3.0 * (conic
.y
- y3
);
1781 if (_cairo_path_fixed_curve_to (path
,
1784 x3
, y3
) != CAIRO_STATUS_SUCCESS
)
1791 _cubic_to (FT_Vector
*control1
, FT_Vector
*control2
,
1792 FT_Vector
*to
, void *closure
)
1794 cairo_path_fixed_t
*path
= closure
;
1795 cairo_fixed_t x0
, y0
;
1796 cairo_fixed_t x1
, y1
;
1797 cairo_fixed_t x2
, y2
;
1799 x0
= _cairo_fixed_from_26_6 (control1
->x
);
1800 y0
= _cairo_fixed_from_26_6 (control1
->y
);
1802 x1
= _cairo_fixed_from_26_6 (control2
->x
);
1803 y1
= _cairo_fixed_from_26_6 (control2
->y
);
1805 x2
= _cairo_fixed_from_26_6 (to
->x
);
1806 y2
= _cairo_fixed_from_26_6 (to
->y
);
1808 if (_cairo_path_fixed_curve_to (path
,
1811 x2
, y2
) != CAIRO_STATUS_SUCCESS
)
1817 static cairo_status_t
1818 _decompose_glyph_outline (FT_Face face
,
1819 cairo_font_options_t
*options
,
1820 cairo_path_fixed_t
**pathp
)
1822 static const FT_Outline_Funcs outline_funcs
= {
1823 (FT_Outline_MoveToFunc
)_move_to
,
1824 (FT_Outline_LineToFunc
)_line_to
,
1825 (FT_Outline_ConicToFunc
)_conic_to
,
1826 (FT_Outline_CubicToFunc
)_cubic_to
,
1830 static const FT_Matrix invert_y
= {
1831 DOUBLE_TO_16_16 (1.0), 0,
1832 0, DOUBLE_TO_16_16 (-1.0),
1836 cairo_path_fixed_t
*path
;
1837 cairo_status_t status
;
1839 path
= _cairo_path_fixed_create ();
1841 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1843 glyph
= face
->glyph
;
1845 /* Font glyphs have an inverted Y axis compared to cairo. */
1846 FT_Outline_Transform (&glyph
->outline
, &invert_y
);
1847 if (FT_Outline_Decompose (&glyph
->outline
, &outline_funcs
, path
)) {
1848 _cairo_path_fixed_destroy (path
);
1849 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1852 status
= _cairo_path_fixed_close_path (path
);
1854 _cairo_path_fixed_destroy (path
);
1860 return CAIRO_STATUS_SUCCESS
;
1864 * Translate glyph to match its metrics.
1867 _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (void *abstract_font
,
1870 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
1873 vector
.x
= glyph
->metrics
.vertBearingX
- glyph
->metrics
.horiBearingX
;
1874 vector
.y
= -glyph
->metrics
.vertBearingY
- glyph
->metrics
.horiBearingY
;
1876 if (glyph
->format
== FT_GLYPH_FORMAT_OUTLINE
) {
1877 FT_Vector_Transform (&vector
, &scaled_font
->unscaled
->Current_Shape
);
1878 FT_Outline_Translate(&glyph
->outline
, vector
.x
, vector
.y
);
1879 } else if (glyph
->format
== FT_GLYPH_FORMAT_BITMAP
) {
1880 glyph
->bitmap_left
+= vector
.x
/ 64;
1881 glyph
->bitmap_top
+= vector
.y
/ 64;
1885 static cairo_int_status_t
1886 _cairo_ft_scaled_glyph_init (void *abstract_font
,
1887 cairo_scaled_glyph_t
*scaled_glyph
,
1888 cairo_scaled_glyph_info_t info
)
1890 cairo_text_extents_t fs_metrics
;
1891 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
1892 cairo_ft_unscaled_font_t
*unscaled
= scaled_font
->unscaled
;
1896 int load_flags
= scaled_font
->ft_options
.load_flags
;
1897 FT_Glyph_Metrics
*metrics
;
1898 double x_factor
, y_factor
;
1899 cairo_bool_t vertical_layout
= FALSE
;
1900 cairo_status_t status
;
1902 face
= _cairo_ft_unscaled_font_lock_face (unscaled
);
1904 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1906 status
= _cairo_ft_unscaled_font_set_scale (scaled_font
->unscaled
,
1907 &scaled_font
->base
.scale
);
1911 /* Ignore global advance unconditionally */
1912 load_flags
|= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
;
1914 if ((info
& CAIRO_SCALED_GLYPH_INFO_PATH
) != 0 &&
1915 (info
& CAIRO_SCALED_GLYPH_INFO_SURFACE
) == 0)
1916 load_flags
|= FT_LOAD_NO_BITMAP
;
1919 * Don't pass FT_LOAD_VERTICAL_LAYOUT to FT_Load_Glyph here as
1920 * suggested by freetype people.
1922 if (load_flags
& FT_LOAD_VERTICAL_LAYOUT
) {
1923 load_flags
&= ~FT_LOAD_VERTICAL_LAYOUT
;
1924 vertical_layout
= TRUE
;
1927 error
= FT_Load_Glyph (scaled_font
->unscaled
->face
,
1928 _cairo_scaled_glyph_index(scaled_glyph
),
1930 /* XXX ignoring all other errors for now. They are not fatal, typically
1931 * just a glyph-not-found. */
1932 if (error
== FT_Err_Out_Of_Memory
) {
1933 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1937 glyph
= face
->glyph
;
1939 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
1941 * embolden glyphs if requested
1943 if (scaled_font
->ft_options
.extra_flags
& CAIRO_FT_OPTIONS_EMBOLDEN
)
1944 FT_GlyphSlot_Embolden (glyph
);
1947 if (vertical_layout
)
1948 _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font
, glyph
);
1950 if (info
& CAIRO_SCALED_GLYPH_INFO_METRICS
) {
1952 cairo_bool_t hint_metrics
= scaled_font
->base
.options
.hint_metrics
!= CAIRO_HINT_METRICS_OFF
;
1954 * Compute font-space metrics
1956 metrics
= &glyph
->metrics
;
1958 if (unscaled
->x_scale
== 0)
1961 x_factor
= 1 / unscaled
->x_scale
;
1963 if (unscaled
->y_scale
== 0)
1966 y_factor
= 1 / unscaled
->y_scale
;
1969 * Note: Y coordinates of the horizontal bearing need to be negated.
1971 * Scale metrics back to glyph space from the scaled glyph space returned
1974 * If we want hinted metrics but aren't asking for hinted glyphs from
1975 * FreeType, then we need to do the metric hinting ourselves.
1978 if (hint_metrics
&& (load_flags
& FT_LOAD_NO_HINTING
))
1984 if (!vertical_layout
) {
1985 x1
= (metrics
->horiBearingX
) & -64;
1986 x2
= (metrics
->horiBearingX
+ metrics
->width
+ 63) & -64;
1987 y1
= (-metrics
->horiBearingY
) & -64;
1988 y2
= (-metrics
->horiBearingY
+ metrics
->height
+ 63) & -64;
1990 advance
= ((metrics
->horiAdvance
+ 32) & -64);
1992 fs_metrics
.x_bearing
= DOUBLE_FROM_26_6 (x1
) * x_factor
;
1993 fs_metrics
.y_bearing
= DOUBLE_FROM_26_6 (y1
) * y_factor
;
1995 fs_metrics
.width
= DOUBLE_FROM_26_6 (x2
- x1
) * x_factor
;
1996 fs_metrics
.height
= DOUBLE_FROM_26_6 (y2
- y1
) * y_factor
;
1998 fs_metrics
.x_advance
= DOUBLE_FROM_26_6 (advance
) * x_factor
;
1999 fs_metrics
.y_advance
= 0;
2001 x1
= (metrics
->vertBearingX
) & -64;
2002 x2
= (metrics
->vertBearingX
+ metrics
->width
+ 63) & -64;
2003 y1
= (metrics
->vertBearingY
) & -64;
2004 y2
= (metrics
->vertBearingY
+ metrics
->height
+ 63) & -64;
2006 advance
= ((metrics
->vertAdvance
+ 32) & -64);
2008 fs_metrics
.x_bearing
= DOUBLE_FROM_26_6 (x1
) * x_factor
;
2009 fs_metrics
.y_bearing
= DOUBLE_FROM_26_6 (y1
) * y_factor
;
2011 fs_metrics
.width
= DOUBLE_FROM_26_6 (x2
- x1
) * x_factor
;
2012 fs_metrics
.height
= DOUBLE_FROM_26_6 (y2
- y1
) * y_factor
;
2014 fs_metrics
.x_advance
= 0;
2015 fs_metrics
.y_advance
= DOUBLE_FROM_26_6 (advance
) * y_factor
;
2018 fs_metrics
.width
= DOUBLE_FROM_26_6 (metrics
->width
) * x_factor
;
2019 fs_metrics
.height
= DOUBLE_FROM_26_6 (metrics
->height
) * y_factor
;
2021 if (!vertical_layout
) {
2022 fs_metrics
.x_bearing
= DOUBLE_FROM_26_6 (metrics
->horiBearingX
) * x_factor
;
2023 fs_metrics
.y_bearing
= DOUBLE_FROM_26_6 (-metrics
->horiBearingY
) * y_factor
;
2025 if (hint_metrics
|| glyph
->format
!= FT_GLYPH_FORMAT_OUTLINE
)
2026 fs_metrics
.x_advance
= DOUBLE_FROM_26_6 (metrics
->horiAdvance
) * x_factor
;
2028 fs_metrics
.x_advance
= DOUBLE_FROM_16_16 (glyph
->linearHoriAdvance
) * x_factor
;
2029 fs_metrics
.y_advance
= 0 * y_factor
;
2031 fs_metrics
.x_bearing
= DOUBLE_FROM_26_6 (metrics
->vertBearingX
) * x_factor
;
2032 fs_metrics
.y_bearing
= DOUBLE_FROM_26_6 (metrics
->vertBearingY
) * y_factor
;
2034 fs_metrics
.x_advance
= 0 * x_factor
;
2035 if (hint_metrics
|| glyph
->format
!= FT_GLYPH_FORMAT_OUTLINE
)
2036 fs_metrics
.y_advance
= DOUBLE_FROM_26_6 (metrics
->vertAdvance
) * y_factor
;
2038 fs_metrics
.y_advance
= DOUBLE_FROM_26_6 (glyph
->linearVertAdvance
) * y_factor
;
2042 _cairo_scaled_glyph_set_metrics (scaled_glyph
,
2047 if ((info
& CAIRO_SCALED_GLYPH_INFO_SURFACE
) != 0) {
2048 cairo_image_surface_t
*surface
;
2050 if (glyph
->format
== FT_GLYPH_FORMAT_OUTLINE
) {
2051 status
= _render_glyph_outline (face
, &scaled_font
->ft_options
.base
,
2054 status
= _render_glyph_bitmap (face
, &scaled_font
->ft_options
.base
,
2056 if (status
== CAIRO_STATUS_SUCCESS
&& unscaled
->have_shape
) {
2057 status
= _transform_glyph_bitmap (&unscaled
->current_shape
,
2060 cairo_surface_destroy (&surface
->base
);
2066 _cairo_scaled_glyph_set_surface (scaled_glyph
,
2071 if (info
& CAIRO_SCALED_GLYPH_INFO_PATH
) {
2072 cairo_path_fixed_t
*path
= NULL
; /* hide compiler warning */
2075 * A kludge -- the above code will trash the outline,
2076 * so reload it. This will probably never occur though
2078 if ((info
& CAIRO_SCALED_GLYPH_INFO_SURFACE
) != 0) {
2079 error
= FT_Load_Glyph (face
,
2080 _cairo_scaled_glyph_index(scaled_glyph
),
2081 load_flags
| FT_LOAD_NO_BITMAP
);
2082 /* XXX ignoring all other errors for now. They are not fatal, typically
2083 * just a glyph-not-found. */
2084 if (error
== FT_Err_Out_Of_Memory
) {
2085 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2088 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
2090 * embolden glyphs if requested
2092 if (scaled_font
->ft_options
.extra_flags
& CAIRO_FT_OPTIONS_EMBOLDEN
)
2093 FT_GlyphSlot_Embolden (glyph
);
2095 if (vertical_layout
)
2096 _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font
, glyph
);
2099 if (glyph
->format
== FT_GLYPH_FORMAT_OUTLINE
)
2100 status
= _decompose_glyph_outline (face
, &scaled_font
->ft_options
.base
,
2103 status
= CAIRO_INT_STATUS_UNSUPPORTED
;
2108 _cairo_scaled_glyph_set_path (scaled_glyph
,
2113 _cairo_ft_unscaled_font_unlock_face (unscaled
);
2118 static unsigned long
2119 _cairo_ft_ucs4_to_index (void *abstract_font
,
2122 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
2123 cairo_ft_unscaled_font_t
*unscaled
= scaled_font
->unscaled
;
2127 face
= _cairo_ft_unscaled_font_lock_face (unscaled
);
2130 index
= FT_Get_Char_Index (face
, ucs4
);
2131 _cairo_ft_unscaled_font_unlock_face (unscaled
);
2135 static cairo_int_status_t
2136 _cairo_ft_load_truetype_table (void *abstract_font
,
2139 unsigned char *buffer
,
2140 unsigned long *length
)
2142 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
2143 cairo_ft_unscaled_font_t
*unscaled
= scaled_font
->unscaled
;
2145 cairo_status_t status
= CAIRO_INT_STATUS_UNSUPPORTED
;
2147 if (_cairo_ft_scaled_font_is_vertical (&scaled_font
->base
))
2148 return CAIRO_INT_STATUS_UNSUPPORTED
;
2150 #if HAVE_FT_LOAD_SFNT_TABLE
2151 face
= _cairo_ft_unscaled_font_lock_face (unscaled
);
2153 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2155 if (FT_IS_SFNT (face
) &&
2156 FT_Load_Sfnt_Table (face
, tag
, offset
, buffer
, length
) == 0)
2157 status
= CAIRO_STATUS_SUCCESS
;
2159 _cairo_ft_unscaled_font_unlock_face (unscaled
);
2165 static cairo_int_status_t
2166 _cairo_ft_map_glyphs_to_unicode (void *abstract_font
,
2167 cairo_scaled_font_subset_t
*font_subset
)
2169 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
2170 cairo_ft_unscaled_font_t
*unscaled
= scaled_font
->unscaled
;
2173 unsigned long charcode
;
2177 face
= _cairo_ft_unscaled_font_lock_face (unscaled
);
2179 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2181 count
= font_subset
->num_glyphs
;
2182 charcode
= FT_Get_First_Char( face
, &glyph
);
2183 while (glyph
!= 0 && count
> 0)
2185 for (i
= 0; i
< font_subset
->num_glyphs
; i
++) {
2186 if (font_subset
->glyphs
[i
] == glyph
) {
2187 font_subset
->to_unicode
[i
] = charcode
;
2192 charcode
= FT_Get_Next_Char (face
, charcode
, &glyph
);
2194 _cairo_ft_unscaled_font_unlock_face (unscaled
);
2196 return CAIRO_STATUS_SUCCESS
;
2199 const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend
= {
2201 _cairo_ft_scaled_font_create_toy
,
2202 _cairo_ft_scaled_font_fini
,
2203 _cairo_ft_scaled_glyph_init
,
2204 NULL
, /* text_to_glyphs */
2205 _cairo_ft_ucs4_to_index
,
2206 NULL
, /* show_glyphs */
2207 _cairo_ft_load_truetype_table
,
2208 _cairo_ft_map_glyphs_to_unicode
,
2211 /* #cairo_ft_font_face_t */
2214 _cairo_ft_font_face_destroy (void *abstract_face
)
2216 cairo_ft_font_face_t
*font_face
= abstract_face
;
2218 cairo_ft_font_face_t
*tmp_face
= NULL
;
2219 cairo_ft_font_face_t
*last_face
= NULL
;
2221 if (font_face
== NULL
)
2224 /* When destroying the face created by cairo_ft_font_face_create_for_ft_face,
2225 * we have a special "zombie" state for the face when the unscaled font
2226 * is still alive but there are no public references to the font face.
2230 * font_face ------> unscaled
2235 * font_face <------- unscaled
2238 if (font_face
->unscaled
&&
2239 font_face
->unscaled
->from_face
&&
2240 CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face
->unscaled
->base
.ref_count
) > 1)
2242 cairo_font_face_reference (&font_face
->base
);
2244 _cairo_unscaled_font_destroy (&font_face
->unscaled
->base
);
2245 font_face
->unscaled
= NULL
;
2250 if (font_face
->unscaled
) {
2251 /* Remove face from linked list */
2252 for (tmp_face
= font_face
->unscaled
->faces
;
2254 tmp_face
= tmp_face
->next
)
2256 if (tmp_face
== font_face
) {
2258 last_face
->next
= tmp_face
->next
;
2260 font_face
->unscaled
->faces
= tmp_face
->next
;
2263 last_face
= tmp_face
;
2266 _cairo_unscaled_font_destroy (&font_face
->unscaled
->base
);
2267 font_face
->unscaled
= NULL
;
2271 static cairo_status_t
2272 _cairo_ft_font_face_scaled_font_create (void *abstract_face
,
2273 const cairo_matrix_t
*font_matrix
,
2274 const cairo_matrix_t
*ctm
,
2275 const cairo_font_options_t
*options
,
2276 cairo_scaled_font_t
**scaled_font
)
2278 cairo_ft_font_face_t
*font_face
= abstract_face
;
2279 cairo_ft_options_t ft_options
;
2281 /* The handling of font options is different depending on how the
2282 * font face was created. When the user creates a font face with
2283 * cairo_ft_font_face_create_for_ft_face(), then the load flags
2284 * passed in augment the load flags for the options. But for
2285 * cairo_ft_font_face_create_for_pattern(), the load flags are
2286 * derived from a pattern where the user has called
2287 * cairo_ft_font_options_substitute(), so *just* use those load
2288 * flags and ignore the options.
2291 ft_options
= font_face
->ft_options
;
2293 return _cairo_ft_scaled_font_create (font_face
->unscaled
,
2296 options
, ft_options
,
2300 static const cairo_font_face_backend_t _cairo_ft_font_face_backend
= {
2302 _cairo_ft_font_face_destroy
,
2303 _cairo_ft_font_face_scaled_font_create
2306 static cairo_font_face_t
*
2307 _cairo_ft_font_face_create (cairo_ft_unscaled_font_t
*unscaled
,
2308 cairo_ft_options_t
*ft_options
)
2310 cairo_ft_font_face_t
*font_face
, **prev_font_face
;
2312 /* Looked for an existing matching font face */
2313 for (font_face
= unscaled
->faces
, prev_font_face
= &unscaled
->faces
;
2315 prev_font_face
= &font_face
->next
, font_face
= font_face
->next
)
2317 if (font_face
->ft_options
.load_flags
== ft_options
->load_flags
&&
2318 font_face
->ft_options
.extra_flags
== ft_options
->extra_flags
&&
2319 cairo_font_options_equal (&font_face
->ft_options
.base
, &ft_options
->base
))
2321 if (font_face
->base
.status
== CAIRO_STATUS_SUCCESS
)
2322 return cairo_font_face_reference (&font_face
->base
);
2324 /* The font_face has been left in an error state, abandon it. */
2325 *prev_font_face
= font_face
->next
;
2330 /* No match found, create a new one */
2331 font_face
= malloc (sizeof (cairo_ft_font_face_t
));
2333 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
2334 return (cairo_font_face_t
*)&_cairo_font_face_nil
;
2337 font_face
->unscaled
= unscaled
;
2338 _cairo_unscaled_font_reference (&unscaled
->base
);
2340 font_face
->ft_options
= *ft_options
;
2342 font_face
->next
= unscaled
->faces
;
2343 unscaled
->faces
= font_face
;
2345 _cairo_font_face_init (&font_face
->base
, &_cairo_ft_font_face_backend
);
2347 return &font_face
->base
;
2350 /* implement the platform-specific interface */
2352 static cairo_status_t
2353 _cairo_ft_font_options_substitute (const cairo_font_options_t
*options
,
2358 if (options
->antialias
!= CAIRO_ANTIALIAS_DEFAULT
)
2360 if (FcPatternGet (pattern
, FC_ANTIALIAS
, 0, &v
) == FcResultNoMatch
)
2362 if (! FcPatternAddBool (pattern
,
2364 options
->antialias
!= CAIRO_ANTIALIAS_NONE
))
2365 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2367 if (options
->antialias
!= CAIRO_ANTIALIAS_SUBPIXEL
) {
2368 FcPatternDel (pattern
, FC_RGBA
);
2369 if (! FcPatternAddInteger (pattern
, FC_RGBA
, FC_RGBA_NONE
))
2370 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2375 if (options
->antialias
!= CAIRO_ANTIALIAS_DEFAULT
)
2377 if (FcPatternGet (pattern
, FC_RGBA
, 0, &v
) == FcResultNoMatch
)
2381 if (options
->antialias
== CAIRO_ANTIALIAS_SUBPIXEL
) {
2382 switch (options
->subpixel_order
) {
2383 case CAIRO_SUBPIXEL_ORDER_DEFAULT
:
2384 case CAIRO_SUBPIXEL_ORDER_RGB
:
2388 case CAIRO_SUBPIXEL_ORDER_BGR
:
2391 case CAIRO_SUBPIXEL_ORDER_VRGB
:
2392 rgba
= FC_RGBA_VRGB
;
2394 case CAIRO_SUBPIXEL_ORDER_VBGR
:
2395 rgba
= FC_RGBA_VBGR
;
2399 rgba
= FC_RGBA_NONE
;
2402 if (! FcPatternAddInteger (pattern
, FC_RGBA
, rgba
))
2403 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2407 if (options
->hint_style
!= CAIRO_HINT_STYLE_DEFAULT
)
2409 if (FcPatternGet (pattern
, FC_HINTING
, 0, &v
) == FcResultNoMatch
)
2411 if (! FcPatternAddBool (pattern
,
2413 options
->hint_style
!= CAIRO_HINT_STYLE_NONE
))
2414 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2417 #ifdef FC_HINT_STYLE
2418 if (FcPatternGet (pattern
, FC_HINT_STYLE
, 0, &v
) == FcResultNoMatch
)
2422 switch (options
->hint_style
) {
2423 case CAIRO_HINT_STYLE_NONE
:
2424 hint_style
= FC_HINT_NONE
;
2426 case CAIRO_HINT_STYLE_SLIGHT
:
2427 hint_style
= FC_HINT_SLIGHT
;
2429 case CAIRO_HINT_STYLE_MEDIUM
:
2430 hint_style
= FC_HINT_MEDIUM
;
2432 case CAIRO_HINT_STYLE_FULL
:
2433 case CAIRO_HINT_STYLE_DEFAULT
:
2435 hint_style
= FC_HINT_FULL
;
2439 if (! FcPatternAddInteger (pattern
, FC_HINT_STYLE
, hint_style
))
2440 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2445 return CAIRO_STATUS_SUCCESS
;
2449 * cairo_ft_font_options_substitute:
2450 * @options: a #cairo_font_options_t object
2451 * @pattern: an existing #FcPattern
2453 * Add options to a #FcPattern based on a #cairo_font_options_t font
2454 * options object. Options that are already in the pattern, are not overridden,
2455 * so you should call this function after calling FcConfigSubstitute() (the
2456 * user's settings should override options based on the surface type), but
2457 * before calling FcDefaultSubstitute().
2460 cairo_ft_font_options_substitute (const cairo_font_options_t
*options
,
2463 if (cairo_font_options_status ((cairo_font_options_t
*) options
))
2466 _cairo_ft_font_options_substitute (options
, pattern
);
2470 * cairo_ft_font_face_create_for_pattern:
2471 * @pattern: A fully resolved fontconfig
2472 * pattern. A pattern can be resolved, by, among other things, calling
2473 * FcConfigSubstitute(), FcDefaultSubstitute(), then
2474 * FcFontMatch(). Cairo will call FcPatternReference() on this
2475 * pattern, so you should not further modify the pattern, but you can
2476 * release your reference to the pattern with FcPatternDestroy() if
2477 * you no longer need to access it.
2479 * Creates a new font face for the FreeType font backend based on a
2480 * fontconfig pattern. This font can then be used with
2481 * cairo_set_font_face() or cairo_scaled_font_create(). The
2482 * #cairo_scaled_font_t returned from cairo_scaled_font_create() is
2483 * also for the FreeType backend and can be used with functions such
2484 * as cairo_ft_scaled_font_lock_face().
2486 * Font rendering options are represented both here and when you
2487 * call cairo_scaled_font_create(). Font options that have a representation
2488 * in a #FcPattern must be passed in here; to modify #FcPattern
2489 * appropriately to reflect the options in a #cairo_font_options_t, call
2490 * cairo_ft_font_options_substitute().
2492 * Return value: a newly created #cairo_font_face_t. Free with
2493 * cairo_font_face_destroy() when you are done using it.
2496 cairo_ft_font_face_create_for_pattern (FcPattern
*pattern
)
2498 cairo_ft_unscaled_font_t
*unscaled
;
2499 cairo_font_face_t
*font_face
;
2500 cairo_ft_options_t ft_options
;
2502 unscaled
= _cairo_ft_unscaled_font_create_for_pattern (pattern
);
2503 if (unscaled
== NULL
) {
2504 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
2505 return (cairo_font_face_t
*)&_cairo_font_face_nil
;
2508 _get_pattern_ft_options (pattern
, &ft_options
);
2509 font_face
= _cairo_ft_font_face_create (unscaled
, &ft_options
);
2510 _cairo_unscaled_font_destroy (&unscaled
->base
);
2516 * cairo_ft_font_face_create_for_ft_face:
2517 * @face: A FreeType face object, already opened. This must
2518 * be kept around until the face's ref_count drops to
2519 * zero and it is freed. Since the face may be referenced
2520 * internally to Cairo, the best way to determine when it
2521 * is safe to free the face is to pass a
2522 * #cairo_destroy_func_t to cairo_font_face_set_user_data()
2523 * @load_flags: flags to pass to FT_Load_Glyph when loading
2524 * glyphs from the font. These flags are OR'ed together with
2525 * the flags derived from the #cairo_font_options_t passed
2526 * to cairo_scaled_font_create(), so only a few values such
2527 * as %FT_LOAD_VERTICAL_LAYOUT, and %FT_LOAD_FORCE_AUTOHINT
2528 * are useful. You should not pass any of the flags affecting
2529 * the load target, such as %FT_LOAD_TARGET_LIGHT.
2531 * Creates a new font face for the FreeType font backend from a
2532 * pre-opened FreeType face. This font can then be used with
2533 * cairo_set_font_face() or cairo_scaled_font_create(). The
2534 * #cairo_scaled_font_t returned from cairo_scaled_font_create() is
2535 * also for the FreeType backend and can be used with functions such
2536 * as cairo_ft_scaled_font_lock_face().
2538 * As an example, here is how one might correctly couple the lifetime of
2539 * the FreeType face object to the #cairo_font_face_t:
2541 * <informalexample><programlisting>
2542 * static const cairo_user_data_key_t key;
2544 * font_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
2545 * status = cairo_font_face_set_user_data (font_face, &key,
2546 * ft_face, (cairo_destroy_func_t) FT_Done_Face);
2548 * cairo_font_face_destroy (font_face);
2549 * FT_Done_Face (ft_face);
2552 * </programlisting></informalexample>
2554 * Return value: a newly created #cairo_font_face_t. Free with
2555 * cairo_font_face_destroy() when you are done using it.
2558 cairo_ft_font_face_create_for_ft_face (FT_Face face
,
2561 cairo_ft_unscaled_font_t
*unscaled
;
2562 cairo_font_face_t
*font_face
;
2563 cairo_ft_options_t ft_options
;
2565 unscaled
= _cairo_ft_unscaled_font_create_from_face (face
);
2566 if (unscaled
== NULL
) {
2567 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
2568 return (cairo_font_face_t
*)&_cairo_font_face_nil
;
2571 ft_options
.load_flags
= load_flags
;
2572 ft_options
.extra_flags
= 0;
2573 _cairo_font_options_init_default (&ft_options
.base
);
2575 font_face
= _cairo_ft_font_face_create (unscaled
, &ft_options
);
2576 _cairo_unscaled_font_destroy (&unscaled
->base
);
2582 * cairo_ft_scaled_font_lock_face:
2583 * @scaled_font: A #cairo_scaled_font_t from the FreeType font backend. Such an
2584 * object can be created by calling cairo_scaled_font_create() on a
2585 * FreeType backend font face (see cairo_ft_font_face_create_for_pattern(),
2586 * cairo_ft_font_face_create_for_ft_face()).
2588 * cairo_ft_scaled_font_lock_face() gets the #FT_Face object from a FreeType
2589 * backend font and scales it appropriately for the font. You must
2590 * release the face with cairo_ft_scaled_font_unlock_face()
2591 * when you are done using it. Since the #FT_Face object can be
2592 * shared between multiple #cairo_scaled_font_t objects, you must not
2593 * lock any other font objects until you unlock this one. A count is
2594 * kept of the number of times cairo_ft_scaled_font_lock_face() is
2595 * called. cairo_ft_scaled_font_unlock_face() must be called the same number
2598 * You must be careful when using this function in a library or in a
2599 * threaded application, because freetype's design makes it unsafe to
2600 * call freetype functions simultaneously from multiple threads, (even
2601 * if using distinct FT_Face objects). Because of this, application
2602 * code that acquires an FT_Face object with this call must add it's
2603 * own locking to protect any use of that object, (and which also must
2604 * protect any other calls into cairo as almost any cairo function
2605 * might result in a call into the freetype library).
2607 * Return value: The #FT_Face object for @font, scaled appropriately,
2608 * or %NULL if @scaled_font is in an error state (see
2609 * cairo_scaled_font_status()) or there is insufficient memory.
2612 cairo_ft_scaled_font_lock_face (cairo_scaled_font_t
*abstract_font
)
2614 cairo_ft_scaled_font_t
*scaled_font
= (cairo_ft_scaled_font_t
*) abstract_font
;
2616 cairo_status_t status
;
2618 if (scaled_font
->base
.status
)
2621 face
= _cairo_ft_unscaled_font_lock_face (scaled_font
->unscaled
);
2623 status
= _cairo_scaled_font_set_error (&scaled_font
->base
, CAIRO_STATUS_NO_MEMORY
);
2627 status
= _cairo_ft_unscaled_font_set_scale (scaled_font
->unscaled
,
2628 &scaled_font
->base
.scale
);
2630 _cairo_ft_unscaled_font_unlock_face (scaled_font
->unscaled
);
2631 status
= _cairo_scaled_font_set_error (&scaled_font
->base
, status
);
2635 /* Note: We deliberately release the unscaled font's mutex here,
2636 * so that we are not holding a lock across two separate calls to
2637 * cairo function, (which would give the application some
2638 * opportunity for creating deadlock. This is obviously unsafe,
2639 * but as documented, the user must add manual locking when using
2641 CAIRO_MUTEX_UNLOCK (scaled_font
->unscaled
->mutex
);
2647 * cairo_ft_scaled_font_unlock_face:
2648 * @scaled_font: A #cairo_scaled_font_t from the FreeType font backend. Such an
2649 * object can be created by calling cairo_scaled_font_create() on a
2650 * FreeType backend font face (see cairo_ft_font_face_create_for_pattern(),
2651 * cairo_ft_font_face_create_for_ft_face()).
2653 * Releases a face obtained with cairo_ft_scaled_font_lock_face().
2656 cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t
*abstract_font
)
2658 cairo_ft_scaled_font_t
*scaled_font
= (cairo_ft_scaled_font_t
*) abstract_font
;
2660 if (scaled_font
->base
.status
)
2663 /* Note: We released the unscaled font's mutex at the end of
2664 * cairo_ft_scaled_font_lock_face, so we have to acquire it again
2665 * as _cairo_ft_unscaled_font_unlock_face expects it to be held
2666 * when we call into it. */
2667 CAIRO_MUTEX_LOCK (scaled_font
->unscaled
->mutex
);
2669 _cairo_ft_unscaled_font_unlock_face (scaled_font
->unscaled
);
2672 /* We expose our unscaled font implementation internally for the the
2673 * PDF backend, which needs to keep track of the the different
2674 * fonts-on-disk used by a document, so it can embed them.
2676 cairo_unscaled_font_t
*
2677 _cairo_ft_scaled_font_get_unscaled_font (cairo_scaled_font_t
*abstract_font
)
2679 cairo_ft_scaled_font_t
*scaled_font
= (cairo_ft_scaled_font_t
*) abstract_font
;
2681 return &scaled_font
->unscaled
->base
;
2685 _cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t
*scaled_font
)
2687 cairo_ft_scaled_font_t
*ft_scaled_font
;
2689 if (!_cairo_scaled_font_is_ft (scaled_font
))
2692 ft_scaled_font
= (cairo_ft_scaled_font_t
*) scaled_font
;
2693 if (ft_scaled_font
->ft_options
.load_flags
& FT_LOAD_VERTICAL_LAYOUT
)
2699 _cairo_ft_font_reset_static_data (void)
2701 _cairo_ft_unscaled_font_map_destroy ();