1 /* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
2 /* cairo - a vector graphics library with display and print output
4 * Copyright © 2000 Keith Packard
5 * Copyright © 2005 Red Hat, Inc
7 * This library is free software; you can redistribute it and/or
8 * modify it either under the terms of the GNU Lesser General Public
9 * License version 2.1 as published by the Free Software Foundation
10 * (the "LGPL") or, at your option, under the terms of the Mozilla
11 * Public License Version 1.1 (the "MPL"). If you do not alter this
12 * notice, a recipient may use your version of this file under either
13 * the MPL or the LGPL.
15 * You should have received a copy of the LGPL along with this library
16 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * You should have received a copy of the MPL along with this library
19 * in the file COPYING-MPL-1.1
21 * The contents of this file are subject to the Mozilla Public License
22 * Version 1.1 (the "License"); you may not use this file except in
23 * compliance with the License. You may obtain a copy of the License at
24 * http://www.mozilla.org/MPL/
26 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
27 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
28 * the specific language governing rights and limitations.
30 * The Original Code is the cairo graphics library.
32 * The Initial Developer of the Original Code is Red Hat, Inc.
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-ft-private.h"
48 #include <fontconfig/fontconfig.h>
49 #include <fontconfig/fcfreetype.h>
52 #include FT_FREETYPE_H
55 #include FT_TRUETYPE_TABLES_H
56 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
57 #include FT_SYNTHESIS_H
60 #define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
61 #define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
62 #define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
63 #define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0)
65 /* This is the max number of FT_face objects we keep open at once
67 #define MAX_OPEN_FACES 10
70 * The simple 2x2 matrix is converted into separate scale and shape
71 * factors so that hinting works right
74 typedef struct _cairo_ft_font_transform
{
75 double x_scale
, y_scale
;
77 } cairo_ft_font_transform_t
;
80 * We create an object that corresponds to a single font on the disk;
81 * (identified by a filename/id pair) these are shared between all
82 * fonts using that file. For cairo_ft_font_face_create_for_ft_face(), we
83 * just create a one-off version with a permanent face value.
86 typedef struct _cairo_ft_font_face cairo_ft_font_face_t
;
88 struct _cairo_ft_unscaled_font
{
89 cairo_unscaled_font_t base
;
91 cairo_bool_t from_face
; /* was the FT_Face provided by user? */
92 FT_Face face
; /* provided or cached face */
94 /* only set if from_face is false */
98 /* We temporarily scale the unscaled font as needed */
99 cairo_bool_t have_scale
;
100 cairo_matrix_t current_scale
;
101 double x_scale
; /* Extracted X scale factor */
102 double y_scale
; /* Extracted Y scale factor */
103 cairo_bool_t have_shape
; /* true if the current scale has a non-scale component*/
104 cairo_matrix_t current_shape
;
105 FT_Matrix Current_Shape
;
110 cairo_ft_font_face_t
*faces
; /* Linked list of faces for this font */
114 _cairo_ft_unscaled_font_keys_equal (const void *key_a
,
118 _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t
*unscaled
);
120 static cairo_status_t
121 _cairo_ft_font_options_substitute (const cairo_font_options_t
*options
,
124 typedef enum _cairo_ft_extra_flags
{
125 CAIRO_FT_OPTIONS_HINT_METRICS
= (1 << 0),
126 CAIRO_FT_OPTIONS_EMBOLDEN
= (1 << 1)
127 } cairo_ft_extra_flags_t
;
129 typedef struct _cairo_ft_options
{
130 cairo_font_options_t base
;
131 int load_flags
; /* flags for FT_Load_Glyph */
132 cairo_ft_extra_flags_t extra_flags
; /* other flags that affect results */
133 } cairo_ft_options_t
;
135 struct _cairo_ft_font_face
{
136 cairo_font_face_t base
;
137 cairo_ft_unscaled_font_t
*unscaled
;
138 cairo_ft_options_t ft_options
;
139 cairo_ft_font_face_t
*next
;
142 static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend
;
145 * We maintain a hash table to map file/id => #cairo_ft_unscaled_font_t.
146 * The hash table itself isn't limited in size. However, we limit the
147 * number of FT_Face objects we keep around; when we've exceeded that
148 * limit and need to create a new FT_Face, we dump the FT_Face from a
149 * random #cairo_ft_unscaled_font_t which has an unlocked FT_Face, (if
153 typedef struct _cairo_ft_unscaled_font_map
{
154 cairo_hash_table_t
*hash_table
;
155 FT_Library ft_library
;
157 } cairo_ft_unscaled_font_map_t
;
159 static cairo_ft_unscaled_font_map_t
*cairo_ft_unscaled_font_map
= NULL
;
162 _font_map_release_face_lock_held (cairo_ft_unscaled_font_map_t
*font_map
,
163 cairo_ft_unscaled_font_t
*unscaled
)
165 if (unscaled
->face
) {
166 FT_Done_Face (unscaled
->face
);
167 unscaled
->face
= NULL
;
168 unscaled
->have_scale
= FALSE
;
170 font_map
->num_open_faces
--;
175 _cairo_ft_unscaled_font_map_create (void)
177 cairo_ft_unscaled_font_map_t
*font_map
;
179 /* This function is only intended to be called from
180 * _cairo_ft_unscaled_font_map_lock. So we'll crash if we can
181 * detect some other call path. */
182 assert (cairo_ft_unscaled_font_map
== NULL
);
184 font_map
= malloc (sizeof (cairo_ft_unscaled_font_map_t
));
185 if (font_map
== NULL
) {
186 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
190 font_map
->hash_table
=
191 _cairo_hash_table_create (_cairo_ft_unscaled_font_keys_equal
);
193 if (font_map
->hash_table
== NULL
)
196 if (FT_Init_FreeType (&font_map
->ft_library
))
199 font_map
->num_open_faces
= 0;
201 cairo_ft_unscaled_font_map
= font_map
;
206 if (font_map
->hash_table
)
207 _cairo_hash_table_destroy (font_map
->hash_table
);
210 cairo_ft_unscaled_font_map
= NULL
;
214 _cairo_ft_unscaled_font_map_destroy (void)
216 cairo_ft_unscaled_font_t
*unscaled
;
217 cairo_ft_unscaled_font_map_t
*font_map
;
219 CAIRO_MUTEX_LOCK (_cairo_ft_unscaled_font_map_mutex
);
221 if (cairo_ft_unscaled_font_map
) {
222 font_map
= cairo_ft_unscaled_font_map
;
224 /* This is rather inefficient, but destroying the hash table
225 * is something we only do during debugging, (during
226 * cairo_debug_reset_static_data), when efficiency is not
229 unscaled
= _cairo_hash_table_random_entry (font_map
->hash_table
,
231 if (unscaled
== NULL
)
233 _cairo_hash_table_remove (font_map
->hash_table
,
234 &unscaled
->base
.hash_entry
);
236 _font_map_release_face_lock_held (font_map
, unscaled
);
237 _cairo_ft_unscaled_font_fini (unscaled
);
241 assert (font_map
->num_open_faces
== 0);
243 FT_Done_FreeType (font_map
->ft_library
);
245 _cairo_hash_table_destroy (font_map
->hash_table
);
249 cairo_ft_unscaled_font_map
= NULL
;
252 CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex
);
255 static cairo_ft_unscaled_font_map_t
*
256 _cairo_ft_unscaled_font_map_lock (void)
258 CAIRO_MUTEX_LOCK (_cairo_ft_unscaled_font_map_mutex
);
260 if (cairo_ft_unscaled_font_map
== NULL
)
262 _cairo_ft_unscaled_font_map_create ();
264 if (cairo_ft_unscaled_font_map
== NULL
) {
265 CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex
);
266 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
271 return cairo_ft_unscaled_font_map
;
275 _cairo_ft_unscaled_font_map_unlock (void)
277 CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex
);
281 _cairo_ft_unscaled_font_init_key (cairo_ft_unscaled_font_t
*key
,
282 cairo_bool_t from_face
,
289 key
->from_face
= from_face
;
290 key
->filename
= filename
;
294 hash
= _cairo_hash_string (filename
);
295 /* the constants are just arbitrary primes */
296 hash
+= ((unsigned long) id
) * 1607;
297 hash
+= ((unsigned long) face
) * 2137;
299 key
->base
.hash_entry
.hash
= hash
;
303 * _cairo_ft_unscaled_font_init:
305 * Initialize a #cairo_ft_unscaled_font_t.
307 * There are two basic flavors of #cairo_ft_unscaled_font_t, one
308 * created from an FT_Face and the other created from a filename/id
309 * pair. These two flavors are identified as from_face and !from_face.
311 * To initialize a from_face font, pass filename==%NULL, id=0 and the
314 * To initialize a !from_face font, pass the filename/id as desired
317 * Note that the code handles these two flavors in very distinct
318 * ways. For example there is a hash_table mapping
319 * filename/id->#cairo_unscaled_font_t in the !from_face case, but no
320 * parallel in the from_face case, (where the calling code would have
321 * to do its own mapping to ensure similar sharing).
323 static cairo_status_t
324 _cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t
*unscaled
,
325 cairo_bool_t from_face
,
326 const char *filename
,
330 _cairo_unscaled_font_init (&unscaled
->base
,
331 &cairo_ft_unscaled_font_backend
);
334 unscaled
->from_face
= TRUE
;
335 _cairo_ft_unscaled_font_init_key (unscaled
, TRUE
, NULL
, 0, face
);
339 unscaled
->from_face
= FALSE
;
340 unscaled
->face
= NULL
;
342 filename_copy
= strdup (filename
);
343 if (filename_copy
== NULL
)
344 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
345 _cairo_ft_unscaled_font_init_key (unscaled
, FALSE
, filename_copy
, id
, NULL
);
348 unscaled
->have_scale
= FALSE
;
349 CAIRO_MUTEX_INIT (unscaled
->mutex
);
350 unscaled
->lock_count
= 0;
352 unscaled
->faces
= NULL
;
354 return CAIRO_STATUS_SUCCESS
;
358 * _cairo_ft_unscaled_font_fini:
360 * Free all data associated with a #cairo_ft_unscaled_font_t.
362 * CAUTION: The unscaled->face field must be %NULL before calling this
363 * function. This is because the #cairo_ft_unscaled_font_t_map keeps a
364 * count of these faces (font_map->num_open_faces) so it maintains the
365 * unscaled->face field while it has its lock held. See
366 * _font_map_release_face_lock_held().
369 _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t
*unscaled
)
371 assert (unscaled
->face
== NULL
);
373 if (unscaled
->filename
) {
374 free (unscaled
->filename
);
375 unscaled
->filename
= NULL
;
378 CAIRO_MUTEX_FINI (unscaled
->mutex
);
382 _cairo_ft_unscaled_font_keys_equal (const void *key_a
,
385 const cairo_ft_unscaled_font_t
*unscaled_a
= key_a
;
386 const cairo_ft_unscaled_font_t
*unscaled_b
= key_b
;
388 if (unscaled_a
->id
== unscaled_b
->id
&&
389 unscaled_a
->from_face
== unscaled_b
->from_face
)
391 if (unscaled_a
->from_face
)
392 return unscaled_a
->face
== unscaled_b
->face
;
394 if (unscaled_a
->filename
== NULL
&& unscaled_b
->filename
== NULL
)
396 else if (unscaled_a
->filename
== NULL
|| unscaled_b
->filename
== NULL
)
399 return (strcmp (unscaled_a
->filename
, unscaled_b
->filename
) == 0);
405 /* Finds or creates a #cairo_ft_unscaled_font_t for the filename/id from
406 * pattern. Returns a new reference to the unscaled font.
408 static cairo_ft_unscaled_font_t
*
409 _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face
,
414 cairo_ft_unscaled_font_t key
, *unscaled
;
415 cairo_ft_unscaled_font_map_t
*font_map
;
416 cairo_status_t status
;
418 font_map
= _cairo_ft_unscaled_font_map_lock ();
419 if (font_map
== NULL
)
422 _cairo_ft_unscaled_font_init_key (&key
, from_face
, filename
, id
, font_face
);
424 /* Return existing unscaled font if it exists in the hash table. */
425 if (_cairo_hash_table_lookup (font_map
->hash_table
, &key
.base
.hash_entry
,
426 (cairo_hash_entry_t
**) &unscaled
))
428 _cairo_unscaled_font_reference (&unscaled
->base
);
429 _cairo_ft_unscaled_font_map_unlock ();
433 /* Otherwise create it and insert into hash table. */
434 unscaled
= malloc (sizeof (cairo_ft_unscaled_font_t
));
435 if (unscaled
== NULL
) {
436 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
437 goto UNWIND_FONT_MAP_LOCK
;
440 status
= _cairo_ft_unscaled_font_init (unscaled
, from_face
, filename
, id
, font_face
);
442 goto UNWIND_UNSCALED_MALLOC
;
444 status
= _cairo_hash_table_insert (font_map
->hash_table
,
445 &unscaled
->base
.hash_entry
);
447 goto UNWIND_UNSCALED_FONT_INIT
;
449 _cairo_ft_unscaled_font_map_unlock ();
453 UNWIND_UNSCALED_FONT_INIT
:
454 _cairo_ft_unscaled_font_fini (unscaled
);
455 UNWIND_UNSCALED_MALLOC
:
457 UNWIND_FONT_MAP_LOCK
:
458 _cairo_ft_unscaled_font_map_unlock ();
464 static cairo_ft_unscaled_font_t
*
465 _cairo_ft_unscaled_font_create_for_pattern (FcPattern
*pattern
)
467 FT_Face font_face
= NULL
;
468 char *filename
= NULL
;
471 if (FcPatternGetFTFace (pattern
, FC_FT_FACE
, 0, &font_face
) != FcResultMatch
) {
472 FcChar8
*fc_filename
= NULL
;
474 if (FcPatternGetString (pattern
, FC_FILE
, 0, &fc_filename
) != FcResultMatch
)
476 filename
= (char *) fc_filename
;
478 if (FcPatternGetInteger (pattern
, FC_INDEX
, 0, &id
) != FcResultMatch
)
482 return _cairo_ft_unscaled_font_create_internal (font_face
!= NULL
, filename
, id
, font_face
);
488 static cairo_ft_unscaled_font_t
*
489 _cairo_ft_unscaled_font_create_from_face (FT_Face face
)
491 return _cairo_ft_unscaled_font_create_internal (TRUE
, NULL
, 0, face
);
495 _cairo_ft_unscaled_font_destroy (void *abstract_font
)
497 cairo_ft_unscaled_font_t
*unscaled
= abstract_font
;
498 cairo_ft_unscaled_font_map_t
*font_map
;
500 if (unscaled
== NULL
)
503 font_map
= _cairo_ft_unscaled_font_map_lock ();
504 /* All created objects must have been mapped in the font map. */
505 assert (font_map
!= NULL
);
507 _cairo_hash_table_remove (font_map
->hash_table
,
508 &unscaled
->base
.hash_entry
);
510 if (unscaled
->from_face
) {
511 /* See comments in _ft_font_face_destroy about the "zombie" state
512 * for a _ft_font_face.
514 if (unscaled
->faces
&& !unscaled
->faces
->unscaled
)
515 cairo_font_face_destroy (&unscaled
->faces
->base
);
517 _font_map_release_face_lock_held (font_map
, unscaled
);
519 unscaled
->face
= NULL
;
521 _cairo_ft_unscaled_font_map_unlock ();
523 _cairo_ft_unscaled_font_fini (unscaled
);
527 _has_unlocked_face (void *entry
)
529 cairo_ft_unscaled_font_t
*unscaled
= entry
;
531 return (unscaled
->lock_count
== 0 && unscaled
->face
);
534 /* Ensures that an unscaled font has a face object. If we exceed
535 * MAX_OPEN_FACES, try to close some.
537 * This differs from _cairo_ft_scaled_font_lock_face in that it doesn't
538 * set the scale on the face, but just returns it at the last scale.
541 _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t
*unscaled
)
543 cairo_ft_unscaled_font_map_t
*font_map
;
546 CAIRO_MUTEX_LOCK (unscaled
->mutex
);
547 unscaled
->lock_count
++;
550 return unscaled
->face
;
552 /* If this unscaled font was created from an FT_Face then we just
553 * returned it above. */
554 assert (!unscaled
->from_face
);
556 font_map
= _cairo_ft_unscaled_font_map_lock ();
558 assert (font_map
!= NULL
);
560 while (font_map
->num_open_faces
>= MAX_OPEN_FACES
)
562 cairo_ft_unscaled_font_t
*entry
;
564 entry
= _cairo_hash_table_random_entry (font_map
->hash_table
,
569 _font_map_release_face_lock_held (font_map
, entry
);
572 _cairo_ft_unscaled_font_map_unlock ();
574 if (FT_New_Face (font_map
->ft_library
,
579 unscaled
->lock_count
--;
580 CAIRO_MUTEX_UNLOCK (unscaled
->mutex
);
581 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
585 unscaled
->face
= face
;
587 font_map
->num_open_faces
++;
593 /* Unlock unscaled font locked with _cairo_ft_unscaled_font_lock_face
596 _cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t
*unscaled
)
598 assert (unscaled
->lock_count
> 0);
600 unscaled
->lock_count
--;
602 CAIRO_MUTEX_UNLOCK (unscaled
->mutex
);
606 static cairo_status_t
607 _compute_transform (cairo_ft_font_transform_t
*sf
,
608 cairo_matrix_t
*scale
)
610 cairo_status_t status
;
611 double x_scale
, y_scale
;
612 cairo_matrix_t normalized
= *scale
;
614 /* The font matrix has x and y "scale" components which we extract and
615 * use as character scale values. These influence the way freetype
616 * chooses hints, as well as selecting different bitmaps in
617 * hand-rendered fonts. We also copy the normalized matrix to
618 * freetype's transformation.
621 status
= _cairo_matrix_compute_basis_scale_factors (scale
,
627 /* FreeType docs say this about x_scale and y_scale:
628 * "A character width or height smaller than 1pt is set to 1pt;"
629 * So, we cap them from below at 1.0 and let the FT transform
630 * take care of sub-1.0 scaling. */
636 sf
->x_scale
= x_scale
;
637 sf
->y_scale
= y_scale
;
639 cairo_matrix_scale (&normalized
, 1.0 / x_scale
, 1.0 / y_scale
);
641 _cairo_matrix_get_affine (&normalized
,
642 &sf
->shape
[0][0], &sf
->shape
[0][1],
643 &sf
->shape
[1][0], &sf
->shape
[1][1],
646 return CAIRO_STATUS_SUCCESS
;
649 /* Temporarily scales an unscaled font to the give scale. We catch
650 * scaling to the same size, since changing a FT_Face is expensive.
652 static cairo_status_t
653 _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t
*unscaled
,
654 cairo_matrix_t
*scale
)
656 cairo_status_t status
;
657 cairo_ft_font_transform_t sf
;
661 assert (unscaled
->face
!= NULL
);
663 if (unscaled
->have_scale
&&
664 scale
->xx
== unscaled
->current_scale
.xx
&&
665 scale
->yx
== unscaled
->current_scale
.yx
&&
666 scale
->xy
== unscaled
->current_scale
.xy
&&
667 scale
->yy
== unscaled
->current_scale
.yy
)
668 return CAIRO_STATUS_SUCCESS
;
670 unscaled
->have_scale
= TRUE
;
671 unscaled
->current_scale
= *scale
;
673 status
= _compute_transform (&sf
, scale
);
677 unscaled
->x_scale
= sf
.x_scale
;
678 unscaled
->y_scale
= sf
.y_scale
;
680 mat
.xx
= DOUBLE_TO_16_16(sf
.shape
[0][0]);
681 mat
.yx
= - DOUBLE_TO_16_16(sf
.shape
[0][1]);
682 mat
.xy
= - DOUBLE_TO_16_16(sf
.shape
[1][0]);
683 mat
.yy
= DOUBLE_TO_16_16(sf
.shape
[1][1]);
685 unscaled
->have_shape
= (mat
.xx
!= 0x10000 ||
690 unscaled
->Current_Shape
= mat
;
691 cairo_matrix_init (&unscaled
->current_shape
,
692 sf
.shape
[0][0], sf
.shape
[0][1],
693 sf
.shape
[1][0], sf
.shape
[1][1],
696 FT_Set_Transform(unscaled
->face
, &mat
, NULL
);
698 if ((unscaled
->face
->face_flags
& FT_FACE_FLAG_SCALABLE
) != 0) {
699 error
= FT_Set_Char_Size (unscaled
->face
,
700 sf
.x_scale
* 64.0 + .5,
701 sf
.y_scale
* 64.0 + .5,
704 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
706 double min_distance
= DBL_MAX
;
710 for (i
= 0; i
< unscaled
->face
->num_fixed_sizes
; i
++) {
711 #if HAVE_FT_BITMAP_SIZE_Y_PPEM
712 double size
= unscaled
->face
->available_sizes
[i
].y_ppem
/ 64.;
714 double size
= unscaled
->face
->available_sizes
[i
].height
;
716 double distance
= fabs (size
- sf
.y_scale
);
718 if (distance
<= min_distance
) {
719 min_distance
= distance
;
723 #if HAVE_FT_BITMAP_SIZE_Y_PPEM
724 error
= FT_Set_Char_Size (unscaled
->face
,
725 unscaled
->face
->available_sizes
[best_i
].x_ppem
,
726 unscaled
->face
->available_sizes
[best_i
].y_ppem
,
730 error
= FT_Set_Pixel_Sizes (unscaled
->face
,
731 unscaled
->face
->available_sizes
[best_i
].width
,
732 unscaled
->face
->available_sizes
[best_i
].height
);
734 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
737 return CAIRO_STATUS_SUCCESS
;
740 /* Empirically-derived subpixel filtering values thanks to Keith
741 * Packard and libXft. */
742 static const int filters
[3][3] = {
745 { 65538*4/7,65538*2/7,65538*1/7 },
747 { 65536*1/4, 65536*2/4, 65537*1/4 },
749 { 65538*1/7,65538*2/7,65538*4/7 },
751 { 65538*9/13,65538*3/13,65538*1/13 },
753 { 65538*1/6, 65538*4/6, 65538*1/6 },
755 { 65538*1/13,65538*3/13,65538*9/13 },
758 /* Fills in val->image with an image surface created from @bitmap
760 static cairo_status_t
761 _get_bitmap_surface (FT_Bitmap
*bitmap
,
762 cairo_bool_t own_buffer
,
763 cairo_font_options_t
*font_options
,
764 cairo_image_surface_t
**surface
)
766 int width
, height
, stride
;
768 int format
= CAIRO_FORMAT_A8
;
769 cairo_bool_t subpixel
= FALSE
;
771 width
= bitmap
->width
;
772 height
= bitmap
->rows
;
774 if (width
== 0 || height
== 0) {
775 *surface
= (cairo_image_surface_t
*)
776 cairo_image_surface_create_for_data (NULL
, format
, 0, 0, 0);
777 return (*surface
)->base
.status
;
780 switch (bitmap
->pixel_mode
) {
781 case FT_PIXEL_MODE_MONO
:
782 stride
= (((width
+ 31) & ~31) >> 3);
784 data
= bitmap
->buffer
;
785 assert (stride
== bitmap
->pitch
);
787 data
= _cairo_malloc_ab (height
, stride
);
789 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
791 if (stride
== bitmap
->pitch
) {
792 memcpy (data
, bitmap
->buffer
, stride
* height
);
795 unsigned char *source
, *dest
;
797 source
= bitmap
->buffer
;
799 for (i
= height
; i
; i
--) {
800 memcpy (dest
, source
, bitmap
->pitch
);
801 memset (dest
+ bitmap
->pitch
, '\0', stride
- bitmap
->pitch
);
803 source
+= bitmap
->pitch
;
809 #ifndef WORDS_BIGENDIAN
812 int count
= stride
* height
;
815 *d
= CAIRO_BITSWAP8 (*d
);
820 format
= CAIRO_FORMAT_A1
;
823 case FT_PIXEL_MODE_LCD
:
824 case FT_PIXEL_MODE_LCD_V
:
825 case FT_PIXEL_MODE_GRAY
:
826 switch (font_options
->antialias
) {
827 case CAIRO_ANTIALIAS_DEFAULT
:
828 case CAIRO_ANTIALIAS_GRAY
:
829 case CAIRO_ANTIALIAS_NONE
:
831 stride
= bitmap
->pitch
;
833 data
= bitmap
->buffer
;
835 data
= _cairo_malloc_ab (height
, stride
);
837 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
839 memcpy (data
, bitmap
->buffer
, stride
* height
);
841 format
= CAIRO_FORMAT_A8
;
843 case CAIRO_ANTIALIAS_SUBPIXEL
: {
845 unsigned char *in_line
, *out_line
, *in
;
847 unsigned int red
, green
, blue
;
851 unsigned char *data_rgba
;
852 unsigned int width_rgba
, stride_rgba
;
856 switch (font_options
->subpixel_order
) {
857 case CAIRO_SUBPIXEL_ORDER_DEFAULT
:
858 case CAIRO_SUBPIXEL_ORDER_RGB
:
859 case CAIRO_SUBPIXEL_ORDER_BGR
:
864 case CAIRO_SUBPIXEL_ORDER_VRGB
:
865 case CAIRO_SUBPIXEL_ORDER_VBGR
:
871 * Filter the glyph to soften the color fringes
874 stride
= bitmap
->pitch
;
875 stride_rgba
= (width_rgba
* 4 + 3) & ~3;
876 data_rgba
= calloc (stride_rgba
, height
);
877 if (data_rgba
== NULL
) {
879 free (bitmap
->buffer
);
880 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
884 switch (font_options
->subpixel_order
) {
885 case CAIRO_SUBPIXEL_ORDER_VRGB
:
887 case CAIRO_SUBPIXEL_ORDER_DEFAULT
:
888 case CAIRO_SUBPIXEL_ORDER_RGB
:
894 case CAIRO_SUBPIXEL_ORDER_VBGR
:
896 case CAIRO_SUBPIXEL_ORDER_BGR
:
902 in_line
= bitmap
->buffer
;
903 out_line
= data_rgba
;
904 for (y
= 0; y
< height
; y
++)
907 out
= (unsigned int *) out_line
;
908 in_line
+= stride
* vmul
;
909 out_line
+= stride_rgba
;
910 for (x
= 0; x
< width
* hmul
; x
+= hmul
)
912 red
= green
= blue
= 0;
914 for (s
= 0; s
< 3; s
++)
916 red
+= filters
[rf
][s
]*in
[x
+o
];
917 green
+= filters
[gf
][s
]*in
[x
+o
];
918 blue
+= filters
[bf
][s
]*in
[x
+o
];
922 green
= green
/ 65536;
924 *out
++ = (green
<< 24) | (red
<< 16) | (green
<< 8) | blue
;
928 /* Images here are stored in native format. The
929 * backend must convert to its own format as needed
933 free (bitmap
->buffer
);
935 stride
= stride_rgba
;
936 format
= CAIRO_FORMAT_ARGB32
;
942 case FT_PIXEL_MODE_GRAY2
:
943 case FT_PIXEL_MODE_GRAY4
:
944 /* These could be triggered by very rare types of TrueType fonts */
947 free (bitmap
->buffer
);
948 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
951 *surface
= (cairo_image_surface_t
*)
952 cairo_image_surface_create_for_data (data
,
954 width
, height
, stride
);
955 if ((*surface
)->base
.status
) {
957 return (*surface
)->base
.status
;
961 pixman_image_set_component_alpha ((*surface
)->pixman_image
, TRUE
);
963 _cairo_image_surface_assume_ownership_of_data ((*surface
));
965 return CAIRO_STATUS_SUCCESS
;
968 /* Converts an outline FT_GlyphSlot into an image
970 * This could go through _render_glyph_bitmap as well, letting
971 * FreeType convert the outline to a bitmap, but doing it ourselves
972 * has two minor advantages: first, we save a copy of the bitmap
973 * buffer: we can directly use the buffer that FreeType renders
976 * Second, it may help when we add support for subpixel
977 * rendering: the Xft code does it this way. (Keith thinks that
978 * it may also be possible to get the subpixel rendering with
979 * FT_Render_Glyph: something worth looking into in more detail
980 * when we add subpixel support. If so, we may want to eliminate
981 * this version of the code path entirely.
983 static cairo_status_t
984 _render_glyph_outline (FT_Face face
,
985 cairo_font_options_t
*font_options
,
986 cairo_image_surface_t
**surface
)
988 FT_GlyphSlot glyphslot
= face
->glyph
;
989 FT_Outline
*outline
= &glyphslot
->outline
;
995 unsigned int width
, height
, stride
;
996 cairo_bool_t subpixel
= FALSE
;
997 cairo_status_t status
;
999 FT_Outline_Get_CBox (outline
, &cbox
);
1003 cbox
.xMax
= (cbox
.xMax
+ 63) & -64;
1004 cbox
.yMax
= (cbox
.yMax
+ 63) & -64;
1006 width
= (unsigned int) ((cbox
.xMax
- cbox
.xMin
) >> 6);
1007 height
= (unsigned int) ((cbox
.yMax
- cbox
.yMin
) >> 6);
1008 stride
= (width
* hmul
+ 3) & ~3;
1010 if (width
* height
== 0) {
1011 cairo_format_t format
;
1012 /* Looks like fb handles zero-sized images just fine */
1013 switch (font_options
->antialias
) {
1014 case CAIRO_ANTIALIAS_NONE
:
1015 format
= CAIRO_FORMAT_A1
;
1017 case CAIRO_ANTIALIAS_SUBPIXEL
:
1018 format
= CAIRO_FORMAT_ARGB32
;
1020 case CAIRO_ANTIALIAS_DEFAULT
:
1021 case CAIRO_ANTIALIAS_GRAY
:
1023 format
= CAIRO_FORMAT_A8
;
1027 (*surface
) = (cairo_image_surface_t
*)
1028 cairo_image_surface_create_for_data (NULL
, format
, 0, 0, 0);
1029 if ((*surface
)->base
.status
)
1030 return (*surface
)->base
.status
;
1033 matrix
.xx
= matrix
.yy
= 0x10000L
;
1034 matrix
.xy
= matrix
.yx
= 0;
1036 switch (font_options
->antialias
) {
1037 case CAIRO_ANTIALIAS_NONE
:
1038 bitmap
.pixel_mode
= FT_PIXEL_MODE_MONO
;
1039 bitmap
.num_grays
= 1;
1040 stride
= ((width
+ 31) & -32) >> 3;
1042 case CAIRO_ANTIALIAS_DEFAULT
:
1043 case CAIRO_ANTIALIAS_GRAY
:
1044 bitmap
.pixel_mode
= FT_PIXEL_MODE_GRAY
;
1045 bitmap
.num_grays
= 256;
1046 stride
= (width
+ 3) & -4;
1048 case CAIRO_ANTIALIAS_SUBPIXEL
:
1049 switch (font_options
->subpixel_order
) {
1050 case CAIRO_SUBPIXEL_ORDER_RGB
:
1051 case CAIRO_SUBPIXEL_ORDER_BGR
:
1052 case CAIRO_SUBPIXEL_ORDER_DEFAULT
:
1058 case CAIRO_SUBPIXEL_ORDER_VRGB
:
1059 case CAIRO_SUBPIXEL_ORDER_VBGR
:
1065 FT_Outline_Transform (outline
, &matrix
);
1067 bitmap
.pixel_mode
= FT_PIXEL_MODE_GRAY
;
1068 bitmap
.num_grays
= 256;
1069 stride
= (width
* hmul
+ 3) & -4;
1072 bitmap
.pitch
= stride
;
1073 bitmap
.width
= width
* hmul
;
1074 bitmap
.rows
= height
* vmul
;
1075 bitmap
.buffer
= calloc (stride
, bitmap
.rows
);
1076 if (bitmap
.buffer
== NULL
)
1077 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1079 FT_Outline_Translate (outline
, -cbox
.xMin
*hmul
, -cbox
.yMin
*vmul
);
1081 if (FT_Outline_Get_Bitmap (glyphslot
->library
, outline
, &bitmap
) != 0) {
1082 free (bitmap
.buffer
);
1083 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1086 status
= _get_bitmap_surface (&bitmap
, TRUE
, font_options
, surface
);
1092 * Note: the font's coordinate system is upside down from ours, so the
1093 * Y coordinate of the control box needs to be negated. Moreover, device
1094 * offsets are position of glyph origin relative to top left while xMin
1095 * and yMax are offsets of top left relative to origin. Another negation.
1097 cairo_surface_set_device_offset (&(*surface
)->base
,
1098 floor (-(double) cbox
.xMin
/ 64.0),
1099 floor (+(double) cbox
.yMax
/ 64.0));
1101 return CAIRO_STATUS_SUCCESS
;
1104 /* Converts a bitmap (or other) FT_GlyphSlot into an image */
1105 static cairo_status_t
1106 _render_glyph_bitmap (FT_Face face
,
1107 cairo_font_options_t
*font_options
,
1108 cairo_image_surface_t
**surface
)
1110 FT_GlyphSlot glyphslot
= face
->glyph
;
1111 cairo_status_t status
= CAIRO_STATUS_SUCCESS
;
1114 /* According to the FreeType docs, glyphslot->format could be
1115 * something other than FT_GLYPH_FORMAT_OUTLINE or
1116 * FT_GLYPH_FORMAT_BITMAP. Calling FT_Render_Glyph gives FreeType
1117 * the opportunity to convert such to
1118 * bitmap. FT_GLYPH_FORMAT_COMPOSITE will not be encountered since
1119 * we avoid the FT_LOAD_NO_RECURSE flag.
1121 error
= FT_Render_Glyph (glyphslot
, FT_RENDER_MODE_NORMAL
);
1122 /* XXX ignoring all other errors for now. They are not fatal, typically
1123 * just a glyph-not-found. */
1124 if (error
== FT_Err_Out_Of_Memory
)
1125 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1127 status
= _get_bitmap_surface (&glyphslot
->bitmap
, FALSE
, font_options
, surface
);
1132 * Note: the font's coordinate system is upside down from ours, so the
1133 * Y coordinate of the control box needs to be negated. Moreover, device
1134 * offsets are position of glyph origin relative to top left while
1135 * bitmap_left and bitmap_top are offsets of top left relative to origin.
1138 cairo_surface_set_device_offset (&(*surface
)->base
,
1139 -glyphslot
->bitmap_left
,
1140 +glyphslot
->bitmap_top
);
1145 static cairo_status_t
1146 _transform_glyph_bitmap (cairo_matrix_t
* shape
,
1147 cairo_image_surface_t
** surface
)
1149 cairo_matrix_t original_to_transformed
;
1150 cairo_matrix_t transformed_to_original
;
1151 cairo_image_surface_t
*old_image
;
1152 cairo_surface_t
*image
;
1154 double origin_x
, origin_y
;
1155 int orig_width
, orig_height
;
1157 int x_min
, y_min
, x_max
, y_max
;
1159 cairo_status_t status
;
1160 cairo_surface_pattern_t pattern
;
1162 /* We want to compute a transform that takes the origin
1163 * (device_x_offset, device_y_offset) to 0,0, then applies
1164 * the "shape" portion of the font transform
1166 original_to_transformed
= *shape
;
1168 cairo_surface_get_device_offset (&(*surface
)->base
, &origin_x
, &origin_y
);
1169 orig_width
= cairo_image_surface_get_width (&(*surface
)->base
);
1170 orig_height
= cairo_image_surface_get_height (&(*surface
)->base
);
1172 cairo_matrix_translate (&original_to_transformed
,
1173 -origin_x
, -origin_y
);
1175 /* Find the bounding box of the original bitmap under that
1179 x
[1] = orig_width
; y
[1] = 0;
1180 x
[2] = orig_width
; y
[2] = orig_height
;
1181 x
[3] = 0; y
[3] = orig_height
;
1183 for (i
= 0; i
< 4; i
++)
1184 cairo_matrix_transform_point (&original_to_transformed
,
1187 x_min
= floor (x
[0]); y_min
= floor (y
[0]);
1188 x_max
= ceil (x
[0]); y_max
= ceil (y
[0]);
1190 for (i
= 1; i
< 4; i
++) {
1192 x_min
= floor (x
[i
]);
1193 else if (x
[i
] > x_max
)
1194 x_max
= ceil (x
[i
]);
1196 y_min
= floor (y
[i
]);
1197 else if (y
[i
] > y_max
)
1198 y_max
= ceil (y
[i
]);
1201 /* Adjust the transform so that the bounding box starts at 0,0 ...
1202 * this gives our final transform from original bitmap to transformed
1205 original_to_transformed
.x0
-= x_min
;
1206 original_to_transformed
.y0
-= y_min
;
1208 /* Create the transformed bitmap
1210 width
= x_max
- x_min
;
1211 height
= y_max
- y_min
;
1213 transformed_to_original
= original_to_transformed
;
1214 status
= cairo_matrix_invert (&transformed_to_original
);
1218 /* We need to pad out the width to 32-bit intervals for cairo-xlib-surface.c */
1219 width
= (width
+ 3) & ~3;
1220 image
= cairo_image_surface_create (CAIRO_FORMAT_A8
, width
, height
);
1222 return image
->status
;
1224 /* Initialize it to empty
1226 status
= _cairo_surface_fill_rectangle (image
, CAIRO_OPERATOR_CLEAR
,
1227 CAIRO_COLOR_TRANSPARENT
,
1231 cairo_surface_destroy (image
);
1235 /* Draw the original bitmap transformed into the new bitmap
1237 _cairo_pattern_init_for_surface (&pattern
, &(*surface
)->base
);
1238 cairo_pattern_set_matrix (&pattern
.base
, &transformed_to_original
);
1240 status
= _cairo_surface_composite (CAIRO_OPERATOR_OVER
,
1241 &pattern
.base
, NULL
, image
,
1246 _cairo_pattern_fini (&pattern
.base
);
1249 cairo_surface_destroy (image
);
1253 /* Now update the cache entry for the new bitmap, recomputing
1254 * the origin based on the final transform.
1256 cairo_matrix_transform_point (&original_to_transformed
,
1257 &origin_x
, &origin_y
);
1259 old_image
= (*surface
);
1260 (*surface
) = (cairo_image_surface_t
*)image
;
1261 cairo_surface_destroy (&old_image
->base
);
1263 cairo_surface_set_device_offset (&(*surface
)->base
,
1264 _cairo_lround (origin_x
),
1265 _cairo_lround (origin_y
));
1269 static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend
= {
1270 _cairo_ft_unscaled_font_destroy
,
1272 _cairo_ft_unscaled_font_create_glyph
1276 /* #cairo_ft_scaled_font_t */
1278 typedef struct _cairo_ft_scaled_font
{
1279 cairo_scaled_font_t base
;
1280 cairo_ft_unscaled_font_t
*unscaled
;
1281 cairo_ft_options_t ft_options
;
1282 } cairo_ft_scaled_font_t
;
1284 const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend
;
1286 /* The load flags passed to FT_Load_Glyph control aspects like hinting and
1287 * antialiasing. Here we compute them from the fields of a FcPattern.
1290 _get_pattern_ft_options (FcPattern
*pattern
, cairo_ft_options_t
*ret
)
1292 FcBool antialias
, vertical_layout
, hinting
, autohint
, bitmap
, embolden
;
1293 cairo_ft_options_t ft_options
;
1295 #ifdef FC_HINT_STYLE
1299 _cairo_font_options_init_default (&ft_options
.base
);
1300 ft_options
.load_flags
= FT_LOAD_DEFAULT
;
1301 ft_options
.extra_flags
= 0;
1303 #ifndef FC_EMBEDDED_BITMAP
1304 #define FC_EMBEDDED_BITMAP "embeddedbitmap"
1307 /* Check whether to force use of embedded bitmaps */
1308 if (FcPatternGetBool (pattern
,
1309 FC_EMBEDDED_BITMAP
, 0, &bitmap
) != FcResultMatch
)
1312 /* disable antialiasing if requested */
1313 if (FcPatternGetBool (pattern
,
1314 FC_ANTIALIAS
, 0, &antialias
) != FcResultMatch
)
1318 cairo_subpixel_order_t subpixel_order
;
1320 /* disable hinting if requested */
1321 if (FcPatternGetBool (pattern
,
1322 FC_HINTING
, 0, &hinting
) != FcResultMatch
)
1325 if (FcPatternGetInteger (pattern
,
1326 FC_RGBA
, 0, &rgba
) != FcResultMatch
)
1327 rgba
= FC_RGBA_UNKNOWN
;
1331 subpixel_order
= CAIRO_SUBPIXEL_ORDER_RGB
;
1334 subpixel_order
= CAIRO_SUBPIXEL_ORDER_BGR
;
1337 subpixel_order
= CAIRO_SUBPIXEL_ORDER_VRGB
;
1340 subpixel_order
= CAIRO_SUBPIXEL_ORDER_VBGR
;
1342 case FC_RGBA_UNKNOWN
:
1345 subpixel_order
= CAIRO_SUBPIXEL_ORDER_DEFAULT
;
1349 if (subpixel_order
!= CAIRO_SUBPIXEL_ORDER_DEFAULT
) {
1350 ft_options
.base
.subpixel_order
= subpixel_order
;
1351 ft_options
.base
.antialias
= CAIRO_ANTIALIAS_SUBPIXEL
;
1354 #ifdef FC_HINT_STYLE
1355 if (FcPatternGetInteger (pattern
,
1356 FC_HINT_STYLE
, 0, &hintstyle
) != FcResultMatch
)
1357 hintstyle
= FC_HINT_FULL
;
1360 hintstyle
= FC_HINT_NONE
;
1362 switch (hintstyle
) {
1364 ft_options
.base
.hint_style
= CAIRO_HINT_STYLE_NONE
;
1366 case FC_HINT_SLIGHT
:
1367 ft_options
.base
.hint_style
= CAIRO_HINT_STYLE_SLIGHT
;
1369 case FC_HINT_MEDIUM
:
1371 ft_options
.base
.hint_style
= CAIRO_HINT_STYLE_MEDIUM
;
1374 ft_options
.base
.hint_style
= CAIRO_HINT_STYLE_FULL
;
1377 #else /* !FC_HINT_STYLE */
1379 ft_options
.base
.hint_style
= CAIRO_HINT_STYLE_NONE
;
1381 #endif /* FC_HINT_STYLE */
1383 /* Force embedded bitmaps off if no hinting requested */
1384 if (ft_options
.base
.hint_style
== CAIRO_HINT_STYLE_NONE
)
1388 ft_options
.load_flags
|= FT_LOAD_NO_BITMAP
;
1391 ft_options
.base
.antialias
= CAIRO_ANTIALIAS_NONE
;
1394 /* force autohinting if requested */
1395 if (FcPatternGetBool (pattern
,
1396 FC_AUTOHINT
, 0, &autohint
) != FcResultMatch
)
1400 ft_options
.load_flags
|= FT_LOAD_FORCE_AUTOHINT
;
1402 if (FcPatternGetBool (pattern
,
1403 FC_VERTICAL_LAYOUT
, 0, &vertical_layout
) != FcResultMatch
)
1404 vertical_layout
= FcFalse
;
1406 if (vertical_layout
)
1407 ft_options
.load_flags
|= FT_LOAD_VERTICAL_LAYOUT
;
1410 #define FC_EMBOLDEN "embolden"
1412 if (FcPatternGetBool (pattern
,
1413 FC_EMBOLDEN
, 0, &embolden
) != FcResultMatch
)
1417 ft_options
.extra_flags
|= CAIRO_FT_OPTIONS_EMBOLDEN
;
1423 _cairo_ft_options_merge (cairo_ft_options_t
*options
,
1424 cairo_ft_options_t
*other
)
1426 int load_flags
= other
->load_flags
;
1427 int load_target
= FT_LOAD_TARGET_NORMAL
;
1429 /* clear load target mode */
1430 load_flags
&= ~(FT_LOAD_TARGET_(FT_LOAD_TARGET_MODE(other
->load_flags
)));
1432 if (load_flags
& FT_LOAD_NO_HINTING
)
1433 other
->base
.hint_style
= CAIRO_HINT_STYLE_NONE
;
1435 if (other
->base
.antialias
== CAIRO_ANTIALIAS_NONE
||
1436 options
->base
.antialias
== CAIRO_ANTIALIAS_NONE
) {
1437 options
->base
.antialias
= CAIRO_ANTIALIAS_NONE
;
1438 options
->base
.subpixel_order
= CAIRO_SUBPIXEL_ORDER_DEFAULT
;
1441 if (other
->base
.antialias
== CAIRO_ANTIALIAS_SUBPIXEL
&&
1442 (options
->base
.antialias
== CAIRO_ANTIALIAS_DEFAULT
||
1443 options
->base
.antialias
== CAIRO_ANTIALIAS_GRAY
)) {
1444 options
->base
.antialias
= CAIRO_ANTIALIAS_SUBPIXEL
;
1445 options
->base
.subpixel_order
= other
->base
.subpixel_order
;
1448 if (options
->base
.hint_style
== CAIRO_HINT_STYLE_DEFAULT
)
1449 options
->base
.hint_style
= other
->base
.hint_style
;
1451 if (other
->base
.hint_style
== CAIRO_HINT_STYLE_NONE
)
1452 options
->base
.hint_style
= CAIRO_HINT_STYLE_NONE
;
1454 if (options
->base
.antialias
== CAIRO_ANTIALIAS_NONE
) {
1455 if (options
->base
.hint_style
== CAIRO_HINT_STYLE_NONE
)
1456 load_flags
|= FT_LOAD_NO_HINTING
;
1458 load_target
= FT_LOAD_TARGET_MONO
;
1459 load_flags
|= FT_LOAD_MONOCHROME
;
1461 switch (options
->base
.hint_style
) {
1462 case CAIRO_HINT_STYLE_NONE
:
1463 load_flags
|= FT_LOAD_NO_HINTING
;
1465 case CAIRO_HINT_STYLE_SLIGHT
:
1466 load_target
= FT_LOAD_TARGET_LIGHT
;
1468 case CAIRO_HINT_STYLE_MEDIUM
:
1470 case CAIRO_HINT_STYLE_FULL
:
1471 case CAIRO_HINT_STYLE_DEFAULT
:
1472 if (options
->base
.antialias
== CAIRO_ANTIALIAS_SUBPIXEL
) {
1473 switch (options
->base
.subpixel_order
) {
1474 case CAIRO_SUBPIXEL_ORDER_DEFAULT
:
1475 case CAIRO_SUBPIXEL_ORDER_RGB
:
1476 case CAIRO_SUBPIXEL_ORDER_BGR
:
1477 load_target
|= FT_LOAD_TARGET_LCD
;
1479 case CAIRO_SUBPIXEL_ORDER_VRGB
:
1480 case CAIRO_SUBPIXEL_ORDER_VBGR
:
1481 load_target
|= FT_LOAD_TARGET_LCD_V
;
1489 options
->load_flags
= load_flags
| load_target
;
1490 options
->extra_flags
= other
->extra_flags
;
1491 if (options
->base
.hint_metrics
!= CAIRO_HINT_METRICS_OFF
)
1492 options
->extra_flags
|= CAIRO_FT_OPTIONS_HINT_METRICS
;
1495 static cairo_status_t
1496 _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t
*unscaled
,
1497 cairo_font_face_t
*font_face
,
1498 const cairo_matrix_t
*font_matrix
,
1499 const cairo_matrix_t
*ctm
,
1500 const cairo_font_options_t
*options
,
1501 cairo_ft_options_t ft_options
,
1502 cairo_scaled_font_t
**font_out
)
1504 cairo_ft_scaled_font_t
*scaled_font
;
1506 FT_Size_Metrics
*metrics
;
1507 cairo_font_extents_t fs_metrics
;
1508 cairo_status_t status
;
1510 face
= _cairo_ft_unscaled_font_lock_face (unscaled
);
1512 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1514 scaled_font
= malloc (sizeof(cairo_ft_scaled_font_t
));
1515 if (scaled_font
== NULL
) {
1516 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1520 _cairo_unscaled_font_reference (&unscaled
->base
);
1521 scaled_font
->unscaled
= unscaled
;
1523 _cairo_font_options_init_copy (&scaled_font
->ft_options
.base
, options
);
1524 _cairo_ft_options_merge (&scaled_font
->ft_options
, &ft_options
);
1526 status
= _cairo_scaled_font_init (&scaled_font
->base
,
1528 font_matrix
, ctm
, options
,
1529 &_cairo_ft_scaled_font_backend
);
1531 _cairo_unscaled_font_destroy (&unscaled
->base
);
1536 status
= _cairo_ft_unscaled_font_set_scale (unscaled
,
1537 &scaled_font
->base
.scale
);
1539 _cairo_unscaled_font_destroy (&unscaled
->base
);
1545 metrics
= &face
->size
->metrics
;
1548 * Get to unscaled metrics so that the upper level can get back to
1551 * Also use this path for bitmap-only fonts. The other branch uses
1552 * face members that are only relevant for scalable fonts. This is
1553 * detected by simply checking for units_per_EM==0.
1555 if (scaled_font
->base
.options
.hint_metrics
!= CAIRO_HINT_METRICS_OFF
||
1556 face
->units_per_EM
== 0) {
1557 double x_factor
, y_factor
;
1559 if (unscaled
->x_scale
== 0)
1562 x_factor
= 1 / unscaled
->x_scale
;
1564 if (unscaled
->y_scale
== 0)
1567 y_factor
= 1 / unscaled
->y_scale
;
1569 fs_metrics
.ascent
= DOUBLE_FROM_26_6(metrics
->ascender
) * y_factor
;
1570 fs_metrics
.descent
= DOUBLE_FROM_26_6(- metrics
->descender
) * y_factor
;
1571 fs_metrics
.height
= DOUBLE_FROM_26_6(metrics
->height
) * y_factor
;
1572 if (!_cairo_ft_scaled_font_is_vertical (&scaled_font
->base
)) {
1573 fs_metrics
.max_x_advance
= DOUBLE_FROM_26_6(metrics
->max_advance
) * x_factor
;
1574 fs_metrics
.max_y_advance
= 0;
1576 fs_metrics
.max_x_advance
= 0;
1577 fs_metrics
.max_y_advance
= DOUBLE_FROM_26_6(metrics
->max_advance
) * y_factor
;
1580 double scale
= face
->units_per_EM
;
1582 fs_metrics
.ascent
= face
->ascender
/ scale
;
1583 fs_metrics
.descent
= - face
->descender
/ scale
;
1584 fs_metrics
.height
= face
->height
/ scale
;
1585 if (!_cairo_ft_scaled_font_is_vertical (&scaled_font
->base
)) {
1586 fs_metrics
.max_x_advance
= face
->max_advance_width
/ scale
;
1587 fs_metrics
.max_y_advance
= 0;
1589 fs_metrics
.max_x_advance
= 0;
1590 fs_metrics
.max_y_advance
= face
->max_advance_height
/ scale
;
1594 status
= _cairo_scaled_font_set_metrics (&scaled_font
->base
, &fs_metrics
);
1596 *font_out
= &scaled_font
->base
;
1599 _cairo_ft_unscaled_font_unlock_face (unscaled
);
1605 _cairo_scaled_font_is_ft (cairo_scaled_font_t
*scaled_font
)
1607 return scaled_font
->backend
== &_cairo_ft_scaled_font_backend
;
1610 static cairo_status_t
1611 _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t
*toy_face
,
1612 const cairo_matrix_t
*font_matrix
,
1613 const cairo_matrix_t
*ctm
,
1614 const cairo_font_options_t
*font_options
,
1615 cairo_scaled_font_t
**font
)
1617 FcPattern
*pattern
, *resolved
;
1618 cairo_ft_unscaled_font_t
*unscaled
;
1622 cairo_matrix_t scale
;
1623 cairo_status_t status
;
1624 cairo_ft_font_transform_t sf
;
1625 cairo_ft_options_t ft_options
;
1627 cairo_matrix_multiply (&scale
, font_matrix
, ctm
);
1628 status
= _compute_transform (&sf
, &scale
);
1632 pattern
= FcPatternCreate ();
1634 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1636 if (!FcPatternAddString (pattern
,
1637 FC_FAMILY
, (unsigned char *) toy_face
->family
))
1639 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1643 switch (toy_face
->slant
)
1645 case CAIRO_FONT_SLANT_ITALIC
:
1646 fcslant
= FC_SLANT_ITALIC
;
1648 case CAIRO_FONT_SLANT_OBLIQUE
:
1649 fcslant
= FC_SLANT_OBLIQUE
;
1651 case CAIRO_FONT_SLANT_NORMAL
:
1653 fcslant
= FC_SLANT_ROMAN
;
1657 if (!FcPatternAddInteger (pattern
, FC_SLANT
, fcslant
)) {
1658 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1662 switch (toy_face
->weight
)
1664 case CAIRO_FONT_WEIGHT_BOLD
:
1665 fcweight
= FC_WEIGHT_BOLD
;
1667 case CAIRO_FONT_WEIGHT_NORMAL
:
1669 fcweight
= FC_WEIGHT_MEDIUM
;
1673 if (!FcPatternAddInteger (pattern
, FC_WEIGHT
, fcweight
)) {
1674 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1678 if (! FcPatternAddDouble (pattern
, FC_PIXEL_SIZE
, sf
.y_scale
)) {
1679 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1683 if (! FcConfigSubstitute (NULL
, pattern
, FcMatchPattern
)) {
1684 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1688 status
= _cairo_ft_font_options_substitute (font_options
, pattern
);
1692 FcDefaultSubstitute (pattern
);
1694 resolved
= FcFontMatch (NULL
, pattern
, &result
);
1696 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1700 unscaled
= _cairo_ft_unscaled_font_create_for_pattern (resolved
);
1702 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1706 _get_pattern_ft_options (resolved
, &ft_options
);
1708 status
= _cairo_ft_scaled_font_create (unscaled
,
1711 font_options
, ft_options
,
1714 _cairo_unscaled_font_destroy (&unscaled
->base
);
1717 FcPatternDestroy (resolved
);
1720 FcPatternDestroy (pattern
);
1726 _cairo_ft_scaled_font_fini (void *abstract_font
)
1728 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
1730 if (scaled_font
== NULL
)
1733 _cairo_unscaled_font_destroy (&scaled_font
->unscaled
->base
);
1737 _move_to (FT_Vector
*to
, void *closure
)
1739 cairo_path_fixed_t
*path
= closure
;
1742 x
= _cairo_fixed_from_26_6 (to
->x
);
1743 y
= _cairo_fixed_from_26_6 (to
->y
);
1745 if (_cairo_path_fixed_close_path (path
) != CAIRO_STATUS_SUCCESS
)
1747 if (_cairo_path_fixed_move_to (path
, x
, y
) != CAIRO_STATUS_SUCCESS
)
1754 _line_to (FT_Vector
*to
, void *closure
)
1756 cairo_path_fixed_t
*path
= closure
;
1759 x
= _cairo_fixed_from_26_6 (to
->x
);
1760 y
= _cairo_fixed_from_26_6 (to
->y
);
1762 if (_cairo_path_fixed_line_to (path
, x
, y
) != CAIRO_STATUS_SUCCESS
)
1769 _conic_to (FT_Vector
*control
, FT_Vector
*to
, void *closure
)
1771 cairo_path_fixed_t
*path
= closure
;
1773 cairo_fixed_t x0
, y0
;
1774 cairo_fixed_t x1
, y1
;
1775 cairo_fixed_t x2
, y2
;
1776 cairo_fixed_t x3
, y3
;
1777 cairo_point_t conic
;
1779 if (! _cairo_path_fixed_get_current_point (path
, &x0
, &y0
))
1782 conic
.x
= _cairo_fixed_from_26_6 (control
->x
);
1783 conic
.y
= _cairo_fixed_from_26_6 (control
->y
);
1785 x3
= _cairo_fixed_from_26_6 (to
->x
);
1786 y3
= _cairo_fixed_from_26_6 (to
->y
);
1788 x1
= x0
+ 2.0/3.0 * (conic
.x
- x0
);
1789 y1
= y0
+ 2.0/3.0 * (conic
.y
- y0
);
1791 x2
= x3
+ 2.0/3.0 * (conic
.x
- x3
);
1792 y2
= y3
+ 2.0/3.0 * (conic
.y
- y3
);
1794 if (_cairo_path_fixed_curve_to (path
,
1797 x3
, y3
) != CAIRO_STATUS_SUCCESS
)
1804 _cubic_to (FT_Vector
*control1
, FT_Vector
*control2
,
1805 FT_Vector
*to
, void *closure
)
1807 cairo_path_fixed_t
*path
= closure
;
1808 cairo_fixed_t x0
, y0
;
1809 cairo_fixed_t x1
, y1
;
1810 cairo_fixed_t x2
, y2
;
1812 x0
= _cairo_fixed_from_26_6 (control1
->x
);
1813 y0
= _cairo_fixed_from_26_6 (control1
->y
);
1815 x1
= _cairo_fixed_from_26_6 (control2
->x
);
1816 y1
= _cairo_fixed_from_26_6 (control2
->y
);
1818 x2
= _cairo_fixed_from_26_6 (to
->x
);
1819 y2
= _cairo_fixed_from_26_6 (to
->y
);
1821 if (_cairo_path_fixed_curve_to (path
,
1824 x2
, y2
) != CAIRO_STATUS_SUCCESS
)
1830 static cairo_status_t
1831 _decompose_glyph_outline (FT_Face face
,
1832 cairo_font_options_t
*options
,
1833 cairo_path_fixed_t
**pathp
)
1835 static const FT_Outline_Funcs outline_funcs
= {
1836 (FT_Outline_MoveToFunc
)_move_to
,
1837 (FT_Outline_LineToFunc
)_line_to
,
1838 (FT_Outline_ConicToFunc
)_conic_to
,
1839 (FT_Outline_CubicToFunc
)_cubic_to
,
1843 static const FT_Matrix invert_y
= {
1844 DOUBLE_TO_16_16 (1.0), 0,
1845 0, DOUBLE_TO_16_16 (-1.0),
1849 cairo_path_fixed_t
*path
;
1850 cairo_status_t status
;
1852 path
= _cairo_path_fixed_create ();
1854 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1856 glyph
= face
->glyph
;
1858 /* Font glyphs have an inverted Y axis compared to cairo. */
1859 FT_Outline_Transform (&glyph
->outline
, &invert_y
);
1860 if (FT_Outline_Decompose (&glyph
->outline
, &outline_funcs
, path
)) {
1861 _cairo_path_fixed_destroy (path
);
1862 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1865 status
= _cairo_path_fixed_close_path (path
);
1867 _cairo_path_fixed_destroy (path
);
1873 return CAIRO_STATUS_SUCCESS
;
1877 * Translate glyph to match its metrics.
1880 _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (void *abstract_font
,
1883 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
1886 vector
.x
= glyph
->metrics
.vertBearingX
- glyph
->metrics
.horiBearingX
;
1887 vector
.y
= -glyph
->metrics
.vertBearingY
- glyph
->metrics
.horiBearingY
;
1889 if (glyph
->format
== FT_GLYPH_FORMAT_OUTLINE
) {
1890 FT_Vector_Transform (&vector
, &scaled_font
->unscaled
->Current_Shape
);
1891 FT_Outline_Translate(&glyph
->outline
, vector
.x
, vector
.y
);
1892 } else if (glyph
->format
== FT_GLYPH_FORMAT_BITMAP
) {
1893 glyph
->bitmap_left
+= vector
.x
/ 64;
1894 glyph
->bitmap_top
+= vector
.y
/ 64;
1898 static cairo_int_status_t
1899 _cairo_ft_scaled_glyph_init (void *abstract_font
,
1900 cairo_scaled_glyph_t
*scaled_glyph
,
1901 cairo_scaled_glyph_info_t info
)
1903 cairo_text_extents_t fs_metrics
;
1904 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
1905 cairo_ft_unscaled_font_t
*unscaled
= scaled_font
->unscaled
;
1909 int load_flags
= scaled_font
->ft_options
.load_flags
;
1910 FT_Glyph_Metrics
*metrics
;
1911 double x_factor
, y_factor
;
1912 cairo_bool_t vertical_layout
= FALSE
;
1913 cairo_status_t status
;
1915 face
= _cairo_ft_unscaled_font_lock_face (unscaled
);
1917 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1919 status
= _cairo_ft_unscaled_font_set_scale (scaled_font
->unscaled
,
1920 &scaled_font
->base
.scale
);
1924 /* Ignore global advance unconditionally */
1925 load_flags
|= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
;
1927 if ((info
& CAIRO_SCALED_GLYPH_INFO_PATH
) != 0 &&
1928 (info
& CAIRO_SCALED_GLYPH_INFO_SURFACE
) == 0)
1929 load_flags
|= FT_LOAD_NO_BITMAP
;
1932 * Don't pass FT_LOAD_VERTICAL_LAYOUT to FT_Load_Glyph here as
1933 * suggested by freetype people.
1935 if (load_flags
& FT_LOAD_VERTICAL_LAYOUT
) {
1936 load_flags
&= ~FT_LOAD_VERTICAL_LAYOUT
;
1937 vertical_layout
= TRUE
;
1940 error
= FT_Load_Glyph (scaled_font
->unscaled
->face
,
1941 _cairo_scaled_glyph_index(scaled_glyph
),
1943 /* XXX ignoring all other errors for now. They are not fatal, typically
1944 * just a glyph-not-found. */
1945 if (error
== FT_Err_Out_Of_Memory
) {
1946 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1950 glyph
= face
->glyph
;
1952 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
1954 * embolden glyphs if requested
1956 if (scaled_font
->ft_options
.extra_flags
& CAIRO_FT_OPTIONS_EMBOLDEN
)
1957 FT_GlyphSlot_Embolden (glyph
);
1960 if (vertical_layout
)
1961 _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font
, glyph
);
1963 if (info
& CAIRO_SCALED_GLYPH_INFO_METRICS
) {
1965 cairo_bool_t hint_metrics
= scaled_font
->base
.options
.hint_metrics
!= CAIRO_HINT_METRICS_OFF
;
1967 * Compute font-space metrics
1969 metrics
= &glyph
->metrics
;
1971 if (unscaled
->x_scale
== 0)
1974 x_factor
= 1 / unscaled
->x_scale
;
1976 if (unscaled
->y_scale
== 0)
1979 y_factor
= 1 / unscaled
->y_scale
;
1982 * Note: Y coordinates of the horizontal bearing need to be negated.
1984 * Scale metrics back to glyph space from the scaled glyph space returned
1987 * If we want hinted metrics but aren't asking for hinted glyphs from
1988 * FreeType, then we need to do the metric hinting ourselves.
1991 if (hint_metrics
&& (load_flags
& FT_LOAD_NO_HINTING
))
1997 if (!vertical_layout
) {
1998 x1
= (metrics
->horiBearingX
) & -64;
1999 x2
= (metrics
->horiBearingX
+ metrics
->width
+ 63) & -64;
2000 y1
= (-metrics
->horiBearingY
) & -64;
2001 y2
= (-metrics
->horiBearingY
+ metrics
->height
+ 63) & -64;
2003 advance
= ((metrics
->horiAdvance
+ 32) & -64);
2005 fs_metrics
.x_bearing
= DOUBLE_FROM_26_6 (x1
) * x_factor
;
2006 fs_metrics
.y_bearing
= DOUBLE_FROM_26_6 (y1
) * y_factor
;
2008 fs_metrics
.width
= DOUBLE_FROM_26_6 (x2
- x1
) * x_factor
;
2009 fs_metrics
.height
= DOUBLE_FROM_26_6 (y2
- y1
) * y_factor
;
2011 fs_metrics
.x_advance
= DOUBLE_FROM_26_6 (advance
) * x_factor
;
2012 fs_metrics
.y_advance
= 0;
2014 x1
= (metrics
->vertBearingX
) & -64;
2015 x2
= (metrics
->vertBearingX
+ metrics
->width
+ 63) & -64;
2016 y1
= (metrics
->vertBearingY
) & -64;
2017 y2
= (metrics
->vertBearingY
+ metrics
->height
+ 63) & -64;
2019 advance
= ((metrics
->vertAdvance
+ 32) & -64);
2021 fs_metrics
.x_bearing
= DOUBLE_FROM_26_6 (x1
) * x_factor
;
2022 fs_metrics
.y_bearing
= DOUBLE_FROM_26_6 (y1
) * y_factor
;
2024 fs_metrics
.width
= DOUBLE_FROM_26_6 (x2
- x1
) * x_factor
;
2025 fs_metrics
.height
= DOUBLE_FROM_26_6 (y2
- y1
) * y_factor
;
2027 fs_metrics
.x_advance
= 0;
2028 fs_metrics
.y_advance
= DOUBLE_FROM_26_6 (advance
) * y_factor
;
2031 fs_metrics
.width
= DOUBLE_FROM_26_6 (metrics
->width
) * x_factor
;
2032 fs_metrics
.height
= DOUBLE_FROM_26_6 (metrics
->height
) * y_factor
;
2034 if (!vertical_layout
) {
2035 fs_metrics
.x_bearing
= DOUBLE_FROM_26_6 (metrics
->horiBearingX
) * x_factor
;
2036 fs_metrics
.y_bearing
= DOUBLE_FROM_26_6 (-metrics
->horiBearingY
) * y_factor
;
2038 if (hint_metrics
|| glyph
->format
!= FT_GLYPH_FORMAT_OUTLINE
)
2039 fs_metrics
.x_advance
= DOUBLE_FROM_26_6 (metrics
->horiAdvance
) * x_factor
;
2041 fs_metrics
.x_advance
= DOUBLE_FROM_16_16 (glyph
->linearHoriAdvance
) * x_factor
;
2042 fs_metrics
.y_advance
= 0 * y_factor
;
2044 fs_metrics
.x_bearing
= DOUBLE_FROM_26_6 (metrics
->vertBearingX
) * x_factor
;
2045 fs_metrics
.y_bearing
= DOUBLE_FROM_26_6 (metrics
->vertBearingY
) * y_factor
;
2047 fs_metrics
.x_advance
= 0 * x_factor
;
2048 if (hint_metrics
|| glyph
->format
!= FT_GLYPH_FORMAT_OUTLINE
)
2049 fs_metrics
.y_advance
= DOUBLE_FROM_26_6 (metrics
->vertAdvance
) * y_factor
;
2051 fs_metrics
.y_advance
= DOUBLE_FROM_26_6 (glyph
->linearVertAdvance
) * y_factor
;
2055 _cairo_scaled_glyph_set_metrics (scaled_glyph
,
2060 if ((info
& CAIRO_SCALED_GLYPH_INFO_SURFACE
) != 0) {
2061 cairo_image_surface_t
*surface
;
2063 if (glyph
->format
== FT_GLYPH_FORMAT_OUTLINE
) {
2064 status
= _render_glyph_outline (face
, &scaled_font
->ft_options
.base
,
2067 status
= _render_glyph_bitmap (face
, &scaled_font
->ft_options
.base
,
2069 if (status
== CAIRO_STATUS_SUCCESS
&& unscaled
->have_shape
) {
2070 status
= _transform_glyph_bitmap (&unscaled
->current_shape
,
2073 cairo_surface_destroy (&surface
->base
);
2079 _cairo_scaled_glyph_set_surface (scaled_glyph
,
2084 if (info
& CAIRO_SCALED_GLYPH_INFO_PATH
) {
2085 cairo_path_fixed_t
*path
= NULL
; /* hide compiler warning */
2088 * A kludge -- the above code will trash the outline,
2089 * so reload it. This will probably never occur though
2091 if ((info
& CAIRO_SCALED_GLYPH_INFO_SURFACE
) != 0) {
2092 error
= FT_Load_Glyph (face
,
2093 _cairo_scaled_glyph_index(scaled_glyph
),
2094 load_flags
| FT_LOAD_NO_BITMAP
);
2095 /* XXX ignoring all other errors for now. They are not fatal, typically
2096 * just a glyph-not-found. */
2097 if (error
== FT_Err_Out_Of_Memory
) {
2098 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2101 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
2103 * embolden glyphs if requested
2105 if (scaled_font
->ft_options
.extra_flags
& CAIRO_FT_OPTIONS_EMBOLDEN
)
2106 FT_GlyphSlot_Embolden (glyph
);
2108 if (vertical_layout
)
2109 _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font
, glyph
);
2112 if (glyph
->format
== FT_GLYPH_FORMAT_OUTLINE
)
2113 status
= _decompose_glyph_outline (face
, &scaled_font
->ft_options
.base
,
2116 status
= CAIRO_INT_STATUS_UNSUPPORTED
;
2121 _cairo_scaled_glyph_set_path (scaled_glyph
,
2126 _cairo_ft_unscaled_font_unlock_face (unscaled
);
2131 static unsigned long
2132 _cairo_ft_ucs4_to_index (void *abstract_font
,
2135 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
2136 cairo_ft_unscaled_font_t
*unscaled
= scaled_font
->unscaled
;
2140 face
= _cairo_ft_unscaled_font_lock_face (unscaled
);
2144 /* If making this compile without fontconfig, use:
2145 * index = FT_Get_Char_Index (face, ucs4); */
2146 index
= FcFreeTypeCharIndex (face
, ucs4
);
2148 _cairo_ft_unscaled_font_unlock_face (unscaled
);
2152 static cairo_int_status_t
2153 _cairo_ft_load_truetype_table (void *abstract_font
,
2156 unsigned char *buffer
,
2157 unsigned long *length
)
2159 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
2160 cairo_ft_unscaled_font_t
*unscaled
= scaled_font
->unscaled
;
2162 cairo_status_t status
= CAIRO_INT_STATUS_UNSUPPORTED
;
2164 if (_cairo_ft_scaled_font_is_vertical (&scaled_font
->base
))
2165 return CAIRO_INT_STATUS_UNSUPPORTED
;
2167 #if HAVE_FT_LOAD_SFNT_TABLE
2168 face
= _cairo_ft_unscaled_font_lock_face (unscaled
);
2170 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2172 if (FT_IS_SFNT (face
) &&
2173 FT_Load_Sfnt_Table (face
, tag
, offset
, buffer
, length
) == 0)
2174 status
= CAIRO_STATUS_SUCCESS
;
2176 _cairo_ft_unscaled_font_unlock_face (unscaled
);
2182 static cairo_int_status_t
2183 _cairo_ft_index_to_ucs4(void *abstract_font
,
2184 unsigned long index
,
2187 cairo_ft_scaled_font_t
*scaled_font
= abstract_font
;
2188 cairo_ft_unscaled_font_t
*unscaled
= scaled_font
->unscaled
;
2193 face
= _cairo_ft_unscaled_font_lock_face (unscaled
);
2195 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2197 *ucs4
= (uint32_t) -1;
2198 charcode
= FT_Get_First_Char(face
, &gindex
);
2199 while (gindex
!= 0) {
2200 charcode
= FT_Get_Next_Char (face
, charcode
, &gindex
);
2201 if (gindex
== index
) {
2207 _cairo_ft_unscaled_font_unlock_face (unscaled
);
2209 return CAIRO_STATUS_SUCCESS
;
2212 const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend
= {
2215 _cairo_ft_scaled_font_create_toy
,
2216 _cairo_ft_scaled_font_fini
,
2217 _cairo_ft_scaled_glyph_init
,
2218 NULL
, /* text_to_glyphs */
2219 _cairo_ft_ucs4_to_index
,
2220 NULL
, /* show_glyphs */
2221 _cairo_ft_load_truetype_table
,
2222 _cairo_ft_index_to_ucs4
2225 /* #cairo_ft_font_face_t */
2228 _cairo_ft_font_face_destroy (void *abstract_face
)
2230 cairo_ft_font_face_t
*font_face
= abstract_face
;
2232 cairo_ft_font_face_t
*tmp_face
= NULL
;
2233 cairo_ft_font_face_t
*last_face
= NULL
;
2235 if (font_face
== NULL
)
2238 /* When destroying the face created by cairo_ft_font_face_create_for_ft_face,
2239 * we have a special "zombie" state for the face when the unscaled font
2240 * is still alive but there are no public references to the font face.
2244 * font_face ------> unscaled
2249 * font_face <------- unscaled
2252 if (font_face
->unscaled
&&
2253 font_face
->unscaled
->from_face
&&
2254 CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face
->unscaled
->base
.ref_count
) > 1)
2256 cairo_font_face_reference (&font_face
->base
);
2258 _cairo_unscaled_font_destroy (&font_face
->unscaled
->base
);
2259 font_face
->unscaled
= NULL
;
2264 if (font_face
->unscaled
) {
2265 /* Remove face from linked list */
2266 for (tmp_face
= font_face
->unscaled
->faces
;
2268 tmp_face
= tmp_face
->next
)
2270 if (tmp_face
== font_face
) {
2272 last_face
->next
= tmp_face
->next
;
2274 font_face
->unscaled
->faces
= tmp_face
->next
;
2277 last_face
= tmp_face
;
2280 _cairo_unscaled_font_destroy (&font_face
->unscaled
->base
);
2281 font_face
->unscaled
= NULL
;
2285 static cairo_status_t
2286 _cairo_ft_font_face_scaled_font_create (void *abstract_face
,
2287 const cairo_matrix_t
*font_matrix
,
2288 const cairo_matrix_t
*ctm
,
2289 const cairo_font_options_t
*options
,
2290 cairo_scaled_font_t
**scaled_font
)
2292 cairo_ft_font_face_t
*font_face
= abstract_face
;
2293 cairo_ft_options_t ft_options
;
2295 /* The handling of font options is different depending on how the
2296 * font face was created. When the user creates a font face with
2297 * cairo_ft_font_face_create_for_ft_face(), then the load flags
2298 * passed in augment the load flags for the options. But for
2299 * cairo_ft_font_face_create_for_pattern(), the load flags are
2300 * derived from a pattern where the user has called
2301 * cairo_ft_font_options_substitute(), so *just* use those load
2302 * flags and ignore the options.
2304 * XXX two points about the above comment:
2305 * 1. I don't see how the comment is relevant here,
2306 * 2. What if the face is coming from FC_FT_FACE of a pattern?
2309 ft_options
= font_face
->ft_options
;
2311 return _cairo_ft_scaled_font_create (font_face
->unscaled
,
2314 options
, ft_options
,
2318 static const cairo_font_face_backend_t _cairo_ft_font_face_backend
= {
2320 _cairo_ft_font_face_destroy
,
2321 NULL
, /* direct implementation */
2322 _cairo_ft_font_face_scaled_font_create
2325 static cairo_font_face_t
*
2326 _cairo_ft_font_face_create (cairo_ft_unscaled_font_t
*unscaled
,
2327 cairo_ft_options_t
*ft_options
)
2329 cairo_ft_font_face_t
*font_face
, **prev_font_face
;
2331 /* Looked for an existing matching font face */
2332 for (font_face
= unscaled
->faces
, prev_font_face
= &unscaled
->faces
;
2334 prev_font_face
= &font_face
->next
, font_face
= font_face
->next
)
2336 if (font_face
->ft_options
.load_flags
== ft_options
->load_flags
&&
2337 font_face
->ft_options
.extra_flags
== ft_options
->extra_flags
&&
2338 cairo_font_options_equal (&font_face
->ft_options
.base
, &ft_options
->base
))
2340 if (font_face
->base
.status
== CAIRO_STATUS_SUCCESS
)
2341 return cairo_font_face_reference (&font_face
->base
);
2343 /* The font_face has been left in an error state, abandon it. */
2344 *prev_font_face
= font_face
->next
;
2349 /* No match found, create a new one */
2350 font_face
= malloc (sizeof (cairo_ft_font_face_t
));
2352 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
2353 return (cairo_font_face_t
*)&_cairo_font_face_nil
;
2356 font_face
->unscaled
= unscaled
;
2357 _cairo_unscaled_font_reference (&unscaled
->base
);
2359 font_face
->ft_options
= *ft_options
;
2361 font_face
->next
= unscaled
->faces
;
2362 unscaled
->faces
= font_face
;
2364 _cairo_font_face_init (&font_face
->base
, &_cairo_ft_font_face_backend
);
2366 return &font_face
->base
;
2369 /* implement the platform-specific interface */
2371 static cairo_status_t
2372 _cairo_ft_font_options_substitute (const cairo_font_options_t
*options
,
2377 if (options
->antialias
!= CAIRO_ANTIALIAS_DEFAULT
)
2379 if (FcPatternGet (pattern
, FC_ANTIALIAS
, 0, &v
) == FcResultNoMatch
)
2381 if (! FcPatternAddBool (pattern
,
2383 options
->antialias
!= CAIRO_ANTIALIAS_NONE
))
2384 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2386 if (options
->antialias
!= CAIRO_ANTIALIAS_SUBPIXEL
) {
2387 FcPatternDel (pattern
, FC_RGBA
);
2388 if (! FcPatternAddInteger (pattern
, FC_RGBA
, FC_RGBA_NONE
))
2389 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2394 if (options
->antialias
!= CAIRO_ANTIALIAS_DEFAULT
)
2396 if (FcPatternGet (pattern
, FC_RGBA
, 0, &v
) == FcResultNoMatch
)
2400 if (options
->antialias
== CAIRO_ANTIALIAS_SUBPIXEL
) {
2401 switch (options
->subpixel_order
) {
2402 case CAIRO_SUBPIXEL_ORDER_DEFAULT
:
2403 case CAIRO_SUBPIXEL_ORDER_RGB
:
2407 case CAIRO_SUBPIXEL_ORDER_BGR
:
2410 case CAIRO_SUBPIXEL_ORDER_VRGB
:
2411 rgba
= FC_RGBA_VRGB
;
2413 case CAIRO_SUBPIXEL_ORDER_VBGR
:
2414 rgba
= FC_RGBA_VBGR
;
2418 rgba
= FC_RGBA_NONE
;
2421 if (! FcPatternAddInteger (pattern
, FC_RGBA
, rgba
))
2422 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2426 if (options
->hint_style
!= CAIRO_HINT_STYLE_DEFAULT
)
2428 if (FcPatternGet (pattern
, FC_HINTING
, 0, &v
) == FcResultNoMatch
)
2430 if (! FcPatternAddBool (pattern
,
2432 options
->hint_style
!= CAIRO_HINT_STYLE_NONE
))
2433 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2436 #ifdef FC_HINT_STYLE
2437 if (FcPatternGet (pattern
, FC_HINT_STYLE
, 0, &v
) == FcResultNoMatch
)
2441 switch (options
->hint_style
) {
2442 case CAIRO_HINT_STYLE_NONE
:
2443 hint_style
= FC_HINT_NONE
;
2445 case CAIRO_HINT_STYLE_SLIGHT
:
2446 hint_style
= FC_HINT_SLIGHT
;
2448 case CAIRO_HINT_STYLE_MEDIUM
:
2449 hint_style
= FC_HINT_MEDIUM
;
2451 case CAIRO_HINT_STYLE_FULL
:
2452 case CAIRO_HINT_STYLE_DEFAULT
:
2454 hint_style
= FC_HINT_FULL
;
2458 if (! FcPatternAddInteger (pattern
, FC_HINT_STYLE
, hint_style
))
2459 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2464 return CAIRO_STATUS_SUCCESS
;
2468 * cairo_ft_font_options_substitute:
2469 * @options: a #cairo_font_options_t object
2470 * @pattern: an existing #FcPattern
2472 * Add options to a #FcPattern based on a #cairo_font_options_t font
2473 * options object. Options that are already in the pattern, are not overridden,
2474 * so you should call this function after calling FcConfigSubstitute() (the
2475 * user's settings should override options based on the surface type), but
2476 * before calling FcDefaultSubstitute().
2479 cairo_ft_font_options_substitute (const cairo_font_options_t
*options
,
2482 if (cairo_font_options_status ((cairo_font_options_t
*) options
))
2485 _cairo_ft_font_options_substitute (options
, pattern
);
2489 * cairo_ft_font_face_create_for_pattern:
2490 * @pattern: A fully resolved fontconfig
2491 * pattern. A pattern can be resolved, by, among other things, calling
2492 * FcConfigSubstitute(), FcDefaultSubstitute(), then
2493 * FcFontMatch(). Cairo will call FcPatternReference() on this
2494 * pattern, so you should not further modify the pattern, but you can
2495 * release your reference to the pattern with FcPatternDestroy() if
2496 * you no longer need to access it.
2498 * Creates a new font face for the FreeType font backend based on a
2499 * fontconfig pattern. This font can then be used with
2500 * cairo_set_font_face() or cairo_scaled_font_create(). The
2501 * #cairo_scaled_font_t returned from cairo_scaled_font_create() is
2502 * also for the FreeType backend and can be used with functions such
2503 * as cairo_ft_scaled_font_lock_face().
2505 * Font rendering options are represented both here and when you
2506 * call cairo_scaled_font_create(). Font options that have a representation
2507 * in a #FcPattern must be passed in here; to modify #FcPattern
2508 * appropriately to reflect the options in a #cairo_font_options_t, call
2509 * cairo_ft_font_options_substitute().
2511 * The pattern's FC_FT_FACE element is inspected first and if that is set,
2512 * that will be the FreeType font face associated with the returned cairo
2513 * font face. Otherwise the FC_FILE and FC_INDEX elements of @pattern are
2514 * used to load a font face from file.
2516 * If the FC_FT_FACE element of @pattern is set, the user is responsible
2517 * for making sure that the referenced FT_Face remains valid for the life
2518 * time of the returned #cairo_font_face_t. See
2519 * cairo_ft_font_face_create_for_ft_face() for an exmaple of how to couple
2520 * the life time of the FT_Face to that of the cairo font-face.
2522 * Return value: a newly created #cairo_font_face_t. Free with
2523 * cairo_font_face_destroy() when you are done using it.
2526 cairo_ft_font_face_create_for_pattern (FcPattern
*pattern
)
2528 cairo_ft_unscaled_font_t
*unscaled
;
2529 cairo_font_face_t
*font_face
;
2530 cairo_ft_options_t ft_options
;
2532 unscaled
= _cairo_ft_unscaled_font_create_for_pattern (pattern
);
2533 if (unscaled
== NULL
) {
2534 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
2535 return (cairo_font_face_t
*)&_cairo_font_face_nil
;
2538 _get_pattern_ft_options (pattern
, &ft_options
);
2539 font_face
= _cairo_ft_font_face_create (unscaled
, &ft_options
);
2540 _cairo_unscaled_font_destroy (&unscaled
->base
);
2546 * cairo_ft_font_face_create_for_ft_face:
2547 * @face: A FreeType face object, already opened. This must
2548 * be kept around until the face's ref_count drops to
2549 * zero and it is freed. Since the face may be referenced
2550 * internally to Cairo, the best way to determine when it
2551 * is safe to free the face is to pass a
2552 * #cairo_destroy_func_t to cairo_font_face_set_user_data()
2553 * @load_flags: flags to pass to FT_Load_Glyph when loading
2554 * glyphs from the font. These flags are OR'ed together with
2555 * the flags derived from the #cairo_font_options_t passed
2556 * to cairo_scaled_font_create(), so only a few values such
2557 * as %FT_LOAD_VERTICAL_LAYOUT, and %FT_LOAD_FORCE_AUTOHINT
2558 * are useful. You should not pass any of the flags affecting
2559 * the load target, such as %FT_LOAD_TARGET_LIGHT.
2561 * Creates a new font face for the FreeType font backend from a
2562 * pre-opened FreeType face. This font can then be used with
2563 * cairo_set_font_face() or cairo_scaled_font_create(). The
2564 * #cairo_scaled_font_t returned from cairo_scaled_font_create() is
2565 * also for the FreeType backend and can be used with functions such
2566 * as cairo_ft_scaled_font_lock_face(). Note that Cairo may keep a reference
2567 * to the FT_Face alive in a font-cache and the exact lifetime of the reference
2568 * depends highly upon the exact usage pattern and is subject to external
2569 * factors. You must not call FT_Done_Face() before the last reference to the
2570 * #cairo_font_face_t has been dropped.
2572 * As an example, below is how one might correctly couple the lifetime of
2573 * the FreeType face object to the #cairo_font_face_t.
2575 * <informalexample><programlisting>
2576 * static const cairo_user_data_key_t key;
2578 * font_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
2579 * status = cairo_font_face_set_user_data (font_face, &key,
2580 * ft_face, (cairo_destroy_func_t) FT_Done_Face);
2582 * cairo_font_face_destroy (font_face);
2583 * FT_Done_Face (ft_face);
2586 * </programlisting></informalexample>
2588 * Return value: a newly created #cairo_font_face_t. Free with
2589 * cairo_font_face_destroy() when you are done using it.
2592 cairo_ft_font_face_create_for_ft_face (FT_Face face
,
2595 cairo_ft_unscaled_font_t
*unscaled
;
2596 cairo_font_face_t
*font_face
;
2597 cairo_ft_options_t ft_options
;
2599 unscaled
= _cairo_ft_unscaled_font_create_from_face (face
);
2600 if (unscaled
== NULL
) {
2601 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
2602 return (cairo_font_face_t
*)&_cairo_font_face_nil
;
2605 ft_options
.load_flags
= load_flags
;
2606 ft_options
.extra_flags
= 0;
2607 _cairo_font_options_init_default (&ft_options
.base
);
2609 font_face
= _cairo_ft_font_face_create (unscaled
, &ft_options
);
2610 _cairo_unscaled_font_destroy (&unscaled
->base
);
2616 * cairo_ft_scaled_font_lock_face:
2617 * @scaled_font: A #cairo_scaled_font_t from the FreeType font backend. Such an
2618 * object can be created by calling cairo_scaled_font_create() on a
2619 * FreeType backend font face (see cairo_ft_font_face_create_for_pattern(),
2620 * cairo_ft_font_face_create_for_ft_face()).
2622 * cairo_ft_scaled_font_lock_face() gets the #FT_Face object from a FreeType
2623 * backend font and scales it appropriately for the font. You must
2624 * release the face with cairo_ft_scaled_font_unlock_face()
2625 * when you are done using it. Since the #FT_Face object can be
2626 * shared between multiple #cairo_scaled_font_t objects, you must not
2627 * lock any other font objects until you unlock this one. A count is
2628 * kept of the number of times cairo_ft_scaled_font_lock_face() is
2629 * called. cairo_ft_scaled_font_unlock_face() must be called the same number
2632 * You must be careful when using this function in a library or in a
2633 * threaded application, because freetype's design makes it unsafe to
2634 * call freetype functions simultaneously from multiple threads, (even
2635 * if using distinct FT_Face objects). Because of this, application
2636 * code that acquires an FT_Face object with this call must add it's
2637 * own locking to protect any use of that object, (and which also must
2638 * protect any other calls into cairo as almost any cairo function
2639 * might result in a call into the freetype library).
2641 * Return value: The #FT_Face object for @font, scaled appropriately,
2642 * or %NULL if @scaled_font is in an error state (see
2643 * cairo_scaled_font_status()) or there is insufficient memory.
2646 cairo_ft_scaled_font_lock_face (cairo_scaled_font_t
*abstract_font
)
2648 cairo_ft_scaled_font_t
*scaled_font
= (cairo_ft_scaled_font_t
*) abstract_font
;
2650 cairo_status_t status
;
2652 if (! _cairo_scaled_font_is_ft (abstract_font
)) {
2653 _cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH
);
2657 if (scaled_font
->base
.status
)
2660 face
= _cairo_ft_unscaled_font_lock_face (scaled_font
->unscaled
);
2662 status
= _cairo_scaled_font_set_error (&scaled_font
->base
, CAIRO_STATUS_NO_MEMORY
);
2666 status
= _cairo_ft_unscaled_font_set_scale (scaled_font
->unscaled
,
2667 &scaled_font
->base
.scale
);
2669 _cairo_ft_unscaled_font_unlock_face (scaled_font
->unscaled
);
2670 status
= _cairo_scaled_font_set_error (&scaled_font
->base
, status
);
2674 /* Note: We deliberately release the unscaled font's mutex here,
2675 * so that we are not holding a lock across two separate calls to
2676 * cairo function, (which would give the application some
2677 * opportunity for creating deadlock. This is obviously unsafe,
2678 * but as documented, the user must add manual locking when using
2680 CAIRO_MUTEX_UNLOCK (scaled_font
->unscaled
->mutex
);
2686 * cairo_ft_scaled_font_unlock_face:
2687 * @scaled_font: A #cairo_scaled_font_t from the FreeType font backend. Such an
2688 * object can be created by calling cairo_scaled_font_create() on a
2689 * FreeType backend font face (see cairo_ft_font_face_create_for_pattern(),
2690 * cairo_ft_font_face_create_for_ft_face()).
2692 * Releases a face obtained with cairo_ft_scaled_font_lock_face().
2695 cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t
*abstract_font
)
2697 cairo_ft_scaled_font_t
*scaled_font
= (cairo_ft_scaled_font_t
*) abstract_font
;
2699 if (! _cairo_scaled_font_is_ft (abstract_font
)) {
2700 _cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH
);
2704 if (scaled_font
->base
.status
)
2707 /* Note: We released the unscaled font's mutex at the end of
2708 * cairo_ft_scaled_font_lock_face, so we have to acquire it again
2709 * as _cairo_ft_unscaled_font_unlock_face expects it to be held
2710 * when we call into it. */
2711 CAIRO_MUTEX_LOCK (scaled_font
->unscaled
->mutex
);
2713 _cairo_ft_unscaled_font_unlock_face (scaled_font
->unscaled
);
2716 /* We expose our unscaled font implementation internally for the the
2717 * PDF backend, which needs to keep track of the the different
2718 * fonts-on-disk used by a document, so it can embed them.
2720 cairo_unscaled_font_t
*
2721 _cairo_ft_scaled_font_get_unscaled_font (cairo_scaled_font_t
*abstract_font
)
2723 cairo_ft_scaled_font_t
*scaled_font
= (cairo_ft_scaled_font_t
*) abstract_font
;
2725 return &scaled_font
->unscaled
->base
;
2729 _cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t
*scaled_font
)
2731 cairo_ft_scaled_font_t
*ft_scaled_font
;
2733 if (!_cairo_scaled_font_is_ft (scaled_font
))
2736 ft_scaled_font
= (cairo_ft_scaled_font_t
*) scaled_font
;
2737 if (ft_scaled_font
->ft_options
.load_flags
& FT_LOAD_VERTICAL_LAYOUT
)
2743 _cairo_ft_font_reset_static_data (void)
2745 _cairo_ft_unscaled_font_map_destroy ();