Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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