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
3  *
4  * Copyright © 2000 Keith Packard
5  * Copyright © 2005 Red Hat, Inc
6  *
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.
14  *
15  * You should have received a copy of the LGPL along with this library
16  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
18  * You should have received a copy of the MPL along with this library
19  * in the file COPYING-MPL-1.1
20  *
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/
25  *
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.
29  *
30  * The Original Code is the cairo graphics library.
31  *
32  * The Initial Developer of the Original Code is Red Hat, Inc.
33  *
34  * Contributor(s):
35  *      Graydon Hoare <graydon@redhat.com>
36  *	Owen Taylor <otaylor@redhat.com>
37  *      Keith Packard <keithp@keithp.com>
38  *      Carl Worth <cworth@cworth.org>
39  */
40 
41 #define _BSD_SOURCE /* for strdup() */
42 #include "cairoint.h"
43 
44 #include "cairo-error-private.h"
45 #include "cairo-ft-private.h"
46 
47 #include <float.h>
48 
49 #include "cairo-fontconfig-private.h"
50 
51 #include <ft2build.h>
52 #include FT_FREETYPE_H
53 #include FT_OUTLINE_H
54 #include FT_IMAGE_H
55 #include FT_TRUETYPE_TABLES_H
56 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
57 #include FT_SYNTHESIS_H
58 #endif
59 
60 #if HAVE_FT_LIBRARY_SETLCDFILTER
61 #include FT_LCD_FILTER_H
62 #endif
63 
64 /* Fontconfig version older than 2.6 didn't have these options */
65 #ifndef FC_LCD_FILTER
66 #define FC_LCD_FILTER	"lcdfilter"
67 #endif
68 /* Some Ubuntu versions defined FC_LCD_FILTER without defining the following */
69 #ifndef FC_LCD_NONE
70 #define FC_LCD_NONE	0
71 #define FC_LCD_DEFAULT	1
72 #define FC_LCD_LIGHT	2
73 #define FC_LCD_LEGACY	3
74 #endif
75 
76 /* FreeType version older than 2.3.5(?) didn't have these options */
77 #ifndef FT_LCD_FILTER_NONE
78 #define FT_LCD_FILTER_NONE	0
79 #define FT_LCD_FILTER_DEFAULT	1
80 #define FT_LCD_FILTER_LIGHT	2
81 #define FT_LCD_FILTER_LEGACY	16
82 #endif
83 
84 #define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
85 #define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
86 #define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
87 #define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0)
88 
89 /* This is the max number of FT_face objects we keep open at once
90  */
91 #define MAX_OPEN_FACES 10
92 
93 /**
94  * SECTION:cairo-ft
95  * @Title: FreeType Fonts
96  * @Short_Description: Font support for FreeType
97  * @See_Also: #cairo_font_face_t
98  *
99  * The FreeType font backend is primarily used to render text on GNU/Linux
100  * systems, but can be used on other platforms too.
101  */
102 
103 /**
104  * CAIRO_HAS_FT_FONT:
105  *
106  * Defined if the FreeType font backend is available.
107  * This macro can be used to conditionally compile backend-specific code.
108  */
109 
110 /**
111  * CAIRO_HAS_FC_FONT:
112  *
113  * Defined if the Fontconfig-specific functions of the FreeType font backend
114  * are available.
115  * This macro can be used to conditionally compile backend-specific code.
116  */
117 
118 /*
119  * The simple 2x2 matrix is converted into separate scale and shape
120  * factors so that hinting works right
121  */
122 
123 typedef struct _cairo_ft_font_transform {
124     double  x_scale, y_scale;
125     double  shape[2][2];
126 } cairo_ft_font_transform_t;
127 
128 /*
129  * We create an object that corresponds to a single font on the disk;
130  * (identified by a filename/id pair) these are shared between all
131  * fonts using that file.  For cairo_ft_font_face_create_for_ft_face(), we
132  * just create a one-off version with a permanent face value.
133  */
134 
135 typedef struct _cairo_ft_font_face cairo_ft_font_face_t;
136 
137 struct _cairo_ft_unscaled_font {
138     cairo_unscaled_font_t base;
139 
140     cairo_bool_t from_face; /* was the FT_Face provided by user? */
141     FT_Face face;	    /* provided or cached face */
142 
143     /* only set if from_face is false */
144     char *filename;
145     int id;
146 
147     /* We temporarily scale the unscaled font as needed */
148     cairo_bool_t have_scale;
149     cairo_matrix_t current_scale;
150     double x_scale;		/* Extracted X scale factor */
151     double y_scale;             /* Extracted Y scale factor */
152     cairo_bool_t have_shape;	/* true if the current scale has a non-scale component*/
153     cairo_matrix_t current_shape;
154     FT_Matrix Current_Shape;
155 
156     cairo_mutex_t mutex;
157     int lock_count;
158 
159     cairo_ft_font_face_t *faces;	/* Linked list of faces for this font */
160 };
161 
162 static int
163 _cairo_ft_unscaled_font_keys_equal (const void *key_a,
164 				    const void *key_b);
165 
166 static void
167 _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled);
168 
169 typedef enum _cairo_ft_extra_flags {
170     CAIRO_FT_OPTIONS_HINT_METRICS = (1 << 0),
171     CAIRO_FT_OPTIONS_EMBOLDEN = (1 << 1)
172 } cairo_ft_extra_flags_t;
173 
174 typedef struct _cairo_ft_options {
175     cairo_font_options_t    base;
176     int			    load_flags;	 /* flags for FT_Load_Glyph */
177     cairo_ft_extra_flags_t  extra_flags; /* other flags that affect results */
178 } cairo_ft_options_t;
179 
180 struct _cairo_ft_font_face {
181     cairo_font_face_t base;
182 
183     cairo_ft_unscaled_font_t *unscaled;
184     cairo_ft_options_t ft_options;
185     cairo_ft_font_face_t *next;
186 
187 #if CAIRO_HAS_FC_FONT
188     FcPattern *pattern; /* if pattern is set, the above fields will be NULL */
189     cairo_font_face_t *resolved_font_face;
190     FcConfig *resolved_config;
191 #endif
192 };
193 
194 static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend;
195 
196 #if CAIRO_HAS_FC_FONT
197 static cairo_status_t
198 _cairo_ft_font_options_substitute (const cairo_font_options_t *options,
199 				   FcPattern                  *pattern);
200 
201 static cairo_font_face_t *
202 _cairo_ft_resolve_pattern (FcPattern		      *pattern,
203 			   const cairo_matrix_t       *font_matrix,
204 			   const cairo_matrix_t       *ctm,
205 			   const cairo_font_options_t *options);
206 
207 #endif
208 
209 /*
210  * We maintain a hash table to map file/id => #cairo_ft_unscaled_font_t.
211  * The hash table itself isn't limited in size. However, we limit the
212  * number of FT_Face objects we keep around; when we've exceeded that
213  * limit and need to create a new FT_Face, we dump the FT_Face from a
214  * random #cairo_ft_unscaled_font_t which has an unlocked FT_Face, (if
215  * there are any).
216  */
217 
218 typedef struct _cairo_ft_unscaled_font_map {
219     cairo_hash_table_t *hash_table;
220     FT_Library ft_library;
221     int num_open_faces;
222 } cairo_ft_unscaled_font_map_t;
223 
224 static cairo_ft_unscaled_font_map_t *cairo_ft_unscaled_font_map = NULL;
225 
226 
227 static void
_font_map_release_face_lock_held(cairo_ft_unscaled_font_map_t * font_map,cairo_ft_unscaled_font_t * unscaled)228 _font_map_release_face_lock_held (cairo_ft_unscaled_font_map_t *font_map,
229 				  cairo_ft_unscaled_font_t *unscaled)
230 {
231     if (unscaled->face) {
232 	FT_Done_Face (unscaled->face);
233 	unscaled->face = NULL;
234 	unscaled->have_scale = FALSE;
235 
236 	font_map->num_open_faces--;
237     }
238 }
239 
240 static cairo_status_t
_cairo_ft_unscaled_font_map_create(void)241 _cairo_ft_unscaled_font_map_create (void)
242 {
243     cairo_ft_unscaled_font_map_t *font_map;
244 
245     /* This function is only intended to be called from
246      * _cairo_ft_unscaled_font_map_lock. So we'll crash if we can
247      * detect some other call path. */
248     assert (cairo_ft_unscaled_font_map == NULL);
249 
250     font_map = malloc (sizeof (cairo_ft_unscaled_font_map_t));
251     if (unlikely (font_map == NULL))
252 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
253 
254     font_map->hash_table =
255 	_cairo_hash_table_create (_cairo_ft_unscaled_font_keys_equal);
256 
257     if (unlikely (font_map->hash_table == NULL))
258 	goto FAIL;
259 
260     if (unlikely (FT_Init_FreeType (&font_map->ft_library)))
261 	goto FAIL;
262 
263     font_map->num_open_faces = 0;
264 
265     cairo_ft_unscaled_font_map = font_map;
266     return CAIRO_STATUS_SUCCESS;
267 
268 FAIL:
269     if (font_map->hash_table)
270 	_cairo_hash_table_destroy (font_map->hash_table);
271     free (font_map);
272 
273     return _cairo_error (CAIRO_STATUS_NO_MEMORY);
274 }
275 
276 
277 static void
_cairo_ft_unscaled_font_map_pluck_entry(void * entry,void * closure)278 _cairo_ft_unscaled_font_map_pluck_entry (void *entry, void *closure)
279 {
280     cairo_ft_unscaled_font_t *unscaled = entry;
281     cairo_ft_unscaled_font_map_t *font_map = closure;
282 
283     _cairo_hash_table_remove (font_map->hash_table,
284 			      &unscaled->base.hash_entry);
285 
286     if (! unscaled->from_face)
287 	_font_map_release_face_lock_held (font_map, unscaled);
288 
289     _cairo_ft_unscaled_font_fini (unscaled);
290     free (unscaled);
291 }
292 
293 static void
_cairo_ft_unscaled_font_map_destroy(void)294 _cairo_ft_unscaled_font_map_destroy (void)
295 {
296     cairo_ft_unscaled_font_map_t *font_map;
297 
298     CAIRO_MUTEX_LOCK (_cairo_ft_unscaled_font_map_mutex);
299     font_map = cairo_ft_unscaled_font_map;
300     cairo_ft_unscaled_font_map = NULL;
301     CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex);
302 
303     if (font_map != NULL) {
304 	_cairo_hash_table_foreach (font_map->hash_table,
305 				   _cairo_ft_unscaled_font_map_pluck_entry,
306 				   font_map);
307 	assert (font_map->num_open_faces == 0);
308 
309 	FT_Done_FreeType (font_map->ft_library);
310 
311 	_cairo_hash_table_destroy (font_map->hash_table);
312 
313 	free (font_map);
314     }
315 }
316 
317 static cairo_ft_unscaled_font_map_t *
_cairo_ft_unscaled_font_map_lock(void)318 _cairo_ft_unscaled_font_map_lock (void)
319 {
320     CAIRO_MUTEX_LOCK (_cairo_ft_unscaled_font_map_mutex);
321 
322     if (unlikely (cairo_ft_unscaled_font_map == NULL)) {
323 	if (unlikely (_cairo_ft_unscaled_font_map_create ())) {
324 	    CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex);
325 	    return NULL;
326 	}
327     }
328 
329     return cairo_ft_unscaled_font_map;
330 }
331 
332 static void
_cairo_ft_unscaled_font_map_unlock(void)333 _cairo_ft_unscaled_font_map_unlock (void)
334 {
335     CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex);
336 }
337 
338 static void
_cairo_ft_unscaled_font_init_key(cairo_ft_unscaled_font_t * key,cairo_bool_t from_face,char * filename,int id,FT_Face face)339 _cairo_ft_unscaled_font_init_key (cairo_ft_unscaled_font_t *key,
340 				  cairo_bool_t              from_face,
341 				  char			   *filename,
342 				  int			    id,
343 				  FT_Face		    face)
344 {
345     unsigned long hash;
346 
347     key->from_face = from_face;
348     key->filename = filename;
349     key->id = id;
350     key->face = face;
351 
352     hash = _cairo_hash_string (filename);
353     /* the constants are just arbitrary primes */
354     hash += ((unsigned long) id) * 1607;
355     hash += ((unsigned long) face) * 2137;
356 
357     key->base.hash_entry.hash = hash;
358 }
359 
360 /**
361  * _cairo_ft_unscaled_font_init:
362  *
363  * Initialize a #cairo_ft_unscaled_font_t.
364  *
365  * There are two basic flavors of #cairo_ft_unscaled_font_t, one
366  * created from an FT_Face and the other created from a filename/id
367  * pair. These two flavors are identified as from_face and !from_face.
368  *
369  * To initialize a from_face font, pass filename==%NULL, id=0 and the
370  * desired face.
371  *
372  * To initialize a !from_face font, pass the filename/id as desired
373  * and face==%NULL.
374  *
375  * Note that the code handles these two flavors in very distinct
376  * ways. For example there is a hash_table mapping
377  * filename/id->#cairo_unscaled_font_t in the !from_face case, but no
378  * parallel in the from_face case, (where the calling code would have
379  * to do its own mapping to ensure similar sharing).
380  **/
381 static cairo_status_t
_cairo_ft_unscaled_font_init(cairo_ft_unscaled_font_t * unscaled,cairo_bool_t from_face,const char * filename,int id,FT_Face face)382 _cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled,
383 			      cairo_bool_t              from_face,
384 			      const char	       *filename,
385 			      int			id,
386 			      FT_Face			face)
387 {
388     _cairo_unscaled_font_init (&unscaled->base,
389 			       &cairo_ft_unscaled_font_backend);
390 
391     if (from_face) {
392 	unscaled->from_face = TRUE;
393 	_cairo_ft_unscaled_font_init_key (unscaled, TRUE, NULL, 0, face);
394     } else {
395 	char *filename_copy;
396 
397 	unscaled->from_face = FALSE;
398 	unscaled->face = NULL;
399 
400 	filename_copy = strdup (filename);
401 	if (unlikely (filename_copy == NULL))
402 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
403 
404 	_cairo_ft_unscaled_font_init_key (unscaled, FALSE, filename_copy, id, NULL);
405     }
406 
407     unscaled->have_scale = FALSE;
408     CAIRO_MUTEX_INIT (unscaled->mutex);
409     unscaled->lock_count = 0;
410 
411     unscaled->faces = NULL;
412 
413     return CAIRO_STATUS_SUCCESS;
414 }
415 
416 /**
417  * _cairo_ft_unscaled_font_fini:
418  *
419  * Free all data associated with a #cairo_ft_unscaled_font_t.
420  *
421  * CAUTION: The unscaled->face field must be %NULL before calling this
422  * function. This is because the #cairo_ft_unscaled_font_t_map keeps a
423  * count of these faces (font_map->num_open_faces) so it maintains the
424  * unscaled->face field while it has its lock held. See
425  * _font_map_release_face_lock_held().
426  **/
427 static void
_cairo_ft_unscaled_font_fini(cairo_ft_unscaled_font_t * unscaled)428 _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled)
429 {
430     assert (unscaled->face == NULL);
431 
432     if (unscaled->filename) {
433 	free (unscaled->filename);
434 	unscaled->filename = NULL;
435     }
436 
437     CAIRO_MUTEX_FINI (unscaled->mutex);
438 }
439 
440 static int
_cairo_ft_unscaled_font_keys_equal(const void * key_a,const void * key_b)441 _cairo_ft_unscaled_font_keys_equal (const void *key_a,
442 				    const void *key_b)
443 {
444     const cairo_ft_unscaled_font_t *unscaled_a = key_a;
445     const cairo_ft_unscaled_font_t *unscaled_b = key_b;
446 
447     if (unscaled_a->id == unscaled_b->id &&
448 	unscaled_a->from_face == unscaled_b->from_face)
449     {
450         if (unscaled_a->from_face)
451 	    return unscaled_a->face == unscaled_b->face;
452 
453 	if (unscaled_a->filename == NULL && unscaled_b->filename == NULL)
454 	    return TRUE;
455 	else if (unscaled_a->filename == NULL || unscaled_b->filename == NULL)
456 	    return FALSE;
457 	else
458 	    return (strcmp (unscaled_a->filename, unscaled_b->filename) == 0);
459     }
460 
461     return FALSE;
462 }
463 
464 /* Finds or creates a #cairo_ft_unscaled_font_t for the filename/id from
465  * pattern.  Returns a new reference to the unscaled font.
466  */
467 static cairo_status_t
_cairo_ft_unscaled_font_create_internal(cairo_bool_t from_face,char * filename,int id,FT_Face font_face,cairo_ft_unscaled_font_t ** out)468 _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face,
469 					 char *filename,
470 					 int id,
471 					 FT_Face font_face,
472 					 cairo_ft_unscaled_font_t **out)
473 {
474     cairo_ft_unscaled_font_t key, *unscaled;
475     cairo_ft_unscaled_font_map_t *font_map;
476     cairo_status_t status;
477 
478     font_map = _cairo_ft_unscaled_font_map_lock ();
479     if (unlikely (font_map == NULL))
480 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
481 
482     _cairo_ft_unscaled_font_init_key (&key, from_face, filename, id, font_face);
483 
484     /* Return existing unscaled font if it exists in the hash table. */
485     unscaled = _cairo_hash_table_lookup (font_map->hash_table,
486 					 &key.base.hash_entry);
487     if (unscaled != NULL) {
488 	_cairo_unscaled_font_reference (&unscaled->base);
489 	goto DONE;
490     }
491 
492     /* Otherwise create it and insert into hash table. */
493     unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
494     if (unlikely (unscaled == NULL)) {
495 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
496 	goto UNWIND_FONT_MAP_LOCK;
497     }
498 
499     status = _cairo_ft_unscaled_font_init (unscaled, from_face, filename, id, font_face);
500     if (unlikely (status))
501 	goto UNWIND_UNSCALED_MALLOC;
502 
503     assert (unscaled->base.hash_entry.hash == key.base.hash_entry.hash);
504     status = _cairo_hash_table_insert (font_map->hash_table,
505 				       &unscaled->base.hash_entry);
506     if (unlikely (status))
507 	goto UNWIND_UNSCALED_FONT_INIT;
508 
509 DONE:
510     _cairo_ft_unscaled_font_map_unlock ();
511     *out = unscaled;
512     return CAIRO_STATUS_SUCCESS;
513 
514 UNWIND_UNSCALED_FONT_INIT:
515     _cairo_ft_unscaled_font_fini (unscaled);
516 UNWIND_UNSCALED_MALLOC:
517     free (unscaled);
518 UNWIND_FONT_MAP_LOCK:
519     _cairo_ft_unscaled_font_map_unlock ();
520     return status;
521 }
522 
523 
524 #if CAIRO_HAS_FC_FONT
525 static cairo_status_t
_cairo_ft_unscaled_font_create_for_pattern(FcPattern * pattern,cairo_ft_unscaled_font_t ** out)526 _cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern,
527 					    cairo_ft_unscaled_font_t **out)
528 {
529     FT_Face font_face = NULL;
530     char *filename = NULL;
531     int id = 0;
532     FcResult ret;
533 
534     ret = FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &font_face);
535     if (ret == FcResultMatch)
536 	goto DONE;
537     if (ret == FcResultOutOfMemory)
538 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
539 
540     ret = FcPatternGetString (pattern, FC_FILE, 0, (FcChar8 **) &filename);
541     if (ret == FcResultOutOfMemory)
542 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
543     if (ret == FcResultMatch) {
544 	/* If FC_INDEX is not set, we just use 0 */
545 	ret = FcPatternGetInteger (pattern, FC_INDEX, 0, &id);
546 	if (ret == FcResultOutOfMemory)
547 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
548 
549 	goto DONE;
550     }
551 
552     /* The pattern contains neither a face nor a filename, resolve it later. */
553     *out = NULL;
554     return CAIRO_STATUS_SUCCESS;
555 
556 DONE:
557     return _cairo_ft_unscaled_font_create_internal (font_face != NULL,
558 						    filename, id, font_face,
559 						    out);
560 }
561 #endif
562 
563 static cairo_status_t
_cairo_ft_unscaled_font_create_from_face(FT_Face face,cairo_ft_unscaled_font_t ** out)564 _cairo_ft_unscaled_font_create_from_face (FT_Face face,
565 					  cairo_ft_unscaled_font_t **out)
566 {
567     return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, 0, face, out);
568 }
569 
570 static void
_cairo_ft_unscaled_font_destroy(void * abstract_font)571 _cairo_ft_unscaled_font_destroy (void *abstract_font)
572 {
573     cairo_ft_unscaled_font_t *unscaled  = abstract_font;
574     cairo_ft_unscaled_font_map_t *font_map;
575 
576     if (unscaled == NULL)
577 	return;
578 
579     font_map = _cairo_ft_unscaled_font_map_lock ();
580     /* All created objects must have been mapped in the font map. */
581     assert (font_map != NULL);
582 
583     if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled->base.ref_count)) {
584 	/* somebody recreated the font whilst we waited for the lock */
585 	_cairo_ft_unscaled_font_map_unlock ();
586 	return;
587     }
588 
589     _cairo_hash_table_remove (font_map->hash_table,
590 			      &unscaled->base.hash_entry);
591 
592     if (unscaled->from_face) {
593 	/* See comments in _ft_font_face_destroy about the "zombie" state
594 	 * for a _ft_font_face.
595 	 */
596 	if (unscaled->faces && unscaled->faces->unscaled == NULL) {
597 	    assert (unscaled->faces->next == NULL);
598 	    cairo_font_face_destroy (&unscaled->faces->base);
599 	}
600     } else {
601 	_font_map_release_face_lock_held (font_map, unscaled);
602     }
603     unscaled->face = NULL;
604 
605     _cairo_ft_unscaled_font_map_unlock ();
606 
607     _cairo_ft_unscaled_font_fini (unscaled);
608 }
609 
610 static cairo_bool_t
_has_unlocked_face(const void * entry)611 _has_unlocked_face (const void *entry)
612 {
613     const cairo_ft_unscaled_font_t *unscaled = entry;
614 
615     return (!unscaled->from_face && unscaled->lock_count == 0 && unscaled->face);
616 }
617 
618 /* Ensures that an unscaled font has a face object. If we exceed
619  * MAX_OPEN_FACES, try to close some.
620  *
621  * This differs from _cairo_ft_scaled_font_lock_face in that it doesn't
622  * set the scale on the face, but just returns it at the last scale.
623  */
624 cairo_warn FT_Face
_cairo_ft_unscaled_font_lock_face(cairo_ft_unscaled_font_t * unscaled)625 _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled)
626 {
627     cairo_ft_unscaled_font_map_t *font_map;
628     FT_Face face = NULL;
629 
630     CAIRO_MUTEX_LOCK (unscaled->mutex);
631     unscaled->lock_count++;
632 
633     if (unscaled->face)
634 	return unscaled->face;
635 
636     /* If this unscaled font was created from an FT_Face then we just
637      * returned it above. */
638     assert (!unscaled->from_face);
639 
640     font_map = _cairo_ft_unscaled_font_map_lock ();
641     {
642 	assert (font_map != NULL);
643 
644 	while (font_map->num_open_faces >= MAX_OPEN_FACES)
645 	{
646 	    cairo_ft_unscaled_font_t *entry;
647 
648 	    entry = _cairo_hash_table_random_entry (font_map->hash_table,
649 						    _has_unlocked_face);
650 	    if (entry == NULL)
651 		break;
652 
653 	    _font_map_release_face_lock_held (font_map, entry);
654 	}
655     }
656     _cairo_ft_unscaled_font_map_unlock ();
657 
658     if (FT_New_Face (font_map->ft_library,
659 		     unscaled->filename,
660 		     unscaled->id,
661 		     &face) != FT_Err_Ok)
662     {
663 	unscaled->lock_count--;
664 	CAIRO_MUTEX_UNLOCK (unscaled->mutex);
665 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
666 	return NULL;
667     }
668 
669     unscaled->face = face;
670 
671     font_map->num_open_faces++;
672 
673     return face;
674 }
675 
676 
677 /* Unlock unscaled font locked with _cairo_ft_unscaled_font_lock_face
678  */
679 void
_cairo_ft_unscaled_font_unlock_face(cairo_ft_unscaled_font_t * unscaled)680 _cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled)
681 {
682     assert (unscaled->lock_count > 0);
683 
684     unscaled->lock_count--;
685 
686     CAIRO_MUTEX_UNLOCK (unscaled->mutex);
687 }
688 
689 
690 static cairo_status_t
_compute_transform(cairo_ft_font_transform_t * sf,cairo_matrix_t * scale)691 _compute_transform (cairo_ft_font_transform_t *sf,
692 		    cairo_matrix_t      *scale)
693 {
694     cairo_status_t status;
695     double x_scale, y_scale;
696     cairo_matrix_t normalized = *scale;
697 
698     /* The font matrix has x and y "scale" components which we extract and
699      * use as character scale values. These influence the way freetype
700      * chooses hints, as well as selecting different bitmaps in
701      * hand-rendered fonts. We also copy the normalized matrix to
702      * freetype's transformation.
703      */
704 
705     status = _cairo_matrix_compute_basis_scale_factors (scale,
706 						  &x_scale, &y_scale,
707 						  1);
708     if (unlikely (status))
709 	return status;
710 
711     /* FreeType docs say this about x_scale and y_scale:
712      * "A character width or height smaller than 1pt is set to 1pt;"
713      * So, we cap them from below at 1.0 and let the FT transform
714      * take care of sub-1.0 scaling. */
715     if (x_scale < 1.0)
716       x_scale = 1.0;
717     if (y_scale < 1.0)
718       y_scale = 1.0;
719 
720     sf->x_scale = x_scale;
721     sf->y_scale = y_scale;
722 
723     cairo_matrix_scale (&normalized, 1.0 / x_scale, 1.0 / y_scale);
724 
725     _cairo_matrix_get_affine (&normalized,
726 			      &sf->shape[0][0], &sf->shape[0][1],
727 			      &sf->shape[1][0], &sf->shape[1][1],
728 			      NULL, NULL);
729 
730     return CAIRO_STATUS_SUCCESS;
731 }
732 
733 /* Temporarily scales an unscaled font to the give scale. We catch
734  * scaling to the same size, since changing a FT_Face is expensive.
735  */
736 static cairo_status_t
_cairo_ft_unscaled_font_set_scale(cairo_ft_unscaled_font_t * unscaled,cairo_matrix_t * scale)737 _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
738 				   cairo_matrix_t	      *scale)
739 {
740     cairo_status_t status;
741     cairo_ft_font_transform_t sf;
742     FT_Matrix mat;
743     FT_Error error;
744 
745     assert (unscaled->face != NULL);
746 
747     if (unscaled->have_scale &&
748 	scale->xx == unscaled->current_scale.xx &&
749 	scale->yx == unscaled->current_scale.yx &&
750 	scale->xy == unscaled->current_scale.xy &&
751 	scale->yy == unscaled->current_scale.yy)
752 	return CAIRO_STATUS_SUCCESS;
753 
754     unscaled->have_scale = TRUE;
755     unscaled->current_scale = *scale;
756 
757     status = _compute_transform (&sf, scale);
758     if (unlikely (status))
759 	return status;
760 
761     unscaled->x_scale = sf.x_scale;
762     unscaled->y_scale = sf.y_scale;
763 
764     mat.xx = DOUBLE_TO_16_16(sf.shape[0][0]);
765     mat.yx = - DOUBLE_TO_16_16(sf.shape[0][1]);
766     mat.xy = - DOUBLE_TO_16_16(sf.shape[1][0]);
767     mat.yy = DOUBLE_TO_16_16(sf.shape[1][1]);
768 
769     unscaled->have_shape = (mat.xx != 0x10000 ||
770 			    mat.yx != 0x00000 ||
771 			    mat.xy != 0x00000 ||
772 			    mat.yy != 0x10000);
773 
774     unscaled->Current_Shape = mat;
775     cairo_matrix_init (&unscaled->current_shape,
776 		       sf.shape[0][0], sf.shape[0][1],
777 		       sf.shape[1][0], sf.shape[1][1],
778 		       0.0, 0.0);
779 
780     FT_Set_Transform(unscaled->face, &mat, NULL);
781 
782     if ((unscaled->face->face_flags & FT_FACE_FLAG_SCALABLE) != 0) {
783 	error = FT_Set_Char_Size (unscaled->face,
784 				  sf.x_scale * 64.0 + .5,
785 				  sf.y_scale * 64.0 + .5,
786 				  0, 0);
787 	if (error)
788 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
789     } else {
790 	double min_distance = DBL_MAX;
791 	int i;
792 	int best_i = 0;
793 
794 	for (i = 0; i < unscaled->face->num_fixed_sizes; i++) {
795 #if HAVE_FT_BITMAP_SIZE_Y_PPEM
796 	    double size = unscaled->face->available_sizes[i].y_ppem / 64.;
797 #else
798 	    double size = unscaled->face->available_sizes[i].height;
799 #endif
800 	    double distance = fabs (size - sf.y_scale);
801 
802 	    if (distance <= min_distance) {
803 		min_distance = distance;
804 		best_i = i;
805 	    }
806 	}
807 #if HAVE_FT_BITMAP_SIZE_Y_PPEM
808 	error = FT_Set_Char_Size (unscaled->face,
809 				  unscaled->face->available_sizes[best_i].x_ppem,
810 				  unscaled->face->available_sizes[best_i].y_ppem,
811 				  0, 0);
812 	if (error)
813 #endif
814 	    error = FT_Set_Pixel_Sizes (unscaled->face,
815 					unscaled->face->available_sizes[best_i].width,
816 					unscaled->face->available_sizes[best_i].height);
817 	if (error)
818 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
819     }
820 
821     return CAIRO_STATUS_SUCCESS;
822 }
823 
824 /* we sometimes need to convert the glyph bitmap in a FT_GlyphSlot
825  * into a different format. For example, we want to convert a
826  * FT_PIXEL_MODE_LCD or FT_PIXEL_MODE_LCD_V bitmap into a 32-bit
827  * ARGB or ABGR bitmap.
828  *
829  * this function prepares a target descriptor for this operation.
830  *
831  * input :: target bitmap descriptor. The function will set its
832  *          'width', 'rows' and 'pitch' fields, and only these
833  *
834  * slot  :: the glyph slot containing the source bitmap. this
835  *          function assumes that slot->format == FT_GLYPH_FORMAT_BITMAP
836  *
837  * mode  :: the requested final rendering mode. supported values are
838  *          MONO, NORMAL (i.e. gray), LCD and LCD_V
839  *
840  * the function returns the size in bytes of the corresponding buffer,
841  * it's up to the caller to allocate the corresponding memory block
842  * before calling _fill_xrender_bitmap
843  *
844  * it also returns -1 in case of error (e.g. incompatible arguments,
845  * like trying to convert a gray bitmap into a monochrome one)
846  */
847 static int
_compute_xrender_bitmap_size(FT_Bitmap * target,FT_GlyphSlot slot,FT_Render_Mode mode)848 _compute_xrender_bitmap_size(FT_Bitmap      *target,
849 			     FT_GlyphSlot    slot,
850 			     FT_Render_Mode  mode)
851 {
852     FT_Bitmap *ftbit;
853     int width, height, pitch;
854 
855     if (slot->format != FT_GLYPH_FORMAT_BITMAP)
856 	return -1;
857 
858     /* compute the size of the final bitmap */
859     ftbit = &slot->bitmap;
860 
861     width = ftbit->width;
862     height = ftbit->rows;
863     pitch = (width + 3) & ~3;
864 
865     switch (ftbit->pixel_mode) {
866     case FT_PIXEL_MODE_MONO:
867 	if (mode == FT_RENDER_MODE_MONO) {
868 	    pitch = (((width + 31) & ~31) >> 3);
869 	    break;
870 	}
871 	/* fall-through */
872 
873     case FT_PIXEL_MODE_GRAY:
874 	if (mode == FT_RENDER_MODE_LCD ||
875 	    mode == FT_RENDER_MODE_LCD_V)
876 	{
877 	    /* each pixel is replicated into a 32-bit ARGB value */
878 	    pitch = width * 4;
879 	}
880 	break;
881 
882     case FT_PIXEL_MODE_LCD:
883 	if (mode != FT_RENDER_MODE_LCD)
884 	    return -1;
885 
886 	/* horz pixel triplets are packed into 32-bit ARGB values */
887 	width /= 3;
888 	pitch = width * 4;
889 	break;
890 
891     case FT_PIXEL_MODE_LCD_V:
892 	if (mode != FT_RENDER_MODE_LCD_V)
893 	    return -1;
894 
895 	/* vert pixel triplets are packed into 32-bit ARGB values */
896 	height /= 3;
897 	pitch = width * 4;
898 	break;
899 
900     default:  /* unsupported source format */
901 	return -1;
902     }
903 
904     target->width = width;
905     target->rows = height;
906     target->pitch = pitch;
907     target->buffer = NULL;
908 
909     return pitch * height;
910 }
911 
912 /* this functions converts the glyph bitmap found in a FT_GlyphSlot
913  * into a different format (see _compute_xrender_bitmap_size)
914  *
915  * you should call this function after _compute_xrender_bitmap_size
916  *
917  * target :: target bitmap descriptor. Note that its 'buffer' pointer
918  *           must point to memory allocated by the caller
919  *
920  * slot   :: the glyph slot containing the source bitmap
921  *
922  * mode   :: the requested final rendering mode
923  *
924  * bgr    :: boolean, set if BGR or VBGR pixel ordering is needed
925  */
926 static void
_fill_xrender_bitmap(FT_Bitmap * target,FT_GlyphSlot slot,FT_Render_Mode mode,int bgr)927 _fill_xrender_bitmap(FT_Bitmap      *target,
928 		     FT_GlyphSlot    slot,
929 		     FT_Render_Mode  mode,
930 		     int             bgr)
931 {
932     FT_Bitmap *ftbit = &slot->bitmap;
933     unsigned char *srcLine = ftbit->buffer;
934     unsigned char *dstLine = target->buffer;
935     int src_pitch = ftbit->pitch;
936     int width = target->width;
937     int height = target->rows;
938     int pitch = target->pitch;
939     int subpixel;
940     int h;
941 
942     subpixel = (mode == FT_RENDER_MODE_LCD ||
943 		mode == FT_RENDER_MODE_LCD_V);
944 
945     if (src_pitch < 0)
946 	srcLine -= src_pitch * (ftbit->rows - 1);
947 
948     target->pixel_mode = ftbit->pixel_mode;
949 
950     switch (ftbit->pixel_mode) {
951     case FT_PIXEL_MODE_MONO:
952 	if (subpixel) {
953 	    /* convert mono to ARGB32 values */
954 
955 	    for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) {
956 		int x;
957 
958 		for (x = 0; x < width; x++) {
959 		    if (srcLine[(x >> 3)] & (0x80 >> (x & 7)))
960 			((unsigned int *) dstLine)[x] = 0xffffffffU;
961 		}
962 	    }
963 	    target->pixel_mode = FT_PIXEL_MODE_LCD;
964 
965 	} else if (mode == FT_RENDER_MODE_NORMAL) {
966 	    /* convert mono to 8-bit gray */
967 
968 	    for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) {
969 		int x;
970 
971 		for (x = 0; x < width; x++) {
972 		    if (srcLine[(x >> 3)] & (0x80 >> (x & 7)))
973 			dstLine[x] = 0xff;
974 		}
975 	    }
976 	    target->pixel_mode = FT_PIXEL_MODE_GRAY;
977 
978 	} else {
979 	    /* copy mono to mono */
980 
981 	    int  bytes = (width + 7) >> 3;
982 
983 	    for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch)
984 		memcpy (dstLine, srcLine, bytes);
985 	}
986 	break;
987 
988     case FT_PIXEL_MODE_GRAY:
989 	if (subpixel) {
990 	    /* convert gray to ARGB32 values */
991 
992 	    for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) {
993 		int x;
994 		unsigned int *dst = (unsigned int *) dstLine;
995 
996 		for (x = 0; x < width; x++) {
997 		    unsigned int pix = srcLine[x];
998 
999 		    pix |= (pix << 8);
1000 		    pix |= (pix << 16);
1001 
1002 		    dst[x] = pix;
1003 		}
1004 	    }
1005 	    target->pixel_mode = FT_PIXEL_MODE_LCD;
1006         } else {
1007             /* copy gray into gray */
1008 
1009             for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch)
1010                 memcpy (dstLine, srcLine, width);
1011         }
1012         break;
1013 
1014     case FT_PIXEL_MODE_LCD:
1015 	if (!bgr) {
1016 	    /* convert horizontal RGB into ARGB32 */
1017 
1018 	    for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) {
1019 		int x;
1020 		unsigned char *src = srcLine;
1021 		unsigned int *dst = (unsigned int *) dstLine;
1022 
1023 		for (x = 0; x < width; x++, src += 3) {
1024 		    unsigned int  pix;
1025 
1026 		    pix = ((unsigned int)src[0] << 16) |
1027 			  ((unsigned int)src[1] <<  8) |
1028 			  ((unsigned int)src[2]      ) |
1029 			  ((unsigned int)src[1] << 24) ;
1030 
1031 		    dst[x] = pix;
1032 		}
1033 	    }
1034 	} else {
1035 	    /* convert horizontal BGR into ARGB32 */
1036 
1037 	    for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) {
1038 
1039 		int x;
1040 		unsigned char *src = srcLine;
1041 		unsigned int *dst = (unsigned int *) dstLine;
1042 
1043 		for (x = 0; x < width; x++, src += 3) {
1044 		    unsigned int  pix;
1045 
1046 		    pix = ((unsigned int)src[2] << 16) |
1047 			  ((unsigned int)src[1] <<  8) |
1048 			  ((unsigned int)src[0]      ) |
1049 			  ((unsigned int)src[1] << 24) ;
1050 
1051 		    dst[x] = pix;
1052 		}
1053 	    }
1054 	}
1055 	break;
1056 
1057     default:  /* FT_PIXEL_MODE_LCD_V */
1058 	/* convert vertical RGB into ARGB32 */
1059 	if (!bgr) {
1060 
1061 	    for (h = height; h > 0; h--, srcLine += 3 * src_pitch, dstLine += pitch) {
1062 		int x;
1063 		unsigned char* src = srcLine;
1064 		unsigned int*  dst = (unsigned int *) dstLine;
1065 
1066 		for (x = 0; x < width; x++, src += 1) {
1067 		    unsigned int pix;
1068 		    pix = ((unsigned int)src[0]           << 16) |
1069 			  ((unsigned int)src[src_pitch]   <<  8) |
1070 			  ((unsigned int)src[src_pitch*2]      ) |
1071 			  ((unsigned int)src[src_pitch]   << 24) ;
1072 		    dst[x] = pix;
1073 		}
1074 	    }
1075 	} else {
1076 
1077 	    for (h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch) {
1078 		int x;
1079 		unsigned char *src = srcLine;
1080 		unsigned int *dst = (unsigned int *) dstLine;
1081 
1082 		for (x = 0; x < width; x++, src += 1) {
1083 		    unsigned int  pix;
1084 
1085 		    pix = ((unsigned int)src[src_pitch * 2] << 16) |
1086 			  ((unsigned int)src[src_pitch]     <<  8) |
1087 			  ((unsigned int)src[0]                  ) |
1088 			  ((unsigned int)src[src_pitch]     << 24) ;
1089 
1090 		    dst[x] = pix;
1091 		}
1092 	    }
1093 	}
1094     }
1095 }
1096 
1097 
1098 /* Fills in val->image with an image surface created from @bitmap
1099  */
1100 static cairo_status_t
_get_bitmap_surface(FT_Bitmap * bitmap,cairo_bool_t own_buffer,cairo_font_options_t * font_options,cairo_image_surface_t ** surface)1101 _get_bitmap_surface (FT_Bitmap		     *bitmap,
1102 		     cairo_bool_t	      own_buffer,
1103 		     cairo_font_options_t    *font_options,
1104 		     cairo_image_surface_t  **surface)
1105 {
1106     int width, height, stride;
1107     unsigned char *data;
1108     int format = CAIRO_FORMAT_A8;
1109     cairo_image_surface_t *image;
1110 
1111     width = bitmap->width;
1112     height = bitmap->rows;
1113 
1114     if (width == 0 || height == 0) {
1115 	*surface = (cairo_image_surface_t *)
1116 	    cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);
1117 	return (*surface)->base.status;
1118     }
1119 
1120     switch (bitmap->pixel_mode) {
1121     case FT_PIXEL_MODE_MONO:
1122 	stride = (((width + 31) & ~31) >> 3);
1123 	if (own_buffer) {
1124 	    data = bitmap->buffer;
1125 	    assert (stride == bitmap->pitch);
1126 	} else {
1127 	    data = _cairo_malloc_ab (height, stride);
1128 	    if (!data)
1129 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1130 
1131 	    if (stride == bitmap->pitch) {
1132 		memcpy (data, bitmap->buffer, stride * height);
1133 	    } else {
1134 		int i;
1135 		unsigned char *source, *dest;
1136 
1137 		source = bitmap->buffer;
1138 		dest = data;
1139 		for (i = height; i; i--) {
1140 		    memcpy (dest, source, bitmap->pitch);
1141 		    memset (dest + bitmap->pitch, '\0', stride - bitmap->pitch);
1142 
1143 		    source += bitmap->pitch;
1144 		    dest += stride;
1145 		}
1146 	    }
1147 	}
1148 
1149 #ifndef WORDS_BIGENDIAN
1150 	{
1151 	    uint8_t   *d = data;
1152 	    int		count = stride * height;
1153 
1154 	    while (count--) {
1155 		*d = CAIRO_BITSWAP8 (*d);
1156 		d++;
1157 	    }
1158 	}
1159 #endif
1160 	format = CAIRO_FORMAT_A1;
1161 	break;
1162 
1163     case FT_PIXEL_MODE_LCD:
1164     case FT_PIXEL_MODE_LCD_V:
1165     case FT_PIXEL_MODE_GRAY:
1166         if (font_options->antialias != CAIRO_ANTIALIAS_SUBPIXEL) {
1167 	    stride = bitmap->pitch;
1168 	    if (own_buffer) {
1169 		data = bitmap->buffer;
1170 	    } else {
1171 		data = _cairo_malloc_ab (height, stride);
1172 		if (!data)
1173 		    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1174 
1175 		memcpy (data, bitmap->buffer, stride * height);
1176 	    }
1177 
1178 	format = CAIRO_FORMAT_A8;
1179 	} else {
1180 	    /* if we get there, the  data from the source bitmap
1181 	     * really comes from _fill_xrender_bitmap, and is
1182 	     * made of 32-bit ARGB or ABGR values */
1183 	    assert (own_buffer != 0);
1184 	    assert (bitmap->pixel_mode != FT_PIXEL_MODE_GRAY);
1185 
1186 		data = bitmap->buffer;
1187 		stride = bitmap->pitch;
1188 		format = CAIRO_FORMAT_ARGB32;
1189 	}
1190 	break;
1191     case FT_PIXEL_MODE_GRAY2:
1192     case FT_PIXEL_MODE_GRAY4:
1193 	/* These could be triggered by very rare types of TrueType fonts */
1194     default:
1195 	if (own_buffer)
1196 	    free (bitmap->buffer);
1197 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1198     }
1199 
1200     /* XXX */
1201     *surface = image = (cairo_image_surface_t *)
1202 	cairo_image_surface_create_for_data (data,
1203 					     format,
1204 					     width, height, stride);
1205     if (image->base.status) {
1206 	free (data);
1207 	return (*surface)->base.status;
1208     }
1209 
1210     if (format == CAIRO_FORMAT_ARGB32)
1211 	pixman_image_set_component_alpha (image->pixman_image, TRUE);
1212 
1213     _cairo_image_surface_assume_ownership_of_data (image);
1214 
1215     _cairo_debug_check_image_surface_is_defined (&image->base);
1216 
1217     return CAIRO_STATUS_SUCCESS;
1218 }
1219 
1220 /* Converts an outline FT_GlyphSlot into an image
1221  *
1222  * This could go through _render_glyph_bitmap as well, letting
1223  * FreeType convert the outline to a bitmap, but doing it ourselves
1224  * has two minor advantages: first, we save a copy of the bitmap
1225  * buffer: we can directly use the buffer that FreeType renders
1226  * into.
1227  *
1228  * Second, it may help when we add support for subpixel
1229  * rendering: the Xft code does it this way. (Keith thinks that
1230  * it may also be possible to get the subpixel rendering with
1231  * FT_Render_Glyph: something worth looking into in more detail
1232  * when we add subpixel support. If so, we may want to eliminate
1233  * this version of the code path entirely.
1234  */
1235 static cairo_status_t
_render_glyph_outline(FT_Face face,cairo_font_options_t * font_options,cairo_image_surface_t ** surface)1236 _render_glyph_outline (FT_Face                    face,
1237 		       cairo_font_options_t	 *font_options,
1238 		       cairo_image_surface_t	**surface)
1239 {
1240     int rgba = FC_RGBA_UNKNOWN;
1241     int lcd_filter = FT_LCD_FILTER_LEGACY;
1242     FT_GlyphSlot glyphslot = face->glyph;
1243     FT_Outline *outline = &glyphslot->outline;
1244     FT_Bitmap bitmap;
1245     FT_BBox cbox;
1246     unsigned int width, height;
1247     cairo_status_t status;
1248     FT_Error fterror;
1249     FT_Library library = glyphslot->library;
1250     FT_Render_Mode render_mode = FT_RENDER_MODE_NORMAL;
1251 
1252     switch (font_options->antialias) {
1253     case CAIRO_ANTIALIAS_NONE:
1254 	render_mode = FT_RENDER_MODE_MONO;
1255 	break;
1256 
1257     case CAIRO_ANTIALIAS_SUBPIXEL:
1258 	switch (font_options->subpixel_order) {
1259 	    case CAIRO_SUBPIXEL_ORDER_DEFAULT:
1260 	    case CAIRO_SUBPIXEL_ORDER_RGB:
1261 	    case CAIRO_SUBPIXEL_ORDER_BGR:
1262 		render_mode = FT_RENDER_MODE_LCD;
1263 		break;
1264 
1265 	    case CAIRO_SUBPIXEL_ORDER_VRGB:
1266 	    case CAIRO_SUBPIXEL_ORDER_VBGR:
1267 		render_mode = FT_RENDER_MODE_LCD_V;
1268 		break;
1269 	}
1270 
1271 	switch (font_options->lcd_filter) {
1272 	case CAIRO_LCD_FILTER_NONE:
1273 	    lcd_filter = FT_LCD_FILTER_NONE;
1274 	    break;
1275 	case CAIRO_LCD_FILTER_DEFAULT:
1276 	case CAIRO_LCD_FILTER_INTRA_PIXEL:
1277 	    lcd_filter = FT_LCD_FILTER_LEGACY;
1278 	    break;
1279 	case CAIRO_LCD_FILTER_FIR3:
1280 	    lcd_filter = FT_LCD_FILTER_LIGHT;
1281 	    break;
1282 	case CAIRO_LCD_FILTER_FIR5:
1283 	    lcd_filter = FT_LCD_FILTER_DEFAULT;
1284 	    break;
1285 	}
1286 
1287 	break;
1288 
1289     case CAIRO_ANTIALIAS_DEFAULT:
1290     case CAIRO_ANTIALIAS_GRAY:
1291 	render_mode = FT_RENDER_MODE_NORMAL;
1292     }
1293 
1294     FT_Outline_Get_CBox (outline, &cbox);
1295 
1296     cbox.xMin &= -64;
1297     cbox.yMin &= -64;
1298     cbox.xMax = (cbox.xMax + 63) & -64;
1299     cbox.yMax = (cbox.yMax + 63) & -64;
1300 
1301     width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6);
1302     height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6);
1303 
1304     if (width * height == 0) {
1305 	cairo_format_t format;
1306 	/* Looks like fb handles zero-sized images just fine */
1307 	switch (render_mode) {
1308 	case FT_RENDER_MODE_MONO:
1309 	    format = CAIRO_FORMAT_A1;
1310 	    break;
1311 	case FT_RENDER_MODE_LCD:
1312 	case FT_RENDER_MODE_LCD_V:
1313 	    format= CAIRO_FORMAT_ARGB32;
1314 	    break;
1315 	case FT_RENDER_MODE_LIGHT:
1316 	case FT_RENDER_MODE_NORMAL:
1317 	case FT_RENDER_MODE_MAX:
1318 	default:
1319 	    format = CAIRO_FORMAT_A8;
1320 	    break;
1321 	}
1322 
1323 	(*surface) = (cairo_image_surface_t *)
1324 	    cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);
1325 	if ((*surface)->base.status)
1326 	    return (*surface)->base.status;
1327     } else {
1328 
1329 	int bitmap_size;
1330 
1331 	switch (render_mode) {
1332 	case FT_RENDER_MODE_LCD:
1333 	    if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_BGR) {
1334 		rgba = FC_RGBA_BGR;
1335 	    } else {
1336 		rgba = FC_RGBA_RGB;
1337 	    }
1338 	case FT_RENDER_MODE_LCD_V:
1339 	    if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_VBGR) {
1340 		rgba = FC_RGBA_VBGR;
1341 	    } else {
1342 		rgba = FC_RGBA_VRGB;
1343 		}
1344 	    break;
1345 	case FT_RENDER_MODE_MONO:
1346 	case FT_RENDER_MODE_LIGHT:
1347 	case FT_RENDER_MODE_NORMAL:
1348 	case FT_RENDER_MODE_MAX:
1349 	default:
1350 	    break;
1351 	    }
1352 
1353 #if HAVE_FT_LIBRARY_SETLCDFILTER
1354 	FT_Library_SetLcdFilter (library, lcd_filter);
1355 #endif
1356 
1357 	fterror = FT_Render_Glyph (face->glyph, render_mode);
1358 
1359 #if HAVE_FT_LIBRARY_SETLCDFILTER
1360 	FT_Library_SetLcdFilter (library, FT_LCD_FILTER_NONE);
1361 #endif
1362 
1363 	if (fterror != 0)
1364 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1365 
1366 	bitmap_size = _compute_xrender_bitmap_size (&bitmap,
1367 						    face->glyph,
1368 						    render_mode);
1369 	if (bitmap_size < 0)
1370 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1371 
1372 	bitmap.buffer = calloc (1, bitmap_size);
1373 	if (bitmap.buffer == NULL)
1374 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1375 
1376 	_fill_xrender_bitmap (&bitmap, face->glyph, render_mode,
1377 			      (rgba == FC_RGBA_BGR || rgba == FC_RGBA_VBGR));
1378 
1379 	/* Note:
1380 	 * _get_bitmap_surface will free bitmap.buffer if there is an error
1381 	 */
1382 	status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);
1383 	if (unlikely (status))
1384 	    return status;
1385 
1386 	/* Note: the font's coordinate system is upside down from ours, so the
1387 	 * Y coordinate of the control box needs to be negated.  Moreover, device
1388 	 * offsets are position of glyph origin relative to top left while xMin
1389 	 * and yMax are offsets of top left relative to origin.  Another negation.
1390 	 */
1391 	cairo_surface_set_device_offset (&(*surface)->base,
1392 					 (double)-glyphslot->bitmap_left,
1393 					 (double)+glyphslot->bitmap_top);
1394     }
1395 
1396     return CAIRO_STATUS_SUCCESS;
1397 }
1398 
1399 /* Converts a bitmap (or other) FT_GlyphSlot into an image */
1400 static cairo_status_t
_render_glyph_bitmap(FT_Face face,cairo_font_options_t * font_options,cairo_image_surface_t ** surface)1401 _render_glyph_bitmap (FT_Face		      face,
1402 		      cairo_font_options_t   *font_options,
1403 		      cairo_image_surface_t **surface)
1404 {
1405     FT_GlyphSlot glyphslot = face->glyph;
1406     cairo_status_t status;
1407     FT_Error error;
1408 
1409     /* According to the FreeType docs, glyphslot->format could be
1410      * something other than FT_GLYPH_FORMAT_OUTLINE or
1411      * FT_GLYPH_FORMAT_BITMAP. Calling FT_Render_Glyph gives FreeType
1412      * the opportunity to convert such to
1413      * bitmap. FT_GLYPH_FORMAT_COMPOSITE will not be encountered since
1414      * we avoid the FT_LOAD_NO_RECURSE flag.
1415      */
1416     error = FT_Render_Glyph (glyphslot, FT_RENDER_MODE_NORMAL);
1417     /* XXX ignoring all other errors for now.  They are not fatal, typically
1418      * just a glyph-not-found. */
1419     if (error == FT_Err_Out_Of_Memory)
1420 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1421 
1422     status = _get_bitmap_surface (&glyphslot->bitmap,
1423 				  FALSE, font_options,
1424 				  surface);
1425     if (unlikely (status))
1426 	return status;
1427 
1428     /*
1429      * Note: the font's coordinate system is upside down from ours, so the
1430      * Y coordinate of the control box needs to be negated.  Moreover, device
1431      * offsets are position of glyph origin relative to top left while
1432      * bitmap_left and bitmap_top are offsets of top left relative to origin.
1433      * Another negation.
1434      */
1435     cairo_surface_set_device_offset (&(*surface)->base,
1436 				     -glyphslot->bitmap_left,
1437 				     +glyphslot->bitmap_top);
1438 
1439     return CAIRO_STATUS_SUCCESS;
1440 }
1441 
1442 static cairo_status_t
_transform_glyph_bitmap(cairo_matrix_t * shape,cairo_image_surface_t ** surface)1443 _transform_glyph_bitmap (cairo_matrix_t         * shape,
1444 			 cairo_image_surface_t ** surface)
1445 {
1446     cairo_matrix_t original_to_transformed;
1447     cairo_matrix_t transformed_to_original;
1448     cairo_image_surface_t *old_image;
1449     cairo_surface_t *image;
1450     double x[4], y[4];
1451     double origin_x, origin_y;
1452     int orig_width, orig_height;
1453     int i;
1454     int x_min, y_min, x_max, y_max;
1455     int width, height;
1456     cairo_status_t status;
1457     cairo_surface_pattern_t pattern;
1458 
1459     /* We want to compute a transform that takes the origin
1460      * (device_x_offset, device_y_offset) to 0,0, then applies
1461      * the "shape" portion of the font transform
1462      */
1463     original_to_transformed = *shape;
1464 
1465     cairo_surface_get_device_offset (&(*surface)->base, &origin_x, &origin_y);
1466     orig_width = (*surface)->width;
1467     orig_height = (*surface)->height;
1468 
1469     cairo_matrix_translate (&original_to_transformed,
1470 			    -origin_x, -origin_y);
1471 
1472     /* Find the bounding box of the original bitmap under that
1473      * transform
1474      */
1475     x[0] = 0;          y[0] = 0;
1476     x[1] = orig_width; y[1] = 0;
1477     x[2] = orig_width; y[2] = orig_height;
1478     x[3] = 0;          y[3] = orig_height;
1479 
1480     for (i = 0; i < 4; i++)
1481       cairo_matrix_transform_point (&original_to_transformed,
1482 				    &x[i], &y[i]);
1483 
1484     x_min = floor (x[0]);   y_min = floor (y[0]);
1485     x_max =  ceil (x[0]);   y_max =  ceil (y[0]);
1486 
1487     for (i = 1; i < 4; i++) {
1488 	if (x[i] < x_min)
1489 	    x_min = floor (x[i]);
1490 	else if (x[i] > x_max)
1491 	    x_max = ceil (x[i]);
1492 	if (y[i] < y_min)
1493 	    y_min = floor (y[i]);
1494 	else if (y[i] > y_max)
1495 	    y_max = ceil (y[i]);
1496     }
1497 
1498     /* Adjust the transform so that the bounding box starts at 0,0 ...
1499      * this gives our final transform from original bitmap to transformed
1500      * bitmap.
1501      */
1502     original_to_transformed.x0 -= x_min;
1503     original_to_transformed.y0 -= y_min;
1504 
1505     /* Create the transformed bitmap */
1506     width  = x_max - x_min;
1507     height = y_max - y_min;
1508 
1509     transformed_to_original = original_to_transformed;
1510     status = cairo_matrix_invert (&transformed_to_original);
1511     if (unlikely (status))
1512 	return status;
1513 
1514     image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
1515     if (unlikely (image->status))
1516 	return image->status;
1517 
1518     /* Draw the original bitmap transformed into the new bitmap
1519      */
1520     _cairo_pattern_init_for_surface (&pattern, &(*surface)->base);
1521     cairo_pattern_set_matrix (&pattern.base, &transformed_to_original);
1522 
1523     status = _cairo_surface_paint (image,
1524 				   CAIRO_OPERATOR_SOURCE,
1525 				   &pattern.base,
1526 				   NULL);
1527 
1528     _cairo_pattern_fini (&pattern.base);
1529 
1530     if (unlikely (status)) {
1531 	cairo_surface_destroy (image);
1532 	return status;
1533     }
1534 
1535     /* Now update the cache entry for the new bitmap, recomputing
1536      * the origin based on the final transform.
1537      */
1538     cairo_matrix_transform_point (&original_to_transformed,
1539 				  &origin_x, &origin_y);
1540 
1541     old_image = (*surface);
1542     (*surface) = (cairo_image_surface_t *)image;
1543     cairo_surface_destroy (&old_image->base);
1544 
1545     cairo_surface_set_device_offset (&(*surface)->base,
1546 				     _cairo_lround (origin_x),
1547 				     _cairo_lround (origin_y));
1548     return CAIRO_STATUS_SUCCESS;
1549 }
1550 
1551 static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend = {
1552     _cairo_ft_unscaled_font_destroy,
1553 #if 0
1554     _cairo_ft_unscaled_font_create_glyph
1555 #endif
1556 };
1557 
1558 /* #cairo_ft_scaled_font_t */
1559 
1560 typedef struct _cairo_ft_scaled_font {
1561     cairo_scaled_font_t base;
1562     cairo_ft_unscaled_font_t *unscaled;
1563     cairo_ft_options_t ft_options;
1564 } cairo_ft_scaled_font_t;
1565 
1566 static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend;
1567 
1568 #if CAIRO_HAS_FC_FONT
1569 /* The load flags passed to FT_Load_Glyph control aspects like hinting and
1570  * antialiasing. Here we compute them from the fields of a FcPattern.
1571  */
1572 static void
_get_pattern_ft_options(FcPattern * pattern,cairo_ft_options_t * ret)1573 _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
1574 {
1575     FcBool antialias, vertical_layout, hinting, autohint, bitmap, embolden;
1576     cairo_ft_options_t ft_options;
1577     int rgba;
1578 #ifdef FC_HINT_STYLE
1579     int hintstyle;
1580 #endif
1581 
1582     _cairo_font_options_init_default (&ft_options.base);
1583     ft_options.load_flags = FT_LOAD_DEFAULT;
1584     ft_options.extra_flags = 0;
1585 
1586 #ifndef FC_EMBEDDED_BITMAP
1587 #define FC_EMBEDDED_BITMAP "embeddedbitmap"
1588 #endif
1589 
1590     /* Check whether to force use of embedded bitmaps */
1591     if (FcPatternGetBool (pattern,
1592 			  FC_EMBEDDED_BITMAP, 0, &bitmap) != FcResultMatch)
1593 	bitmap = FcFalse;
1594 
1595     /* disable antialiasing if requested */
1596     if (FcPatternGetBool (pattern,
1597 			  FC_ANTIALIAS, 0, &antialias) != FcResultMatch)
1598 	antialias = FcTrue;
1599 
1600     if (antialias) {
1601 	cairo_subpixel_order_t subpixel_order;
1602 	int lcd_filter;
1603 
1604 	/* disable hinting if requested */
1605 	if (FcPatternGetBool (pattern,
1606 			      FC_HINTING, 0, &hinting) != FcResultMatch)
1607 	    hinting = FcTrue;
1608 
1609 	if (FcPatternGetInteger (pattern,
1610 				 FC_RGBA, 0, &rgba) != FcResultMatch)
1611 	    rgba = FC_RGBA_UNKNOWN;
1612 
1613 	switch (rgba) {
1614 	case FC_RGBA_RGB:
1615 	    subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB;
1616 	    break;
1617 	case FC_RGBA_BGR:
1618 	    subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR;
1619 	    break;
1620 	case FC_RGBA_VRGB:
1621 	    subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB;
1622 	    break;
1623 	case FC_RGBA_VBGR:
1624 	    subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR;
1625 	    break;
1626 	case FC_RGBA_UNKNOWN:
1627 	case FC_RGBA_NONE:
1628 	default:
1629 	    subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
1630 	    break;
1631 	}
1632 
1633 	if (subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT) {
1634 	    ft_options.base.subpixel_order = subpixel_order;
1635 	    ft_options.base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;
1636 	}
1637 
1638 	if (FcPatternGetInteger (pattern,
1639 				 FC_LCD_FILTER, 0, &lcd_filter) == FcResultMatch)
1640 	{
1641 	    switch (lcd_filter) {
1642 	    case FC_LCD_NONE:
1643 		ft_options.base.lcd_filter = CAIRO_LCD_FILTER_NONE;
1644 		break;
1645 	    case FC_LCD_DEFAULT:
1646 		ft_options.base.lcd_filter = CAIRO_LCD_FILTER_FIR5;
1647 		break;
1648 	    case FC_LCD_LIGHT:
1649 		ft_options.base.lcd_filter = CAIRO_LCD_FILTER_FIR3;
1650 		break;
1651 	    case FC_LCD_LEGACY:
1652 		ft_options.base.lcd_filter = CAIRO_LCD_FILTER_INTRA_PIXEL;
1653 		break;
1654 	    }
1655 	}
1656 
1657 #ifdef FC_HINT_STYLE
1658 	if (FcPatternGetInteger (pattern,
1659 				 FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch)
1660 	    hintstyle = FC_HINT_FULL;
1661 
1662 	if (!hinting)
1663 	    hintstyle = FC_HINT_NONE;
1664 
1665 	switch (hintstyle) {
1666 	case FC_HINT_NONE:
1667 	    ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE;
1668 	    break;
1669 	case FC_HINT_SLIGHT:
1670 	    ft_options.base.hint_style = CAIRO_HINT_STYLE_SLIGHT;
1671 	    break;
1672 	case FC_HINT_MEDIUM:
1673 	default:
1674 	    ft_options.base.hint_style = CAIRO_HINT_STYLE_MEDIUM;
1675 	    break;
1676 	case FC_HINT_FULL:
1677 	    ft_options.base.hint_style = CAIRO_HINT_STYLE_FULL;
1678 	    break;
1679 	}
1680 #else /* !FC_HINT_STYLE */
1681 	if (!hinting) {
1682 	    ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE;
1683 	}
1684 #endif /* FC_HINT_STYLE */
1685 
1686 	/* Force embedded bitmaps off if no hinting requested */
1687 	if (ft_options.base.hint_style == CAIRO_HINT_STYLE_NONE)
1688 	  bitmap = FcFalse;
1689 
1690 	if (!bitmap)
1691 	    ft_options.load_flags |= FT_LOAD_NO_BITMAP;
1692 
1693     } else {
1694 	ft_options.base.antialias = CAIRO_ANTIALIAS_NONE;
1695     }
1696 
1697     /* force autohinting if requested */
1698     if (FcPatternGetBool (pattern,
1699 			  FC_AUTOHINT, 0, &autohint) != FcResultMatch)
1700 	autohint = FcFalse;
1701 
1702     if (autohint)
1703 	ft_options.load_flags |= FT_LOAD_FORCE_AUTOHINT;
1704 
1705     if (FcPatternGetBool (pattern,
1706 			  FC_VERTICAL_LAYOUT, 0, &vertical_layout) != FcResultMatch)
1707 	vertical_layout = FcFalse;
1708 
1709     if (vertical_layout)
1710 	ft_options.load_flags |= FT_LOAD_VERTICAL_LAYOUT;
1711 
1712 #ifndef FC_EMBOLDEN
1713 #define FC_EMBOLDEN "embolden"
1714 #endif
1715     if (FcPatternGetBool (pattern,
1716 			  FC_EMBOLDEN, 0, &embolden) != FcResultMatch)
1717 	embolden = FcFalse;
1718 
1719     if (embolden)
1720 	ft_options.extra_flags |= CAIRO_FT_OPTIONS_EMBOLDEN;
1721 
1722     *ret = ft_options;
1723 }
1724 #endif
1725 
1726 static void
_cairo_ft_options_merge(cairo_ft_options_t * options,cairo_ft_options_t * other)1727 _cairo_ft_options_merge (cairo_ft_options_t *options,
1728 			 cairo_ft_options_t *other)
1729 {
1730     int load_flags = other->load_flags;
1731     int load_target = FT_LOAD_TARGET_NORMAL;
1732 
1733     /* clear load target mode */
1734     load_flags &= ~(FT_LOAD_TARGET_(FT_LOAD_TARGET_MODE(other->load_flags)));
1735 
1736     if (load_flags & FT_LOAD_NO_HINTING)
1737 	other->base.hint_style = CAIRO_HINT_STYLE_NONE;
1738 
1739     if (other->base.antialias == CAIRO_ANTIALIAS_NONE ||
1740 	options->base.antialias == CAIRO_ANTIALIAS_NONE) {
1741 	options->base.antialias = CAIRO_ANTIALIAS_NONE;
1742 	options->base.subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
1743     }
1744 
1745     if (other->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL &&
1746 	(options->base.antialias == CAIRO_ANTIALIAS_DEFAULT ||
1747 	 options->base.antialias == CAIRO_ANTIALIAS_GRAY)) {
1748 	options->base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;
1749 	options->base.subpixel_order = other->base.subpixel_order;
1750     }
1751 
1752     if (options->base.hint_style == CAIRO_HINT_STYLE_DEFAULT)
1753 	options->base.hint_style = other->base.hint_style;
1754 
1755     if (other->base.hint_style == CAIRO_HINT_STYLE_NONE)
1756 	options->base.hint_style = CAIRO_HINT_STYLE_NONE;
1757 
1758     if (options->base.lcd_filter == CAIRO_LCD_FILTER_DEFAULT)
1759 	options->base.lcd_filter = other->base.lcd_filter;
1760 
1761     if (other->base.lcd_filter == CAIRO_LCD_FILTER_NONE)
1762 	options->base.lcd_filter = CAIRO_LCD_FILTER_NONE;
1763 
1764     if (options->base.antialias == CAIRO_ANTIALIAS_NONE) {
1765 	if (options->base.hint_style == CAIRO_HINT_STYLE_NONE)
1766 	    load_flags |= FT_LOAD_NO_HINTING;
1767 	else
1768 	    load_target = FT_LOAD_TARGET_MONO;
1769 	load_flags |= FT_LOAD_MONOCHROME;
1770     } else {
1771 	switch (options->base.hint_style) {
1772 	case CAIRO_HINT_STYLE_NONE:
1773 	    load_flags |= FT_LOAD_NO_HINTING;
1774 	    break;
1775 	case CAIRO_HINT_STYLE_SLIGHT:
1776 	    load_target = FT_LOAD_TARGET_LIGHT;
1777 	    break;
1778 	case CAIRO_HINT_STYLE_MEDIUM:
1779 	    break;
1780 	case CAIRO_HINT_STYLE_FULL:
1781 	case CAIRO_HINT_STYLE_DEFAULT:
1782 	    if (options->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL) {
1783 		switch (options->base.subpixel_order) {
1784 		case CAIRO_SUBPIXEL_ORDER_DEFAULT:
1785 		case CAIRO_SUBPIXEL_ORDER_RGB:
1786 		case CAIRO_SUBPIXEL_ORDER_BGR:
1787 		    load_target = FT_LOAD_TARGET_LCD;
1788 		    break;
1789 		case CAIRO_SUBPIXEL_ORDER_VRGB:
1790 		case CAIRO_SUBPIXEL_ORDER_VBGR:
1791 		    load_target = FT_LOAD_TARGET_LCD_V;
1792 		break;
1793 		}
1794 	    }
1795 	    break;
1796 	}
1797     }
1798 
1799     options->load_flags = load_flags | load_target;
1800     options->extra_flags = other->extra_flags;
1801     if (options->base.hint_metrics != CAIRO_HINT_METRICS_OFF)
1802 	options->extra_flags |= CAIRO_FT_OPTIONS_HINT_METRICS;
1803 }
1804 
1805 static cairo_status_t
_cairo_ft_font_face_scaled_font_create(void * abstract_font_face,const cairo_matrix_t * font_matrix,const cairo_matrix_t * ctm,const cairo_font_options_t * options,cairo_scaled_font_t ** font_out)1806 _cairo_ft_font_face_scaled_font_create (void		    *abstract_font_face,
1807 					const cairo_matrix_t	 *font_matrix,
1808 					const cairo_matrix_t	 *ctm,
1809 					const cairo_font_options_t *options,
1810 					cairo_scaled_font_t       **font_out)
1811 {
1812     cairo_ft_font_face_t *font_face = abstract_font_face;
1813     cairo_ft_scaled_font_t *scaled_font;
1814     FT_Face face;
1815     FT_Size_Metrics *metrics;
1816     cairo_font_extents_t fs_metrics;
1817     cairo_status_t status;
1818     cairo_ft_unscaled_font_t *unscaled;
1819 
1820     assert (font_face->unscaled);
1821 
1822     face = _cairo_ft_unscaled_font_lock_face (font_face->unscaled);
1823     if (unlikely (face == NULL)) /* backend error */
1824 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1825 
1826     scaled_font = malloc (sizeof (cairo_ft_scaled_font_t));
1827     if (unlikely (scaled_font == NULL)) {
1828 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1829 	goto FAIL;
1830     }
1831 
1832     scaled_font->unscaled = unscaled = font_face->unscaled;
1833     _cairo_unscaled_font_reference (&unscaled->base);
1834 
1835     _cairo_font_options_init_copy (&scaled_font->ft_options.base, options);
1836     _cairo_ft_options_merge (&scaled_font->ft_options, &font_face->ft_options);
1837 
1838     status = _cairo_scaled_font_init (&scaled_font->base,
1839 			              &font_face->base,
1840 				      font_matrix, ctm, options,
1841 				      &_cairo_ft_scaled_font_backend);
1842     if (unlikely (status))
1843 	goto CLEANUP_SCALED_FONT;
1844 
1845     status = _cairo_ft_unscaled_font_set_scale (unscaled,
1846 				                &scaled_font->base.scale);
1847     if (unlikely (status)) {
1848 	/* This can only fail if we encounter an error with the underlying
1849 	 * font, so propagate the error back to the font-face. */
1850 	_cairo_ft_unscaled_font_unlock_face (unscaled);
1851 	_cairo_unscaled_font_destroy (&unscaled->base);
1852 	free (scaled_font);
1853 	return status;
1854     }
1855 
1856 
1857     metrics = &face->size->metrics;
1858 
1859     /*
1860      * Get to unscaled metrics so that the upper level can get back to
1861      * user space
1862      *
1863      * Also use this path for bitmap-only fonts.  The other branch uses
1864      * face members that are only relevant for scalable fonts.  This is
1865      * detected by simply checking for units_per_EM==0.
1866      */
1867     if (scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF ||
1868 	face->units_per_EM == 0) {
1869 	double x_factor, y_factor;
1870 
1871 	if (unscaled->x_scale == 0)
1872 	    x_factor = 0;
1873 	else
1874 	    x_factor = 1 / unscaled->x_scale;
1875 
1876 	if (unscaled->y_scale == 0)
1877 	    y_factor = 0;
1878 	else
1879 	    y_factor = 1 / unscaled->y_scale;
1880 
1881 	fs_metrics.ascent =        DOUBLE_FROM_26_6(metrics->ascender) * y_factor;
1882 	fs_metrics.descent =       DOUBLE_FROM_26_6(- metrics->descender) * y_factor;
1883 	fs_metrics.height =        DOUBLE_FROM_26_6(metrics->height) * y_factor;
1884 	if (!_cairo_ft_scaled_font_is_vertical (&scaled_font->base)) {
1885 	    fs_metrics.max_x_advance = DOUBLE_FROM_26_6(metrics->max_advance) * x_factor;
1886 	    fs_metrics.max_y_advance = 0;
1887 	} else {
1888 	    fs_metrics.max_x_advance = 0;
1889 	    fs_metrics.max_y_advance = DOUBLE_FROM_26_6(metrics->max_advance) * y_factor;
1890 	}
1891     } else {
1892 	double scale = face->units_per_EM;
1893 
1894 	fs_metrics.ascent =        face->ascender / scale;
1895 	fs_metrics.descent =       - face->descender / scale;
1896 	fs_metrics.height =        face->height / scale;
1897 	if (!_cairo_ft_scaled_font_is_vertical (&scaled_font->base)) {
1898 	    fs_metrics.max_x_advance = face->max_advance_width / scale;
1899 	    fs_metrics.max_y_advance = 0;
1900 	} else {
1901 	    fs_metrics.max_x_advance = 0;
1902 	    fs_metrics.max_y_advance = face->max_advance_height / scale;
1903 	}
1904     }
1905 
1906     status = _cairo_scaled_font_set_metrics (&scaled_font->base, &fs_metrics);
1907     if (unlikely (status))
1908 	goto CLEANUP_SCALED_FONT;
1909 
1910     _cairo_ft_unscaled_font_unlock_face (unscaled);
1911 
1912     *font_out = &scaled_font->base;
1913     return CAIRO_STATUS_SUCCESS;
1914 
1915   CLEANUP_SCALED_FONT:
1916     _cairo_unscaled_font_destroy (&unscaled->base);
1917     free (scaled_font);
1918   FAIL:
1919     _cairo_ft_unscaled_font_unlock_face (font_face->unscaled);
1920     *font_out = _cairo_scaled_font_create_in_error (status);
1921     return CAIRO_STATUS_SUCCESS; /* non-backend error */
1922 }
1923 
1924 cairo_bool_t
_cairo_scaled_font_is_ft(cairo_scaled_font_t * scaled_font)1925 _cairo_scaled_font_is_ft (cairo_scaled_font_t *scaled_font)
1926 {
1927     return scaled_font->backend == &_cairo_ft_scaled_font_backend;
1928 }
1929 
1930 static void
_cairo_ft_scaled_font_fini(void * abstract_font)1931 _cairo_ft_scaled_font_fini (void *abstract_font)
1932 {
1933     cairo_ft_scaled_font_t *scaled_font = abstract_font;
1934 
1935     if (scaled_font == NULL)
1936         return;
1937 
1938     _cairo_unscaled_font_destroy (&scaled_font->unscaled->base);
1939 }
1940 
1941 static int
_move_to(FT_Vector * to,void * closure)1942 _move_to (FT_Vector *to, void *closure)
1943 {
1944     cairo_path_fixed_t *path = closure;
1945     cairo_fixed_t x, y;
1946 
1947     x = _cairo_fixed_from_26_6 (to->x);
1948     y = _cairo_fixed_from_26_6 (to->y);
1949 
1950     if (_cairo_path_fixed_close_path (path) != CAIRO_STATUS_SUCCESS)
1951 	return 1;
1952     if (_cairo_path_fixed_move_to (path, x, y) != CAIRO_STATUS_SUCCESS)
1953 	return 1;
1954 
1955     return 0;
1956 }
1957 
1958 static int
_line_to(FT_Vector * to,void * closure)1959 _line_to (FT_Vector *to, void *closure)
1960 {
1961     cairo_path_fixed_t *path = closure;
1962     cairo_fixed_t x, y;
1963 
1964     x = _cairo_fixed_from_26_6 (to->x);
1965     y = _cairo_fixed_from_26_6 (to->y);
1966 
1967     if (_cairo_path_fixed_line_to (path, x, y) != CAIRO_STATUS_SUCCESS)
1968 	return 1;
1969 
1970     return 0;
1971 }
1972 
1973 static int
_conic_to(FT_Vector * control,FT_Vector * to,void * closure)1974 _conic_to (FT_Vector *control, FT_Vector *to, void *closure)
1975 {
1976     cairo_path_fixed_t *path = closure;
1977 
1978     cairo_fixed_t x0, y0;
1979     cairo_fixed_t x1, y1;
1980     cairo_fixed_t x2, y2;
1981     cairo_fixed_t x3, y3;
1982     cairo_point_t conic;
1983 
1984     if (! _cairo_path_fixed_get_current_point (path, &x0, &y0))
1985 	return 1;
1986 
1987     conic.x = _cairo_fixed_from_26_6 (control->x);
1988     conic.y = _cairo_fixed_from_26_6 (control->y);
1989 
1990     x3 = _cairo_fixed_from_26_6 (to->x);
1991     y3 = _cairo_fixed_from_26_6 (to->y);
1992 
1993     x1 = x0 + 2.0/3.0 * (conic.x - x0);
1994     y1 = y0 + 2.0/3.0 * (conic.y - y0);
1995 
1996     x2 = x3 + 2.0/3.0 * (conic.x - x3);
1997     y2 = y3 + 2.0/3.0 * (conic.y - y3);
1998 
1999     if (_cairo_path_fixed_curve_to (path,
2000 				    x1, y1,
2001 				    x2, y2,
2002 				    x3, y3) != CAIRO_STATUS_SUCCESS)
2003 	return 1;
2004 
2005     return 0;
2006 }
2007 
2008 static int
_cubic_to(FT_Vector * control1,FT_Vector * control2,FT_Vector * to,void * closure)2009 _cubic_to (FT_Vector *control1, FT_Vector *control2,
2010 	   FT_Vector *to, void *closure)
2011 {
2012     cairo_path_fixed_t *path = closure;
2013     cairo_fixed_t x0, y0;
2014     cairo_fixed_t x1, y1;
2015     cairo_fixed_t x2, y2;
2016 
2017     x0 = _cairo_fixed_from_26_6 (control1->x);
2018     y0 = _cairo_fixed_from_26_6 (control1->y);
2019 
2020     x1 = _cairo_fixed_from_26_6 (control2->x);
2021     y1 = _cairo_fixed_from_26_6 (control2->y);
2022 
2023     x2 = _cairo_fixed_from_26_6 (to->x);
2024     y2 = _cairo_fixed_from_26_6 (to->y);
2025 
2026     if (_cairo_path_fixed_curve_to (path,
2027 				    x0, y0,
2028 				    x1, y1,
2029 				    x2, y2) != CAIRO_STATUS_SUCCESS)
2030 	return 1;
2031 
2032     return 0;
2033 }
2034 
2035 static cairo_status_t
_decompose_glyph_outline(FT_Face face,cairo_font_options_t * options,cairo_path_fixed_t ** pathp)2036 _decompose_glyph_outline (FT_Face		  face,
2037 			  cairo_font_options_t	 *options,
2038 			  cairo_path_fixed_t	**pathp)
2039 {
2040     static const FT_Outline_Funcs outline_funcs = {
2041 	(FT_Outline_MoveToFunc)_move_to,
2042 	(FT_Outline_LineToFunc)_line_to,
2043 	(FT_Outline_ConicToFunc)_conic_to,
2044 	(FT_Outline_CubicToFunc)_cubic_to,
2045 	0, /* shift */
2046 	0, /* delta */
2047     };
2048     static const FT_Matrix invert_y = {
2049 	DOUBLE_TO_16_16 (1.0), 0,
2050 	0, DOUBLE_TO_16_16 (-1.0),
2051     };
2052 
2053     FT_GlyphSlot glyph;
2054     cairo_path_fixed_t *path;
2055     cairo_status_t status;
2056 
2057     path = _cairo_path_fixed_create ();
2058     if (!path)
2059 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2060 
2061     glyph = face->glyph;
2062 
2063     /* Font glyphs have an inverted Y axis compared to cairo. */
2064     FT_Outline_Transform (&glyph->outline, &invert_y);
2065     if (FT_Outline_Decompose (&glyph->outline, &outline_funcs, path)) {
2066 	_cairo_path_fixed_destroy (path);
2067 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2068     }
2069 
2070     status = _cairo_path_fixed_close_path (path);
2071     if (unlikely (status)) {
2072 	_cairo_path_fixed_destroy (path);
2073 	return status;
2074     }
2075 
2076     *pathp = path;
2077 
2078     return CAIRO_STATUS_SUCCESS;
2079 }
2080 
2081 /*
2082  * Translate glyph to match its metrics.
2083  */
2084 static void
_cairo_ft_scaled_glyph_vertical_layout_bearing_fix(void * abstract_font,FT_GlyphSlot glyph)2085 _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (void        *abstract_font,
2086 						    FT_GlyphSlot glyph)
2087 {
2088     cairo_ft_scaled_font_t *scaled_font = abstract_font;
2089     FT_Vector vector;
2090 
2091     vector.x = glyph->metrics.vertBearingX - glyph->metrics.horiBearingX;
2092     vector.y = -glyph->metrics.vertBearingY - glyph->metrics.horiBearingY;
2093 
2094     if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
2095 	FT_Vector_Transform (&vector, &scaled_font->unscaled->Current_Shape);
2096 	FT_Outline_Translate(&glyph->outline, vector.x, vector.y);
2097     } else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
2098 	glyph->bitmap_left += vector.x / 64;
2099 	glyph->bitmap_top  += vector.y / 64;
2100     }
2101 }
2102 
2103 static cairo_int_status_t
_cairo_ft_scaled_glyph_init(void * abstract_font,cairo_scaled_glyph_t * scaled_glyph,cairo_scaled_glyph_info_t info)2104 _cairo_ft_scaled_glyph_init (void			*abstract_font,
2105 			     cairo_scaled_glyph_t	*scaled_glyph,
2106 			     cairo_scaled_glyph_info_t	 info)
2107 {
2108     cairo_text_extents_t    fs_metrics;
2109     cairo_ft_scaled_font_t *scaled_font = abstract_font;
2110     cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
2111     FT_GlyphSlot glyph;
2112     FT_Face face;
2113     FT_Error error;
2114     int load_flags = scaled_font->ft_options.load_flags;
2115     FT_Glyph_Metrics *metrics;
2116     double x_factor, y_factor;
2117     cairo_bool_t vertical_layout = FALSE;
2118     cairo_status_t status;
2119 
2120     face = _cairo_ft_unscaled_font_lock_face (unscaled);
2121     if (!face)
2122 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2123 
2124     status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
2125 				                &scaled_font->base.scale);
2126     if (unlikely (status))
2127 	goto FAIL;
2128 
2129     /* Ignore global advance unconditionally */
2130     load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
2131 
2132     if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0 &&
2133 	(info & CAIRO_SCALED_GLYPH_INFO_SURFACE) == 0)
2134 	load_flags |= FT_LOAD_NO_BITMAP;
2135 
2136     /*
2137      * Don't pass FT_LOAD_VERTICAL_LAYOUT to FT_Load_Glyph here as
2138      * suggested by freetype people.
2139      */
2140     if (load_flags & FT_LOAD_VERTICAL_LAYOUT) {
2141 	load_flags &= ~FT_LOAD_VERTICAL_LAYOUT;
2142 	vertical_layout = TRUE;
2143     }
2144 
2145     error = FT_Load_Glyph (scaled_font->unscaled->face,
2146 			   _cairo_scaled_glyph_index(scaled_glyph),
2147 			   load_flags);
2148     /* XXX ignoring all other errors for now.  They are not fatal, typically
2149      * just a glyph-not-found. */
2150     if (error == FT_Err_Out_Of_Memory) {
2151 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2152 	goto FAIL;
2153     }
2154 
2155     glyph = face->glyph;
2156 
2157 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
2158     /*
2159      * embolden glyphs if requested
2160      */
2161     if (scaled_font->ft_options.extra_flags & CAIRO_FT_OPTIONS_EMBOLDEN)
2162 	FT_GlyphSlot_Embolden (glyph);
2163 #endif
2164 
2165     if (vertical_layout)
2166 	_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, glyph);
2167 
2168     if (info & CAIRO_SCALED_GLYPH_INFO_METRICS) {
2169 
2170 	cairo_bool_t hint_metrics = scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF;
2171 	/*
2172 	 * Compute font-space metrics
2173 	 */
2174 	metrics = &glyph->metrics;
2175 
2176 	if (unscaled->x_scale == 0)
2177 	    x_factor = 0;
2178 	else
2179 	    x_factor = 1 / unscaled->x_scale;
2180 
2181 	if (unscaled->y_scale == 0)
2182 	    y_factor = 0;
2183 	else
2184 	    y_factor = 1 / unscaled->y_scale;
2185 
2186 	/*
2187 	 * Note: Y coordinates of the horizontal bearing need to be negated.
2188 	 *
2189 	 * Scale metrics back to glyph space from the scaled glyph space returned
2190 	 * by FreeType
2191 	 *
2192 	 * If we want hinted metrics but aren't asking for hinted glyphs from
2193 	 * FreeType, then we need to do the metric hinting ourselves.
2194 	 */
2195 
2196 	if (hint_metrics && (load_flags & FT_LOAD_NO_HINTING))
2197 	{
2198 	    FT_Pos x1, x2;
2199 	    FT_Pos y1, y2;
2200 	    FT_Pos advance;
2201 
2202 	    if (!vertical_layout) {
2203 		x1 = (metrics->horiBearingX) & -64;
2204 		x2 = (metrics->horiBearingX + metrics->width + 63) & -64;
2205 		y1 = (-metrics->horiBearingY) & -64;
2206 		y2 = (-metrics->horiBearingY + metrics->height + 63) & -64;
2207 
2208 		advance = ((metrics->horiAdvance + 32) & -64);
2209 
2210 		fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor;
2211 		fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor;
2212 
2213 		fs_metrics.width  = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;
2214 		fs_metrics.height  = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;
2215 
2216 		fs_metrics.x_advance = DOUBLE_FROM_26_6 (advance) * x_factor;
2217 		fs_metrics.y_advance = 0;
2218 	    } else {
2219 		x1 = (metrics->vertBearingX) & -64;
2220 		x2 = (metrics->vertBearingX + metrics->width + 63) & -64;
2221 		y1 = (metrics->vertBearingY) & -64;
2222 		y2 = (metrics->vertBearingY + metrics->height + 63) & -64;
2223 
2224 		advance = ((metrics->vertAdvance + 32) & -64);
2225 
2226 		fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor;
2227 		fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor;
2228 
2229 		fs_metrics.width  = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;
2230 		fs_metrics.height  = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;
2231 
2232 		fs_metrics.x_advance = 0;
2233 		fs_metrics.y_advance = DOUBLE_FROM_26_6 (advance) * y_factor;
2234 	    }
2235 	 } else {
2236 	    fs_metrics.width  = DOUBLE_FROM_26_6 (metrics->width) * x_factor;
2237 	    fs_metrics.height = DOUBLE_FROM_26_6 (metrics->height) * y_factor;
2238 
2239 	    if (!vertical_layout) {
2240 		fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) * x_factor;
2241 		fs_metrics.y_bearing = DOUBLE_FROM_26_6 (-metrics->horiBearingY) * y_factor;
2242 
2243 		if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE)
2244 		    fs_metrics.x_advance = DOUBLE_FROM_26_6 (metrics->horiAdvance) * x_factor;
2245 		else
2246 		    fs_metrics.x_advance = DOUBLE_FROM_16_16 (glyph->linearHoriAdvance) * x_factor;
2247 		fs_metrics.y_advance = 0 * y_factor;
2248 	    } else {
2249 		fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingX) * x_factor;
2250 		fs_metrics.y_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingY) * y_factor;
2251 
2252 		fs_metrics.x_advance = 0 * x_factor;
2253 		if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE)
2254 		    fs_metrics.y_advance = DOUBLE_FROM_26_6 (metrics->vertAdvance) * y_factor;
2255 		else
2256 		    fs_metrics.y_advance = DOUBLE_FROM_16_16 (glyph->linearVertAdvance) * y_factor;
2257 	    }
2258 	 }
2259 
2260 	_cairo_scaled_glyph_set_metrics (scaled_glyph,
2261 					 &scaled_font->base,
2262 					 &fs_metrics);
2263     }
2264 
2265     if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
2266 	cairo_image_surface_t	*surface;
2267 
2268 	if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
2269 	    status = _render_glyph_outline (face, &scaled_font->ft_options.base,
2270 					    &surface);
2271 	} else {
2272 	    status = _render_glyph_bitmap (face, &scaled_font->ft_options.base,
2273 					   &surface);
2274 	    if (likely (status == CAIRO_STATUS_SUCCESS) &&
2275 		unscaled->have_shape)
2276 	    {
2277 		status = _transform_glyph_bitmap (&unscaled->current_shape,
2278 						  &surface);
2279 		if (unlikely (status))
2280 		    cairo_surface_destroy (&surface->base);
2281 	    }
2282 	}
2283 	if (unlikely (status))
2284 	    goto FAIL;
2285 
2286 	_cairo_scaled_glyph_set_surface (scaled_glyph,
2287 					 &scaled_font->base,
2288 					 surface);
2289     }
2290 
2291     if (info & CAIRO_SCALED_GLYPH_INFO_PATH) {
2292 	cairo_path_fixed_t *path = NULL; /* hide compiler warning */
2293 
2294 	/*
2295 	 * A kludge -- the above code will trash the outline,
2296 	 * so reload it. This will probably never occur though
2297 	 */
2298 	if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
2299 	    error = FT_Load_Glyph (face,
2300 				   _cairo_scaled_glyph_index(scaled_glyph),
2301 				   load_flags | FT_LOAD_NO_BITMAP);
2302 	    /* XXX ignoring all other errors for now.  They are not fatal, typically
2303 	     * just a glyph-not-found. */
2304 	    if (error == FT_Err_Out_Of_Memory) {
2305 		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2306 		goto FAIL;
2307 	    }
2308 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
2309 	    /*
2310 	     * embolden glyphs if requested
2311 	     */
2312 	    if (scaled_font->ft_options.extra_flags & CAIRO_FT_OPTIONS_EMBOLDEN)
2313 		FT_GlyphSlot_Embolden (glyph);
2314 #endif
2315 	    if (vertical_layout)
2316 		_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, glyph);
2317 
2318 	}
2319 	if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
2320 	    status = _decompose_glyph_outline (face, &scaled_font->ft_options.base,
2321 					       &path);
2322 	else
2323 	    status = CAIRO_INT_STATUS_UNSUPPORTED;
2324 
2325 	if (unlikely (status))
2326 	    goto FAIL;
2327 
2328 	_cairo_scaled_glyph_set_path (scaled_glyph,
2329 				      &scaled_font->base,
2330 				      path);
2331     }
2332  FAIL:
2333     _cairo_ft_unscaled_font_unlock_face (unscaled);
2334 
2335     return status;
2336 }
2337 
2338 static unsigned long
_cairo_ft_ucs4_to_index(void * abstract_font,uint32_t ucs4)2339 _cairo_ft_ucs4_to_index (void	    *abstract_font,
2340 			 uint32_t    ucs4)
2341 {
2342     cairo_ft_scaled_font_t *scaled_font = abstract_font;
2343     cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
2344     FT_Face face;
2345     FT_UInt index;
2346 
2347     face = _cairo_ft_unscaled_font_lock_face (unscaled);
2348     if (!face)
2349 	return 0;
2350 
2351 #if CAIRO_HAS_FC_FONT
2352     index = FcFreeTypeCharIndex (face, ucs4);
2353 #else
2354     index = FT_Get_Char_Index (face, ucs4);
2355 #endif
2356 
2357     _cairo_ft_unscaled_font_unlock_face (unscaled);
2358     return index;
2359 }
2360 
2361 static cairo_int_status_t
_cairo_ft_load_truetype_table(void * abstract_font,unsigned long tag,long offset,unsigned char * buffer,unsigned long * length)2362 _cairo_ft_load_truetype_table (void	       *abstract_font,
2363                               unsigned long     tag,
2364                               long              offset,
2365                               unsigned char    *buffer,
2366                               unsigned long    *length)
2367 {
2368     cairo_ft_scaled_font_t *scaled_font = abstract_font;
2369     cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
2370     FT_Face face;
2371     cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
2372 
2373     if (_cairo_ft_scaled_font_is_vertical (&scaled_font->base))
2374         return CAIRO_INT_STATUS_UNSUPPORTED;
2375 
2376 #if HAVE_FT_LOAD_SFNT_TABLE
2377     face = _cairo_ft_unscaled_font_lock_face (unscaled);
2378     if (!face)
2379 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2380 
2381     if (FT_IS_SFNT (face) &&
2382 	FT_Load_Sfnt_Table (face, tag, offset, buffer, length) == 0)
2383         status = CAIRO_STATUS_SUCCESS;
2384 
2385     _cairo_ft_unscaled_font_unlock_face (unscaled);
2386 #endif
2387 
2388     return status;
2389 }
2390 
2391 static cairo_int_status_t
_cairo_ft_index_to_ucs4(void * abstract_font,unsigned long index,uint32_t * ucs4)2392 _cairo_ft_index_to_ucs4(void	        *abstract_font,
2393 			unsigned long    index,
2394 			uint32_t	*ucs4)
2395 {
2396     cairo_ft_scaled_font_t *scaled_font = abstract_font;
2397     cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
2398     FT_Face face;
2399     FT_ULong  charcode;
2400     FT_UInt   gindex;
2401 
2402     face = _cairo_ft_unscaled_font_lock_face (unscaled);
2403     if (!face)
2404 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2405 
2406     *ucs4 = (uint32_t) -1;
2407     charcode = FT_Get_First_Char(face, &gindex);
2408     while (gindex != 0) {
2409 	if (gindex == index) {
2410 	    *ucs4 = charcode;
2411 	    break;
2412 	}
2413 	charcode = FT_Get_Next_Char (face, charcode, &gindex);
2414     }
2415 
2416     _cairo_ft_unscaled_font_unlock_face (unscaled);
2417 
2418     return CAIRO_STATUS_SUCCESS;
2419 }
2420 
2421 static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend = {
2422     CAIRO_FONT_TYPE_FT,
2423     _cairo_ft_scaled_font_fini,
2424     _cairo_ft_scaled_glyph_init,
2425     NULL,			/* text_to_glyphs */
2426     _cairo_ft_ucs4_to_index,
2427     NULL,			/* show_glyphs */
2428     _cairo_ft_load_truetype_table,
2429     _cairo_ft_index_to_ucs4
2430 };
2431 
2432 /* #cairo_ft_font_face_t */
2433 
2434 #if CAIRO_HAS_FC_FONT
2435 static cairo_status_t
2436 _cairo_ft_font_face_create_for_pattern (FcPattern *pattern,
2437 					cairo_font_face_t **out);
2438 
2439 static cairo_status_t
_cairo_ft_font_face_create_for_toy(cairo_toy_font_face_t * toy_face,cairo_font_face_t ** font_face)2440 _cairo_ft_font_face_create_for_toy (cairo_toy_font_face_t   *toy_face,
2441 				    cairo_font_face_t      **font_face)
2442 {
2443     FcPattern *pattern;
2444     int fcslant;
2445     int fcweight;
2446     cairo_status_t status = CAIRO_STATUS_SUCCESS;
2447 
2448     pattern = FcPatternCreate ();
2449     if (!pattern)
2450 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2451 
2452     if (!FcPatternAddString (pattern,
2453 		             FC_FAMILY, (unsigned char *) toy_face->family))
2454     {
2455 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2456 	goto FREE_PATTERN;
2457     }
2458 
2459     switch (toy_face->slant)
2460     {
2461     case CAIRO_FONT_SLANT_ITALIC:
2462         fcslant = FC_SLANT_ITALIC;
2463         break;
2464     case CAIRO_FONT_SLANT_OBLIQUE:
2465 	fcslant = FC_SLANT_OBLIQUE;
2466         break;
2467     case CAIRO_FONT_SLANT_NORMAL:
2468     default:
2469         fcslant = FC_SLANT_ROMAN;
2470         break;
2471     }
2472 
2473     if (!FcPatternAddInteger (pattern, FC_SLANT, fcslant)) {
2474 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2475 	goto FREE_PATTERN;
2476     }
2477 
2478     switch (toy_face->weight)
2479     {
2480     case CAIRO_FONT_WEIGHT_BOLD:
2481         fcweight = FC_WEIGHT_BOLD;
2482         break;
2483     case CAIRO_FONT_WEIGHT_NORMAL:
2484     default:
2485         fcweight = FC_WEIGHT_MEDIUM;
2486         break;
2487     }
2488 
2489     if (!FcPatternAddInteger (pattern, FC_WEIGHT, fcweight)) {
2490 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2491 	goto FREE_PATTERN;
2492     }
2493 
2494     status = _cairo_ft_font_face_create_for_pattern (pattern, font_face);
2495 
2496  FREE_PATTERN:
2497     FcPatternDestroy (pattern);
2498 
2499     return status;
2500 }
2501 #endif
2502 
2503 static void
_cairo_ft_font_face_destroy(void * abstract_face)2504 _cairo_ft_font_face_destroy (void *abstract_face)
2505 {
2506     cairo_ft_font_face_t *font_face = abstract_face;
2507 
2508     /* When destroying a face created by cairo_ft_font_face_create_for_ft_face,
2509      * we have a special "zombie" state for the face when the unscaled font
2510      * is still alive but there are no other references to a font face with
2511      * the same FT_Face.
2512      *
2513      * We go from:
2514      *
2515      *   font_face ------> unscaled
2516      *        <-....weak....../
2517      *
2518      * To:
2519      *
2520      *    font_face <------- unscaled
2521      */
2522 
2523     if (font_face->unscaled &&
2524 	font_face->unscaled->from_face &&
2525 	font_face->next == NULL &&
2526 	font_face->unscaled->faces == font_face &&
2527 	CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1)
2528     {
2529 	cairo_font_face_reference (&font_face->base);
2530 
2531 	_cairo_unscaled_font_destroy (&font_face->unscaled->base);
2532 	font_face->unscaled = NULL;
2533 
2534 	return;
2535     }
2536 
2537     if (font_face->unscaled) {
2538 	cairo_ft_font_face_t *tmp_face = NULL;
2539 	cairo_ft_font_face_t *last_face = NULL;
2540 
2541 	/* Remove face from linked list */
2542 	for (tmp_face = font_face->unscaled->faces;
2543 	     tmp_face;
2544 	     tmp_face = tmp_face->next)
2545 	{
2546 	    if (tmp_face == font_face) {
2547 		if (last_face)
2548 		    last_face->next = tmp_face->next;
2549 		else
2550 		    font_face->unscaled->faces = tmp_face->next;
2551 	    }
2552 
2553 	    last_face = tmp_face;
2554 	}
2555 
2556 	_cairo_unscaled_font_destroy (&font_face->unscaled->base);
2557 	font_face->unscaled = NULL;
2558     }
2559 
2560 #if CAIRO_HAS_FC_FONT
2561     if (font_face->pattern) {
2562 	FcPatternDestroy (font_face->pattern);
2563 	cairo_font_face_destroy (font_face->resolved_font_face);
2564     }
2565 #endif
2566 }
2567 
2568 static cairo_font_face_t *
_cairo_ft_font_face_get_implementation(void * abstract_face,const cairo_matrix_t * font_matrix,const cairo_matrix_t * ctm,const cairo_font_options_t * options)2569 _cairo_ft_font_face_get_implementation (void                     *abstract_face,
2570 					const cairo_matrix_t       *font_matrix,
2571 					const cairo_matrix_t       *ctm,
2572 					const cairo_font_options_t *options)
2573 {
2574     cairo_ft_font_face_t      *font_face = abstract_face;
2575 
2576     /* The handling of font options is different depending on how the
2577      * font face was created. When the user creates a font face with
2578      * cairo_ft_font_face_create_for_ft_face(), then the load flags
2579      * passed in augment the load flags for the options.  But for
2580      * cairo_ft_font_face_create_for_pattern(), the load flags are
2581      * derived from a pattern where the user has called
2582      * cairo_ft_font_options_substitute(), so *just* use those load
2583      * flags and ignore the options.
2584      */
2585 
2586 #if CAIRO_HAS_FC_FONT
2587     /* If we have an unresolved pattern, resolve it and create
2588      * unscaled font.  Otherwise, use the ones stored in font_face.
2589      */
2590     if (font_face->pattern) {
2591 	cairo_font_face_t *resolved;
2592 
2593 	/* Cache the resolved font whilst the FcConfig remains consistent. */
2594 	resolved = font_face->resolved_font_face;
2595 	if (resolved != NULL) {
2596 	    if (! FcInitBringUptoDate ()) {
2597 		_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
2598 		return (cairo_font_face_t *) &_cairo_font_face_nil;
2599 	    }
2600 
2601 	    if (font_face->resolved_config == FcConfigGetCurrent ())
2602 		return cairo_font_face_reference (resolved);
2603 
2604 	    cairo_font_face_destroy (resolved);
2605 	    font_face->resolved_font_face = NULL;
2606 	}
2607 
2608 	resolved = _cairo_ft_resolve_pattern (font_face->pattern,
2609 					      font_matrix,
2610 					      ctm,
2611 					      options);
2612 	if (unlikely (resolved->status))
2613 	    return resolved;
2614 
2615 	font_face->resolved_font_face = cairo_font_face_reference (resolved);
2616 	font_face->resolved_config = FcConfigGetCurrent ();
2617 
2618 	return resolved;
2619     }
2620 #endif
2621 
2622     return abstract_face;
2623 }
2624 
2625 const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
2626     CAIRO_FONT_TYPE_FT,
2627 #if CAIRO_HAS_FC_FONT
2628     _cairo_ft_font_face_create_for_toy,
2629 #else
2630     NULL,
2631 #endif
2632     _cairo_ft_font_face_destroy,
2633     _cairo_ft_font_face_scaled_font_create,
2634     _cairo_ft_font_face_get_implementation
2635 };
2636 
2637 #if CAIRO_HAS_FC_FONT
2638 static cairo_status_t
_cairo_ft_font_face_create_for_pattern(FcPattern * pattern,cairo_font_face_t ** out)2639 _cairo_ft_font_face_create_for_pattern (FcPattern *pattern,
2640 					cairo_font_face_t **out)
2641 {
2642     cairo_ft_font_face_t *font_face;
2643 
2644     font_face = malloc (sizeof (cairo_ft_font_face_t));
2645     if (unlikely (font_face == NULL))
2646 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2647 
2648     font_face->unscaled = NULL;
2649     font_face->next = NULL;
2650 
2651     font_face->pattern = FcPatternDuplicate (pattern);
2652     if (unlikely (font_face->pattern == NULL)) {
2653 	free (font_face);
2654 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2655     }
2656 
2657     font_face->resolved_font_face = NULL;
2658     font_face->resolved_config = NULL;
2659 
2660     _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend);
2661 
2662     *out = &font_face->base;
2663     return CAIRO_STATUS_SUCCESS;
2664 }
2665 #endif
2666 
2667 static cairo_font_face_t *
_cairo_ft_font_face_create(cairo_ft_unscaled_font_t * unscaled,cairo_ft_options_t * ft_options)2668 _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
2669 			    cairo_ft_options_t	     *ft_options)
2670 {
2671     cairo_ft_font_face_t *font_face, **prev_font_face;
2672 
2673     /* Looked for an existing matching font face */
2674     for (font_face = unscaled->faces, prev_font_face = &unscaled->faces;
2675 	 font_face;
2676 	 prev_font_face = &font_face->next, font_face = font_face->next)
2677     {
2678 	if (font_face->ft_options.load_flags == ft_options->load_flags &&
2679 	    font_face->ft_options.extra_flags == ft_options->extra_flags &&
2680 	    cairo_font_options_equal (&font_face->ft_options.base, &ft_options->base))
2681 	{
2682 	    if (font_face->base.status) {
2683 		/* The font_face has been left in an error state, abandon it. */
2684 		*prev_font_face = font_face->next;
2685 		break;
2686 	    }
2687 
2688 	    if (font_face->unscaled == NULL) {
2689 		/* Resurrect this "zombie" font_face (from
2690 		 * _cairo_ft_font_face_destroy), switching its unscaled_font
2691 		 * from owner to ownee. */
2692 		font_face->unscaled = unscaled;
2693 		_cairo_unscaled_font_reference (&unscaled->base);
2694 		return &font_face->base;
2695 	    } else
2696 		return cairo_font_face_reference (&font_face->base);
2697 	}
2698     }
2699 
2700     /* No match found, create a new one */
2701     font_face = malloc (sizeof (cairo_ft_font_face_t));
2702     if (unlikely (!font_face)) {
2703 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
2704 	return (cairo_font_face_t *)&_cairo_font_face_nil;
2705     }
2706 
2707     font_face->unscaled = unscaled;
2708     _cairo_unscaled_font_reference (&unscaled->base);
2709 
2710     font_face->ft_options = *ft_options;
2711 
2712     if (unscaled->faces && unscaled->faces->unscaled == NULL) {
2713 	/* This "zombie" font_face (from _cairo_ft_font_face_destroy)
2714 	 * is no longer needed. */
2715 	assert (unscaled->from_face && unscaled->faces->next == NULL);
2716 	cairo_font_face_destroy (&unscaled->faces->base);
2717 	unscaled->faces = NULL;
2718     }
2719 
2720     font_face->next = unscaled->faces;
2721     unscaled->faces = font_face;
2722 
2723 #if CAIRO_HAS_FC_FONT
2724     font_face->pattern = NULL;
2725 #endif
2726 
2727     _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend);
2728 
2729     return &font_face->base;
2730 }
2731 
2732 /* implement the platform-specific interface */
2733 
2734 #if CAIRO_HAS_FC_FONT
2735 static cairo_status_t
_cairo_ft_font_options_substitute(const cairo_font_options_t * options,FcPattern * pattern)2736 _cairo_ft_font_options_substitute (const cairo_font_options_t *options,
2737 				   FcPattern                  *pattern)
2738 {
2739     FcValue v;
2740 
2741     if (options->antialias != CAIRO_ANTIALIAS_DEFAULT)
2742     {
2743 	if (FcPatternGet (pattern, FC_ANTIALIAS, 0, &v) == FcResultNoMatch)
2744 	{
2745 	    if (! FcPatternAddBool (pattern,
2746 			            FC_ANTIALIAS,
2747 				    options->antialias != CAIRO_ANTIALIAS_NONE))
2748 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2749 
2750 	    if (options->antialias != CAIRO_ANTIALIAS_SUBPIXEL) {
2751 		FcPatternDel (pattern, FC_RGBA);
2752 		if (! FcPatternAddInteger (pattern, FC_RGBA, FC_RGBA_NONE))
2753 		    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2754 	    }
2755 	}
2756     }
2757 
2758     if (options->antialias != CAIRO_ANTIALIAS_DEFAULT)
2759     {
2760 	if (FcPatternGet (pattern, FC_RGBA, 0, &v) == FcResultNoMatch)
2761 	{
2762 	    int rgba;
2763 
2764 	    if (options->antialias == CAIRO_ANTIALIAS_SUBPIXEL) {
2765 		switch (options->subpixel_order) {
2766 		case CAIRO_SUBPIXEL_ORDER_DEFAULT:
2767 		case CAIRO_SUBPIXEL_ORDER_RGB:
2768 		default:
2769 		    rgba = FC_RGBA_RGB;
2770 		    break;
2771 		case CAIRO_SUBPIXEL_ORDER_BGR:
2772 		    rgba = FC_RGBA_BGR;
2773 		    break;
2774 		case CAIRO_SUBPIXEL_ORDER_VRGB:
2775 		    rgba = FC_RGBA_VRGB;
2776 		    break;
2777 		case CAIRO_SUBPIXEL_ORDER_VBGR:
2778 		    rgba = FC_RGBA_VBGR;
2779 		    break;
2780 		}
2781 	    } else {
2782 		rgba = FC_RGBA_NONE;
2783 	    }
2784 
2785 	    if (! FcPatternAddInteger (pattern, FC_RGBA, rgba))
2786 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2787 	}
2788     }
2789 
2790     if (options->lcd_filter != CAIRO_LCD_FILTER_DEFAULT)
2791     {
2792 	if (FcPatternGet (pattern, FC_LCD_FILTER, 0, &v) == FcResultNoMatch)
2793 	{
2794 	    int lcd_filter;
2795 
2796 	    switch (options->lcd_filter) {
2797 	    case CAIRO_LCD_FILTER_NONE:
2798 		lcd_filter = FT_LCD_FILTER_NONE;
2799 		break;
2800 	    case CAIRO_LCD_FILTER_DEFAULT:
2801 	    case CAIRO_LCD_FILTER_INTRA_PIXEL:
2802 		lcd_filter = FT_LCD_FILTER_LEGACY;
2803 		break;
2804 	    case CAIRO_LCD_FILTER_FIR3:
2805 		lcd_filter = FT_LCD_FILTER_LIGHT;
2806 		break;
2807 	    default:
2808 	    case CAIRO_LCD_FILTER_FIR5:
2809 		lcd_filter = FT_LCD_FILTER_DEFAULT;
2810 		break;
2811 	    }
2812 
2813 	    if (! FcPatternAddInteger (pattern, FC_LCD_FILTER, lcd_filter))
2814 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2815 	}
2816     }
2817 
2818     if (options->hint_style != CAIRO_HINT_STYLE_DEFAULT)
2819     {
2820 	if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch)
2821 	{
2822 	    if (! FcPatternAddBool (pattern,
2823 			            FC_HINTING,
2824 				    options->hint_style != CAIRO_HINT_STYLE_NONE))
2825 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2826 	}
2827 
2828 #ifdef FC_HINT_STYLE
2829 	if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch)
2830 	{
2831 	    int hint_style;
2832 
2833 	    switch (options->hint_style) {
2834 	    case CAIRO_HINT_STYLE_NONE:
2835 		hint_style = FC_HINT_NONE;
2836 		break;
2837 	    case CAIRO_HINT_STYLE_SLIGHT:
2838 		hint_style = FC_HINT_SLIGHT;
2839 		break;
2840 	    case CAIRO_HINT_STYLE_MEDIUM:
2841 		hint_style = FC_HINT_MEDIUM;
2842 		break;
2843 	    case CAIRO_HINT_STYLE_FULL:
2844 	    case CAIRO_HINT_STYLE_DEFAULT:
2845 	    default:
2846 		hint_style = FC_HINT_FULL;
2847 		break;
2848 	    }
2849 
2850 	    if (! FcPatternAddInteger (pattern, FC_HINT_STYLE, hint_style))
2851 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2852 	}
2853 #endif
2854     }
2855 
2856     return CAIRO_STATUS_SUCCESS;
2857 }
2858 
2859 /**
2860  * cairo_ft_font_options_substitute:
2861  * @options: a #cairo_font_options_t object
2862  * @pattern: an existing #FcPattern
2863  *
2864  * Add options to a #FcPattern based on a #cairo_font_options_t font
2865  * options object. Options that are already in the pattern, are not overridden,
2866  * so you should call this function after calling FcConfigSubstitute() (the
2867  * user's settings should override options based on the surface type), but
2868  * before calling FcDefaultSubstitute().
2869  **/
2870 void
cairo_ft_font_options_substitute(const cairo_font_options_t * options,FcPattern * pattern)2871 cairo_ft_font_options_substitute (const cairo_font_options_t *options,
2872 				  FcPattern                  *pattern)
2873 {
2874     if (cairo_font_options_status ((cairo_font_options_t *) options))
2875 	return;
2876 
2877     _cairo_ft_font_options_substitute (options, pattern);
2878 }
2879 
2880 static cairo_font_face_t *
_cairo_ft_resolve_pattern(FcPattern * pattern,const cairo_matrix_t * font_matrix,const cairo_matrix_t * ctm,const cairo_font_options_t * font_options)2881 _cairo_ft_resolve_pattern (FcPattern		      *pattern,
2882 			   const cairo_matrix_t       *font_matrix,
2883 			   const cairo_matrix_t       *ctm,
2884 			   const cairo_font_options_t *font_options)
2885 {
2886     cairo_status_t status;
2887 
2888     cairo_matrix_t scale;
2889     FcPattern *resolved;
2890     cairo_ft_font_transform_t sf;
2891     FcResult result;
2892     cairo_ft_unscaled_font_t *unscaled;
2893     cairo_ft_options_t ft_options;
2894     cairo_font_face_t *font_face;
2895 
2896     scale = *ctm;
2897     scale.x0 = scale.y0 = 0;
2898     cairo_matrix_multiply (&scale,
2899                            font_matrix,
2900                            &scale);
2901 
2902     status = _compute_transform (&sf, &scale);
2903     if (unlikely (status))
2904 	return (cairo_font_face_t *)&_cairo_font_face_nil;
2905 
2906     pattern = FcPatternDuplicate (pattern);
2907     if (pattern == NULL)
2908 	return (cairo_font_face_t *)&_cairo_font_face_nil;
2909 
2910     if (! FcPatternAddDouble (pattern, FC_PIXEL_SIZE, sf.y_scale)) {
2911 	font_face = (cairo_font_face_t *)&_cairo_font_face_nil;
2912 	goto FREE_PATTERN;
2913     }
2914 
2915     if (! FcConfigSubstitute (NULL, pattern, FcMatchPattern)) {
2916 	font_face = (cairo_font_face_t *)&_cairo_font_face_nil;
2917 	goto FREE_PATTERN;
2918     }
2919 
2920     status = _cairo_ft_font_options_substitute (font_options, pattern);
2921     if (status) {
2922 	font_face = (cairo_font_face_t *)&_cairo_font_face_nil;
2923 	goto FREE_PATTERN;
2924     }
2925 
2926     FcDefaultSubstitute (pattern);
2927 
2928     resolved = FcFontMatch (NULL, pattern, &result);
2929     if (!resolved) {
2930 	/* We failed to find any font. Substitute twin so that the user can
2931 	 * see something (and hopefully recognise that the font is missing)
2932 	 * and not just receive a NO_MEMORY error during rendering.
2933 	 */
2934 	font_face = _cairo_font_face_twin_create_fallback ();
2935 	goto FREE_PATTERN;
2936     }
2937 
2938     status = _cairo_ft_unscaled_font_create_for_pattern (resolved, &unscaled);
2939     if (unlikely (status || unscaled == NULL)) {
2940 	font_face = (cairo_font_face_t *)&_cairo_font_face_nil;
2941 	goto FREE_RESOLVED;
2942     }
2943 
2944     _get_pattern_ft_options (resolved, &ft_options);
2945     font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
2946     _cairo_unscaled_font_destroy (&unscaled->base);
2947 
2948 FREE_RESOLVED:
2949     FcPatternDestroy (resolved);
2950 
2951 FREE_PATTERN:
2952     FcPatternDestroy (pattern);
2953 
2954     return font_face;
2955 }
2956 
2957 /**
2958  * cairo_ft_font_face_create_for_pattern:
2959  * @pattern: A fontconfig pattern.  Cairo makes a copy of the pattern
2960  * if it needs to.  You are free to modify or free @pattern after this call.
2961  *
2962  * Creates a new font face for the FreeType font backend based on a
2963  * fontconfig pattern. This font can then be used with
2964  * cairo_set_font_face() or cairo_scaled_font_create(). The
2965  * #cairo_scaled_font_t returned from cairo_scaled_font_create() is
2966  * also for the FreeType backend and can be used with functions such
2967  * as cairo_ft_scaled_font_lock_face().
2968  *
2969  * Font rendering options are represented both here and when you
2970  * call cairo_scaled_font_create(). Font options that have a representation
2971  * in a #FcPattern must be passed in here; to modify #FcPattern
2972  * appropriately to reflect the options in a #cairo_font_options_t, call
2973  * cairo_ft_font_options_substitute().
2974  *
2975  * The pattern's FC_FT_FACE element is inspected first and if that is set,
2976  * that will be the FreeType font face associated with the returned cairo
2977  * font face.  Otherwise the FC_FILE element is checked.  If it's set,
2978  * that and the value of the FC_INDEX element (defaults to zero) of @pattern
2979  * are used to load a font face from file.
2980  *
2981  * If both steps from the previous paragraph fails, @pattern will be passed
2982  * to FcConfigSubstitute, FcDefaultSubstitute, and finally FcFontMatch,
2983  * and the resulting font pattern is used.
2984  *
2985  * If the FC_FT_FACE element of @pattern is set, the user is responsible
2986  * for making sure that the referenced FT_Face remains valid for the life
2987  * time of the returned #cairo_font_face_t.  See
2988  * cairo_ft_font_face_create_for_ft_face() for an exmaple of how to couple
2989  * the life time of the FT_Face to that of the cairo font-face.
2990  *
2991  * Return value: a newly created #cairo_font_face_t. Free with
2992  *  cairo_font_face_destroy() when you are done using it.
2993  **/
2994 cairo_font_face_t *
cairo_ft_font_face_create_for_pattern(FcPattern * pattern)2995 cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
2996 {
2997     cairo_ft_unscaled_font_t *unscaled;
2998     cairo_font_face_t *font_face;
2999     cairo_ft_options_t ft_options;
3000     cairo_status_t status;
3001 
3002     status = _cairo_ft_unscaled_font_create_for_pattern (pattern, &unscaled);
3003     if (unlikely (status))
3004 	return (cairo_font_face_t *) &_cairo_font_face_nil;
3005     if (unlikely (unscaled == NULL)) {
3006 	/* Store the pattern.  We will resolve it and create unscaled
3007 	 * font when creating scaled fonts */
3008 	status = _cairo_ft_font_face_create_for_pattern (pattern,
3009 							 &font_face);
3010 	if (unlikely (status))
3011 	    return (cairo_font_face_t *) &_cairo_font_face_nil;
3012 
3013 	return font_face;
3014     }
3015 
3016     _get_pattern_ft_options (pattern, &ft_options);
3017     font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
3018     _cairo_unscaled_font_destroy (&unscaled->base);
3019 
3020     return font_face;
3021 }
3022 #endif
3023 
3024 /**
3025  * cairo_ft_font_face_create_for_ft_face:
3026  * @face: A FreeType face object, already opened. This must
3027  *   be kept around until the face's ref_count drops to
3028  *   zero and it is freed. Since the face may be referenced
3029  *   internally to Cairo, the best way to determine when it
3030  *   is safe to free the face is to pass a
3031  *   #cairo_destroy_func_t to cairo_font_face_set_user_data()
3032  * @load_flags: flags to pass to FT_Load_Glyph when loading
3033  *   glyphs from the font. These flags are OR'ed together with
3034  *   the flags derived from the #cairo_font_options_t passed
3035  *   to cairo_scaled_font_create(), so only a few values such
3036  *   as %FT_LOAD_VERTICAL_LAYOUT, and %FT_LOAD_FORCE_AUTOHINT
3037  *   are useful. You should not pass any of the flags affecting
3038  *   the load target, such as %FT_LOAD_TARGET_LIGHT.
3039  *
3040  * Creates a new font face for the FreeType font backend from a
3041  * pre-opened FreeType face. This font can then be used with
3042  * cairo_set_font_face() or cairo_scaled_font_create(). The
3043  * #cairo_scaled_font_t returned from cairo_scaled_font_create() is
3044  * also for the FreeType backend and can be used with functions such
3045  * as cairo_ft_scaled_font_lock_face(). Note that Cairo may keep a reference
3046  * to the FT_Face alive in a font-cache and the exact lifetime of the reference
3047  * depends highly upon the exact usage pattern and is subject to external
3048  * factors. You must not call FT_Done_Face() before the last reference to the
3049  * #cairo_font_face_t has been dropped.
3050  *
3051  * As an example, below is how one might correctly couple the lifetime of
3052  * the FreeType face object to the #cairo_font_face_t.
3053  *
3054  * <informalexample><programlisting>
3055  * static const cairo_user_data_key_t key;
3056  *
3057  * font_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
3058  * status = cairo_font_face_set_user_data (font_face, &key,
3059  *                                ft_face, (cairo_destroy_func_t) FT_Done_Face);
3060  * if (status) {
3061  *    cairo_font_face_destroy (font_face);
3062  *    FT_Done_Face (ft_face);
3063  *    return ERROR;
3064  * }
3065  * </programlisting></informalexample>
3066  *
3067  * Return value: a newly created #cairo_font_face_t. Free with
3068  *  cairo_font_face_destroy() when you are done using it.
3069  **/
3070 cairo_font_face_t *
cairo_ft_font_face_create_for_ft_face(FT_Face face,int load_flags)3071 cairo_ft_font_face_create_for_ft_face (FT_Face         face,
3072 				       int             load_flags)
3073 {
3074     cairo_ft_unscaled_font_t *unscaled;
3075     cairo_font_face_t *font_face;
3076     cairo_ft_options_t ft_options;
3077     cairo_status_t status;
3078 
3079     status = _cairo_ft_unscaled_font_create_from_face (face, &unscaled);
3080     if (unlikely (status))
3081 	return (cairo_font_face_t *)&_cairo_font_face_nil;
3082 
3083     ft_options.load_flags = load_flags;
3084     ft_options.extra_flags = 0;
3085     _cairo_font_options_init_default (&ft_options.base);
3086 
3087     font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
3088     _cairo_unscaled_font_destroy (&unscaled->base);
3089 
3090     return font_face;
3091 }
3092 
3093 /**
3094  * cairo_ft_scaled_font_lock_face:
3095  * @scaled_font: A #cairo_scaled_font_t from the FreeType font backend. Such an
3096  *   object can be created by calling cairo_scaled_font_create() on a
3097  *   FreeType backend font face (see cairo_ft_font_face_create_for_pattern(),
3098  *   cairo_ft_font_face_create_for_ft_face()).
3099  *
3100  * cairo_ft_scaled_font_lock_face() gets the #FT_Face object from a FreeType
3101  * backend font and scales it appropriately for the font. You must
3102  * release the face with cairo_ft_scaled_font_unlock_face()
3103  * when you are done using it.  Since the #FT_Face object can be
3104  * shared between multiple #cairo_scaled_font_t objects, you must not
3105  * lock any other font objects until you unlock this one. A count is
3106  * kept of the number of times cairo_ft_scaled_font_lock_face() is
3107  * called. cairo_ft_scaled_font_unlock_face() must be called the same number
3108  * of times.
3109  *
3110  * You must be careful when using this function in a library or in a
3111  * threaded application, because freetype's design makes it unsafe to
3112  * call freetype functions simultaneously from multiple threads, (even
3113  * if using distinct FT_Face objects). Because of this, application
3114  * code that acquires an FT_Face object with this call must add its
3115  * own locking to protect any use of that object, (and which also must
3116  * protect any other calls into cairo as almost any cairo function
3117  * might result in a call into the freetype library).
3118  *
3119  * Return value: The #FT_Face object for @font, scaled appropriately,
3120  * or %NULL if @scaled_font is in an error state (see
3121  * cairo_scaled_font_status()) or there is insufficient memory.
3122  **/
3123 FT_Face
cairo_ft_scaled_font_lock_face(cairo_scaled_font_t * abstract_font)3124 cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font)
3125 {
3126     cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
3127     FT_Face face;
3128     cairo_status_t status;
3129 
3130     if (! _cairo_scaled_font_is_ft (abstract_font)) {
3131 	_cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH);
3132 	return NULL;
3133     }
3134 
3135     if (scaled_font->base.status)
3136 	return NULL;
3137 
3138     face = _cairo_ft_unscaled_font_lock_face (scaled_font->unscaled);
3139     if (unlikely (face == NULL)) {
3140 	status = _cairo_scaled_font_set_error (&scaled_font->base, CAIRO_STATUS_NO_MEMORY);
3141 	return NULL;
3142     }
3143 
3144     status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
3145 				                &scaled_font->base.scale);
3146     if (unlikely (status)) {
3147 	_cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
3148 	status = _cairo_scaled_font_set_error (&scaled_font->base, status);
3149 	return NULL;
3150     }
3151 
3152     /* Note: We deliberately release the unscaled font's mutex here,
3153      * so that we are not holding a lock across two separate calls to
3154      * cairo function, (which would give the application some
3155      * opportunity for creating deadlock. This is obviously unsafe,
3156      * but as documented, the user must add manual locking when using
3157      * this function. */
3158      CAIRO_MUTEX_UNLOCK (scaled_font->unscaled->mutex);
3159 
3160     return face;
3161 }
3162 
3163 /**
3164  * cairo_ft_scaled_font_unlock_face:
3165  * @scaled_font: A #cairo_scaled_font_t from the FreeType font backend. Such an
3166  *   object can be created by calling cairo_scaled_font_create() on a
3167  *   FreeType backend font face (see cairo_ft_font_face_create_for_pattern(),
3168  *   cairo_ft_font_face_create_for_ft_face()).
3169  *
3170  * Releases a face obtained with cairo_ft_scaled_font_lock_face().
3171  **/
3172 void
cairo_ft_scaled_font_unlock_face(cairo_scaled_font_t * abstract_font)3173 cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t *abstract_font)
3174 {
3175     cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
3176 
3177     if (! _cairo_scaled_font_is_ft (abstract_font)) {
3178 	_cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH);
3179 	return;
3180     }
3181 
3182     if (scaled_font->base.status)
3183 	return;
3184 
3185     /* Note: We released the unscaled font's mutex at the end of
3186      * cairo_ft_scaled_font_lock_face, so we have to acquire it again
3187      * as _cairo_ft_unscaled_font_unlock_face expects it to be held
3188      * when we call into it. */
3189     CAIRO_MUTEX_LOCK (scaled_font->unscaled->mutex);
3190 
3191     _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
3192 }
3193 
3194 /* We expose our unscaled font implementation internally for the the
3195  * PDF backend, which needs to keep track of the the different
3196  * fonts-on-disk used by a document, so it can embed them.
3197  */
3198 cairo_unscaled_font_t *
_cairo_ft_scaled_font_get_unscaled_font(cairo_scaled_font_t * abstract_font)3199 _cairo_ft_scaled_font_get_unscaled_font (cairo_scaled_font_t *abstract_font)
3200 {
3201     cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
3202 
3203     return &scaled_font->unscaled->base;
3204 }
3205 
3206 cairo_bool_t
_cairo_ft_scaled_font_is_vertical(cairo_scaled_font_t * scaled_font)3207 _cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font)
3208 {
3209     cairo_ft_scaled_font_t *ft_scaled_font;
3210 
3211     if (!_cairo_scaled_font_is_ft (scaled_font))
3212 	return FALSE;
3213 
3214     ft_scaled_font = (cairo_ft_scaled_font_t *) scaled_font;
3215     if (ft_scaled_font->ft_options.load_flags & FT_LOAD_VERTICAL_LAYOUT)
3216 	return TRUE;
3217     return FALSE;
3218 }
3219 
3220 unsigned int
_cairo_ft_scaled_font_get_load_flags(cairo_scaled_font_t * scaled_font)3221 _cairo_ft_scaled_font_get_load_flags (cairo_scaled_font_t *scaled_font)
3222 {
3223     cairo_ft_scaled_font_t *ft_scaled_font;
3224 
3225     if (! _cairo_scaled_font_is_ft (scaled_font))
3226 	return 0;
3227 
3228     ft_scaled_font = (cairo_ft_scaled_font_t *) scaled_font;
3229     return ft_scaled_font->ft_options.load_flags;
3230 }
3231 
3232 void
_cairo_ft_font_reset_static_data(void)3233 _cairo_ft_font_reset_static_data (void)
3234 {
3235     _cairo_ft_unscaled_font_map_destroy ();
3236 }
3237