Back to index

lightning-sunbird  0.9+nobinonly
cairo-ft-font.c
Go to the documentation of this file.
00001 /* cairo - a vector graphics library with display and print output
00002  *
00003  * Copyright © 2000 Keith Packard
00004  * Copyright © 2005 Red Hat, Inc
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it either under the terms of the GNU Lesser General Public
00008  * License version 2.1 as published by the Free Software Foundation
00009  * (the "LGPL") or, at your option, under the terms of the Mozilla
00010  * Public License Version 1.1 (the "MPL"). If you do not alter this
00011  * notice, a recipient may use your version of this file under either
00012  * the MPL or the LGPL.
00013  *
00014  * You should have received a copy of the LGPL along with this library
00015  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00017  * You should have received a copy of the MPL along with this library
00018  * in the file COPYING-MPL-1.1
00019  *
00020  * The contents of this file are subject to the Mozilla Public License
00021  * Version 1.1 (the "License"); you may not use this file except in
00022  * compliance with the License. You may obtain a copy of the License at
00023  * http://www.mozilla.org/MPL/
00024  *
00025  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
00026  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
00027  * the specific language governing rights and limitations.
00028  *
00029  * The Original Code is the cairo graphics library.
00030  *
00031  * The Initial Developer of the Original Code is Red Hat, Inc.
00032  *
00033  * Contributor(s):
00034  *      Graydon Hoare <graydon@redhat.com>
00035  *     Owen Taylor <otaylor@redhat.com>
00036  *      Keith Packard <keithp@keithp.com>
00037  *      Carl Worth <cworth@cworth.org>
00038  */
00039 
00040 #include <float.h>
00041 
00042 #include "cairo-ft-private.h"
00043 
00044 #include <fontconfig/fontconfig.h>
00045 #include <fontconfig/fcfreetype.h>
00046 
00047 #include <ft2build.h>
00048 #include FT_FREETYPE_H
00049 #include FT_OUTLINE_H
00050 #include FT_IMAGE_H
00051 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
00052 #include FT_SYNTHESIS_H
00053 #endif
00054 
00055 #define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
00056 #define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
00057 #define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
00058 #define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0)
00059 
00060 /* We pack some of our own information into the bits unused
00061  * by FreeType's load flags. If FreeType ever uses up all
00062  * the load flag bits, we'll have to do something else.
00063  * (probably just store what we care about in load_flags
00064  * then convert into FreeType terms.
00065  */
00066 #define PRIVATE_FLAG_HINT_METRICS (0x01 << 24)
00067 #define PRIVATE_FLAG_EMBOLDEN     (0x02 << 24)
00068 #define PRIVATE_FLAGS_MASK        (0xff << 24)
00069 
00070  /* This is the max number of FT_face objects we keep open at once
00071   */
00072  #define MAX_OPEN_FACES 10
00073 
00074 /* This is the max number of FT_face objects we keep open at once
00075  */
00076 #define MAX_OPEN_FACES 10
00077 
00078 /* This is the maximum font size we allow to be passed to FT_Set_Char_Size
00079  */
00080 #define MAX_FONT_SIZE 1000
00081 
00082 /*
00083  * The simple 2x2 matrix is converted into separate scale and shape
00084  * factors so that hinting works right
00085  */
00086 
00087 typedef struct _cairo_ft_font_transform {
00088     double  x_scale, y_scale;
00089     double  shape[2][2];
00090 } cairo_ft_font_transform_t;
00091 
00092 /* 
00093  * We create an object that corresponds to a single font on the disk;
00094  * (identified by a filename/id pair) these are shared between all
00095  * fonts using that file.  For cairo_ft_font_face_create_for_ft_face(), we
00096  * just create a one-off version with a permanent face value.
00097  */
00098 
00099 typedef struct _cairo_ft_font_face cairo_ft_font_face_t;
00100 
00101 struct _cairo_ft_unscaled_font {
00102     cairo_unscaled_font_t base;
00103 
00104     cairo_bool_t from_face; /* from cairo_ft_font_face_create_for_ft_face()? */
00105     FT_Face face;        /* provided or cached face */
00106 
00107     /* only set if from_face is false */
00108     char *filename;
00109     int id;
00110 
00111     /* We temporarily scale the unscaled font as needed */
00112     cairo_bool_t have_scale;
00113     cairo_matrix_t current_scale;
00114     double x_scale;         /* Extracted X scale factor */
00115     double y_scale;             /* Extracted Y scale factor */
00116     cairo_bool_t have_shape;       /* true if the current scale has a non-scale component*/
00117     
00118     int lock;        /* count of how many times this font has been locked */
00119 
00120     cairo_ft_font_face_t *faces;   /* Linked list of faces for this font */
00121 };
00122 
00123 static int
00124 _cairo_ft_unscaled_font_keys_equal (void *key_a,
00125                                 void *key_b);
00126 
00127 static void
00128 _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled);
00129 
00130 struct _cairo_ft_font_face {
00131     cairo_font_face_t base;
00132     cairo_ft_unscaled_font_t *unscaled;
00133     int load_flags;
00134     cairo_ft_font_face_t *next;
00135 };
00136 
00137 static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend;
00138 
00139 /*
00140  * We maintain a hash table to map file/id => cairo_ft_unscaled_font_t.
00141  * The hash table itself isn't limited in size. However, we limit the
00142  * number of FT_Face objects we keep around; when we've exceeeded that
00143  * limit and need to create a new FT_Face, we dump the FT_Face from a
00144  * random cairo_ft_unscaled_font_t which has an unlocked FT_Face, (if
00145  * there are any).
00146  */
00147 
00148 typedef struct _cairo_ft_unscaled_font_map {
00149     cairo_hash_table_t *hash_table;
00150     FT_Library ft_library;
00151     int num_open_faces;
00152 } cairo_ft_unscaled_font_map_t;
00153 
00154 static cairo_ft_unscaled_font_map_t *cairo_ft_unscaled_font_map = NULL;
00155 
00156 CAIRO_MUTEX_DECLARE(cairo_ft_unscaled_font_map_mutex);
00157 
00158 static void
00159 _font_map_release_face_lock_held (cairo_ft_unscaled_font_map_t *font_map,
00160                               cairo_ft_unscaled_font_t *unscaled)
00161 {
00162     if (unscaled->face) {
00163        FT_Done_Face (unscaled->face);
00164        unscaled->face = NULL;
00165        unscaled->have_scale = FALSE;
00166 
00167        font_map->num_open_faces--;
00168     }
00169 }
00170 
00171 static void
00172 _cairo_ft_unscaled_font_map_create (void)
00173 {
00174     cairo_ft_unscaled_font_map_t *font_map;
00175 
00176     /* This function is only intended to be called from
00177      * _cairo_ft_unscaled_font_map_lock. So we'll crash if we can
00178      * detect some other call path. */
00179     assert (cairo_ft_unscaled_font_map == NULL);
00180 
00181     font_map = malloc (sizeof (cairo_ft_unscaled_font_map_t));
00182     if (font_map == NULL)
00183        goto FAIL;
00184 
00185     font_map->hash_table =
00186        _cairo_hash_table_create (_cairo_ft_unscaled_font_keys_equal);
00187 
00188     if (font_map->hash_table == NULL)
00189        goto FAIL;
00190 
00191     if (FT_Init_FreeType (&font_map->ft_library))
00192        goto FAIL;
00193 
00194     font_map->num_open_faces = 0;
00195 
00196     cairo_ft_unscaled_font_map = font_map;
00197     return;
00198 
00199 FAIL:
00200     if (font_map) {
00201        if (font_map->hash_table)
00202            _cairo_hash_table_destroy (font_map->hash_table);
00203        free (font_map);
00204     }
00205     cairo_ft_unscaled_font_map = NULL;
00206 }
00207 
00208 static void
00209 _cairo_ft_unscaled_font_map_destroy (void)
00210 {
00211     cairo_ft_unscaled_font_t *unscaled;
00212     cairo_ft_unscaled_font_map_t *font_map;
00213 
00214     CAIRO_MUTEX_LOCK (cairo_ft_unscaled_font_map_mutex);
00215 
00216     if (cairo_ft_unscaled_font_map) {
00217        font_map = cairo_ft_unscaled_font_map;
00218 
00219        /* This is rather inefficient, but destroying the hash table
00220         * is something we only do during debugging, (during
00221         * cairo_debug_reset_static_data), when efficiency is not
00222         * relevant. */
00223         while (1) {
00224            unscaled = _cairo_hash_table_random_entry (font_map->hash_table,
00225                                                  NULL);
00226            if (unscaled == NULL)
00227               break;
00228            _cairo_hash_table_remove (font_map->hash_table,
00229                                   &unscaled->base.hash_entry);
00230 
00231            _font_map_release_face_lock_held (font_map, unscaled);
00232            _cairo_ft_unscaled_font_fini (unscaled);
00233            free (unscaled);
00234        }
00235 
00236        assert (font_map->num_open_faces == 0);
00237 
00238        FT_Done_FreeType (font_map->ft_library);
00239 
00240        _cairo_hash_table_destroy (font_map->hash_table);
00241 
00242        free (font_map);
00243 
00244        cairo_ft_unscaled_font_map = NULL;
00245     }
00246 
00247     CAIRO_MUTEX_UNLOCK (cairo_ft_unscaled_font_map_mutex);
00248 }
00249 
00250 static cairo_ft_unscaled_font_map_t *
00251 _cairo_ft_unscaled_font_map_lock (void)
00252 {
00253     CAIRO_MUTEX_LOCK (cairo_ft_unscaled_font_map_mutex);
00254 
00255     if (cairo_ft_unscaled_font_map == NULL)
00256     {
00257        _cairo_ft_unscaled_font_map_create ();
00258 
00259        if (cairo_ft_unscaled_font_map == NULL) {
00260            CAIRO_MUTEX_UNLOCK (cairo_ft_unscaled_font_map_mutex);
00261            return NULL;
00262        }
00263     }
00264 
00265     return cairo_ft_unscaled_font_map;
00266 }
00267 
00268 static void
00269 _cairo_ft_unscaled_font_map_unlock (void)
00270 {
00271     CAIRO_MUTEX_UNLOCK (cairo_ft_unscaled_font_map_mutex);
00272 }
00273 
00274 static void
00275 _cairo_ft_unscaled_font_init_key (cairo_ft_unscaled_font_t *key,
00276                               char                  *filename,
00277                               int                    id)
00278 {
00279     unsigned long hash;
00280 
00281     key->filename = filename;
00282     key->id = id;
00283 
00284     /* 1607 is just an arbitrary prime. */
00285     hash = _cairo_hash_string (filename);
00286     hash += ((unsigned long) id) * 1607;
00287        
00288     key->base.hash_entry.hash = hash;
00289 }
00290 
00312 static cairo_status_t
00313 _cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled,
00314                            const char            *filename,
00315                            int                   id,
00316                            FT_Face               face)
00317 {
00318     _cairo_unscaled_font_init (&unscaled->base,
00319                             &cairo_ft_unscaled_font_backend);
00320 
00321     if (face) {
00322        unscaled->from_face = TRUE;
00323        unscaled->face = face;
00324        unscaled->filename = NULL;
00325        unscaled->id = 0;
00326     } else {
00327        char *filename_copy;
00328 
00329        unscaled->from_face = FALSE;
00330        unscaled->face = NULL;
00331 
00332        filename_copy = strdup (filename);
00333        if (filename_copy == NULL)
00334            return CAIRO_STATUS_NO_MEMORY;
00335 
00336        _cairo_ft_unscaled_font_init_key (unscaled, filename_copy, id);
00337     }
00338 
00339     unscaled->have_scale = FALSE;
00340     unscaled->lock = 0;
00341     
00342     unscaled->faces = NULL;
00343 
00344     return CAIRO_STATUS_SUCCESS;
00345 }
00346 
00347 cairo_bool_t
00348 _cairo_unscaled_font_is_ft (cairo_unscaled_font_t *unscaled_font)
00349 {
00350     return unscaled_font->backend == &cairo_ft_unscaled_font_backend;
00351 }
00352 
00364 static void
00365 _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled)
00366 {
00367     assert (unscaled->face == NULL);
00368 
00369     if (unscaled->filename) {
00370        free (unscaled->filename);
00371        unscaled->filename = NULL;
00372     }
00373 }
00374 
00375 static int
00376 _cairo_ft_unscaled_font_keys_equal (void *key_a,
00377                                 void *key_b)
00378 {
00379     cairo_ft_unscaled_font_t *unscaled_a = key_a;
00380     cairo_ft_unscaled_font_t *unscaled_b = key_b;
00381 
00382     return (strcmp (unscaled_a->filename, unscaled_b->filename) == 0 &&
00383            unscaled_a->id == unscaled_b->id);
00384 }
00385 
00386 /* Finds or creates a cairo_ft_unscaled_font for the filename/id from
00387  * pattern.  Returns a new reference to the unscaled font.
00388  */
00389 static cairo_ft_unscaled_font_t *
00390 _cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern)
00391 {
00392     cairo_ft_unscaled_font_t key, *unscaled;
00393     cairo_ft_unscaled_font_map_t *font_map;
00394     cairo_status_t status;
00395     FcChar8 *fc_filename;
00396     char *filename;
00397     int id;
00398     
00399     if (FcPatternGetString (pattern, FC_FILE, 0, &fc_filename) != FcResultMatch)
00400        goto UNWIND;
00401     filename = (char *) fc_filename;
00402 
00403     if (FcPatternGetInteger (pattern, FC_INDEX, 0, &id) != FcResultMatch)
00404        goto UNWIND;
00405     
00406     font_map = _cairo_ft_unscaled_font_map_lock ();
00407     if (font_map == NULL)
00408        goto UNWIND;
00409 
00410     _cairo_ft_unscaled_font_init_key (&key, filename, id);
00411 
00412     /* Return exsiting unscaled font if it exists in the hash table. */
00413     if (_cairo_hash_table_lookup (font_map->hash_table, &key.base.hash_entry,
00414                               (cairo_hash_entry_t **) &unscaled))
00415     {
00416        _cairo_ft_unscaled_font_map_unlock ();
00417        _cairo_unscaled_font_reference (&unscaled->base);
00418        return unscaled;
00419     }
00420 
00421     /* Otherwise create it and insert into hash table. */
00422     unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
00423     if (unscaled == NULL)
00424        goto UNWIND_FONT_MAP_LOCK;
00425 
00426     status = _cairo_ft_unscaled_font_init (unscaled, filename, id, NULL);
00427     if (status)
00428        goto UNWIND_UNSCALED_MALLOC;
00429 
00430     status = _cairo_hash_table_insert (font_map->hash_table,
00431                                    &unscaled->base.hash_entry);
00432     if (status)
00433        goto UNWIND_UNSCALED_FONT_INIT;
00434 
00435     _cairo_ft_unscaled_font_map_unlock ();
00436 
00437     return unscaled;
00438 
00439 UNWIND_UNSCALED_FONT_INIT:
00440     _cairo_ft_unscaled_font_fini (unscaled);
00441 UNWIND_UNSCALED_MALLOC:
00442     free (unscaled);
00443 UNWIND_FONT_MAP_LOCK:
00444     _cairo_ft_unscaled_font_map_unlock ();
00445 UNWIND:    
00446     return NULL;
00447 }
00448 
00449 static cairo_ft_unscaled_font_t *
00450 _cairo_ft_unscaled_font_create_from_face (FT_Face face)
00451 {
00452     cairo_status_t status;
00453     cairo_ft_unscaled_font_t *unscaled;
00454 
00455     unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
00456     if (unscaled == NULL)
00457        return NULL;
00458 
00459     status = _cairo_ft_unscaled_font_init (unscaled, NULL, 0, face);
00460     if (status) {
00461        free (unscaled);
00462        return NULL;
00463     }
00464 
00465     return unscaled;
00466 }
00467 
00468 static void 
00469 _cairo_ft_unscaled_font_destroy (void *abstract_font)
00470 {
00471     cairo_ft_unscaled_font_t *unscaled  = abstract_font;
00472 
00473     if (unscaled == NULL)
00474        return;
00475 
00476     if (unscaled->from_face) {
00477        /* See comments in _ft_font_face_destroy about the "zombie" state
00478         * for a _ft_font_face.
00479         */
00480        if (unscaled->faces && !unscaled->faces->unscaled)
00481            cairo_font_face_destroy (&unscaled->faces->base);
00482     } else {
00483        cairo_ft_unscaled_font_map_t *font_map;
00484        
00485        font_map = _cairo_ft_unscaled_font_map_lock ();
00486        /* All created objects must have been mapped in the font map. */
00487        assert (font_map != NULL);
00488 
00489        _cairo_hash_table_remove (font_map->hash_table,
00490                               &unscaled->base.hash_entry);
00491 
00492        _font_map_release_face_lock_held (font_map, unscaled);
00493        _cairo_ft_unscaled_font_fini (unscaled);
00494 
00495        _cairo_ft_unscaled_font_map_unlock ();
00496     }
00497 }
00498 
00499 static cairo_bool_t
00500 _has_unlocked_face (void *entry)
00501 {
00502     cairo_ft_unscaled_font_t *unscaled = entry;
00503 
00504     return (unscaled->lock == 0 && unscaled->face);
00505 }
00506 
00507 /* Ensures that an unscaled font has a face object. If we exceed
00508  * MAX_OPEN_FACES, try to close some.
00509  *
00510  * This differs from _cairo_ft_scaled_font_lock_face in that it doesn't
00511  * set the scale on the face, but just returns it at the last scale.
00512  */
00513 FT_Face
00514 _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled)
00515 {
00516     cairo_ft_unscaled_font_map_t *font_map;
00517     FT_Face face = NULL;
00518 
00519     if (unscaled->face) {
00520        unscaled->lock++;
00521        return unscaled->face;
00522     }
00523 
00524     /* If this unscaled font was created from an FT_Face then we just
00525      * returned it above. */
00526     assert (!unscaled->from_face);
00527     
00528     font_map = _cairo_ft_unscaled_font_map_lock ();
00529     assert (font_map != NULL);
00530     
00531     while (font_map->num_open_faces >= MAX_OPEN_FACES)
00532     {
00533        cairo_ft_unscaled_font_t *entry;
00534     
00535        entry = _cairo_hash_table_random_entry (font_map->hash_table,
00536                                           _has_unlocked_face);
00537        if (entry == NULL)
00538            break;
00539 
00540        _font_map_release_face_lock_held (font_map, entry);
00541     }
00542 
00543     if (FT_New_Face (font_map->ft_library,
00544                    unscaled->filename,
00545                    unscaled->id,
00546                    &face) != FT_Err_Ok)
00547        goto FAIL;
00548 
00549     unscaled->face = face;
00550     unscaled->lock++;
00551 
00552     font_map->num_open_faces++;
00553 
00554  FAIL:
00555     _cairo_ft_unscaled_font_map_unlock ();
00556 
00557     return face;
00558 }
00559 
00560 /* Unlock unscaled font locked with _cairo_ft_unscaled_font_lock_face
00561  */
00562 void
00563 _cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled)
00564 {
00565     assert (unscaled->lock > 0);
00566     
00567     unscaled->lock--;
00568 }
00569 
00570 static void
00571 _compute_transform (cairo_ft_font_transform_t *sf,
00572                   cairo_matrix_t      *scale)
00573 {
00574     cairo_matrix_t normalized = *scale;
00575     double tx, ty;
00576     
00577     /* The font matrix has x and y "scale" components which we extract and
00578      * use as character scale values. These influence the way freetype
00579      * chooses hints, as well as selecting different bitmaps in
00580      * hand-rendered fonts. We also copy the normalized matrix to
00581      * freetype's transformation.
00582      */
00583 
00584     _cairo_matrix_compute_scale_factors (&normalized, 
00585                                     &sf->x_scale, &sf->y_scale,
00586                                     /* XXX */ 1);
00587     
00588     if (sf->x_scale != 0 && sf->y_scale != 0) {
00589        cairo_matrix_scale (&normalized, 1.0 / sf->x_scale, 1.0 / sf->y_scale);
00590     
00591        _cairo_matrix_get_affine (&normalized, 
00592                               &sf->shape[0][0], &sf->shape[0][1],
00593                               &sf->shape[1][0], &sf->shape[1][1],
00594                               &tx, &ty);
00595     } else {
00596        sf->shape[0][0] = sf->shape[1][1] = 1.0;
00597        sf->shape[0][1] = sf->shape[1][0] = 0.0;
00598     }
00599 }
00600 
00601 /* Temporarily scales an unscaled font to the give scale. We catch
00602  * scaling to the same size, since changing a FT_Face is expensive.
00603  */
00604 static void
00605 _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
00606                                cairo_matrix_t          *scale)
00607 {
00608     cairo_ft_font_transform_t sf;
00609     FT_Matrix mat;
00610     FT_UInt pixel_width, pixel_height;
00611     FT_Error error;
00612 
00613     assert (unscaled->face != NULL);
00614     
00615     if (unscaled->have_scale &&
00616        scale->xx == unscaled->current_scale.xx &&
00617        scale->yx == unscaled->current_scale.yx &&
00618        scale->xy == unscaled->current_scale.xy &&
00619        scale->yy == unscaled->current_scale.yy)
00620        return;
00621 
00622     unscaled->have_scale = TRUE;
00623     unscaled->current_scale = *scale;
00624        
00625     _compute_transform (&sf, scale);
00626 
00627     unscaled->x_scale = sf.x_scale;
00628     unscaled->y_scale = sf.y_scale;
00629        
00630     mat.xx = DOUBLE_TO_16_16(sf.shape[0][0]);
00631     mat.yx = - DOUBLE_TO_16_16(sf.shape[0][1]);
00632     mat.xy = - DOUBLE_TO_16_16(sf.shape[1][0]);
00633     mat.yy = DOUBLE_TO_16_16(sf.shape[1][1]);
00634 
00635     unscaled->have_shape = (mat.xx != 0x10000 ||
00636                          mat.yx != 0x00000 ||
00637                          mat.xy != 0x00000 ||
00638                          mat.yy != 0x10000);
00639     
00640     FT_Set_Transform(unscaled->face, &mat, NULL);
00641 
00642     if ((unscaled->face->face_flags & FT_FACE_FLAG_SCALABLE) != 0) {
00643         double x_scale = sf.x_scale;
00644         double y_scale = sf.y_scale;
00645         if (x_scale > MAX_FONT_SIZE) {
00646             x_scale = MAX_FONT_SIZE;
00647         }
00648         if (y_scale > MAX_FONT_SIZE) {
00649             y_scale = MAX_FONT_SIZE;
00650         }
00651 
00652         pixel_width = x_scale;
00653         pixel_height = y_scale;
00654         
00655        error = FT_Set_Char_Size (unscaled->face,
00656                                   x_scale * 64.0,
00657                                   y_scale * 64.0,
00658                               0, 0);
00659     } else {
00660        double min_distance = DBL_MAX;
00661        int i;
00662        int best_i = 0;
00663 
00664        pixel_width = pixel_height = 0;
00665        
00666        for (i = 0; i < unscaled->face->num_fixed_sizes; i++) {
00667 #if HAVE_FT_BITMAP_SIZE_Y_PPEM
00668            double size = unscaled->face->available_sizes[i].y_ppem / 64.;
00669 #else
00670            double size = unscaled->face->available_sizes[i].height;
00671 #endif
00672            double distance = fabs (size - sf.y_scale);
00673            
00674            if (distance <= min_distance) {
00675               min_distance = distance;
00676               best_i = i;
00677            }
00678        }
00679 #if HAVE_FT_BITMAP_SIZE_Y_PPEM
00680        error = FT_Set_Char_Size (unscaled->face,
00681                               unscaled->face->available_sizes[best_i].x_ppem,
00682                               unscaled->face->available_sizes[best_i].y_ppem,
00683                               0, 0);
00684        if (error)
00685 #endif
00686            error = FT_Set_Pixel_Sizes (unscaled->face,
00687                                    unscaled->face->available_sizes[best_i].width,
00688                                    unscaled->face->available_sizes[best_i].height);
00689     }
00690 
00691     assert (error == 0);
00692 }
00693 
00694 /* Empirically-derived subpixel filtering values thanks to Keith
00695  * Packard and libXft. */
00696 static const int    filters[3][3] = {
00697     /* red */
00698 #if 0
00699     {    65538*4/7,65538*2/7,65538*1/7 },
00700     /* green */
00701     {    65536*1/4, 65536*2/4, 65537*1/4 },
00702     /* blue */
00703     {    65538*1/7,65538*2/7,65538*4/7 },
00704 #endif
00705     {    65538*9/13,65538*3/13,65538*1/13 },
00706     /* green */
00707     {    65538*1/6, 65538*4/6, 65538*1/6 },
00708     /* blue */
00709     {    65538*1/13,65538*3/13,65538*9/13 },
00710 };
00711 
00712 static cairo_bool_t
00713 _native_byte_order_lsb (void)
00714 {
00715     int       x = 1;
00716 
00717     return *((char *) &x) == 1;
00718 }
00719 
00720 /* Fills in val->image with an image surface created from @bitmap
00721  */
00722 static cairo_status_t
00723 _get_bitmap_surface (cairo_image_glyph_cache_entry_t *val,
00724                    FT_Bitmap                       *bitmap,
00725                    cairo_bool_t                     own_buffer,
00726                    int                          rgba)
00727 {
00728     int width, height, stride;
00729     unsigned char *data;
00730     int format = CAIRO_FORMAT_A8;
00731     cairo_bool_t subpixel = FALSE;
00732     
00733     width = bitmap->width;
00734     height = bitmap->rows;
00735     
00736     if (width * height == 0) {
00737        if (own_buffer && bitmap->buffer)
00738            free (bitmap->buffer);
00739        
00740        val->image = NULL;
00741     } else {
00742        switch (bitmap->pixel_mode) {
00743        case FT_PIXEL_MODE_MONO:
00744            stride = (((width + 31) & ~31) >> 3);
00745            if (own_buffer) {
00746               data = bitmap->buffer;
00747               assert (stride == bitmap->pitch);
00748            } else {
00749               data = malloc (stride * height);
00750               if (!data)
00751                   return CAIRO_STATUS_NO_MEMORY;
00752 
00753               if (stride == bitmap->pitch) {
00754                   memcpy (data, bitmap->buffer, stride * height);
00755               } else {
00756                   int i;
00757                   unsigned char *source, *dest;
00758               
00759                   source = bitmap->buffer;
00760                   dest = data;
00761                   for (i = height; i; i--) {
00762                      memcpy (dest, source, bitmap->pitch);
00763                      memset (dest + bitmap->pitch, '\0', stride - bitmap->pitch);
00764                      
00765                      source += bitmap->pitch;
00766                      dest += stride;
00767                   }
00768               }
00769            }
00770            
00771            if (_native_byte_order_lsb())
00772            {
00773               unsigned char   *d = data, c;
00774               int           count = stride * height;
00775               
00776               while (count--) {
00777                   c = *d;
00778                   c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55);
00779                   c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33);
00780                   c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f);
00781                   *d++ = c;
00782               }
00783            }
00784            format = CAIRO_FORMAT_A1;
00785            break;
00786 
00787        case FT_PIXEL_MODE_LCD:
00788        case FT_PIXEL_MODE_LCD_V:
00789        case FT_PIXEL_MODE_GRAY:
00790            if (rgba == FC_RGBA_NONE || rgba == FC_RGBA_UNKNOWN)
00791            {
00792               stride = bitmap->pitch;
00793               if (own_buffer) {
00794                   data = bitmap->buffer;
00795               } else {
00796                   data = malloc (stride * height);
00797                   if (!data)
00798                      return CAIRO_STATUS_NO_MEMORY;
00799                   memcpy (data, bitmap->buffer, stride * height);
00800               }
00801               format = CAIRO_FORMAT_A8;
00802            } else {
00803               int               x, y;
00804               unsigned char   *in_line, *out_line, *in;
00805               unsigned int    *out;
00806               unsigned int    red, green, blue;
00807               int               rf, gf, bf;
00808               int               s;
00809               int               o, os;
00810               unsigned char   *data_rgba;
00811               unsigned int    width_rgba, stride_rgba;
00812               int               vmul = 1;
00813               int               hmul = 1;
00814               
00815               switch (rgba) {
00816               case FC_RGBA_RGB:
00817               case FC_RGBA_BGR:
00818               default:
00819                   width /= 3;
00820                   hmul = 3;
00821                   break;
00822               case FC_RGBA_VRGB:
00823               case FC_RGBA_VBGR:
00824                   vmul = 3;
00825                   height /= 3;
00826                   break;
00827               }
00828               subpixel = TRUE;
00829               /*
00830                * Filter the glyph to soften the color fringes
00831                */
00832               width_rgba = width;
00833               stride = bitmap->pitch;
00834               stride_rgba = (width_rgba * 4 + 3) & ~3;
00835               data_rgba = calloc (1, stride_rgba * height);
00836     
00837               os = 1;
00838               switch (rgba) {
00839               case FC_RGBA_VRGB:
00840                   os = stride;
00841               case FC_RGBA_RGB:
00842               default:
00843                   rf = 0;
00844                   gf = 1;
00845                   bf = 2;
00846                   break;
00847               case FC_RGBA_VBGR:
00848                   os = stride;
00849               case FC_RGBA_BGR:
00850                   bf = 0;
00851                   gf = 1;
00852                   rf = 2;
00853                   break;
00854               }
00855               in_line = bitmap->buffer;
00856               out_line = data_rgba;
00857               for (y = 0; y < height; y++)
00858               {
00859                   in = in_line;
00860                   out = (unsigned int *) out_line;
00861                   in_line += stride * vmul;
00862                   out_line += stride_rgba;
00863                   for (x = 0; x < width * hmul; x += hmul)
00864                   {
00865                      red = green = blue = 0;
00866                      o = 0;
00867                      for (s = 0; s < 3; s++)
00868                      {
00869                          red += filters[rf][s]*in[x+o];
00870                          green += filters[gf][s]*in[x+o];
00871                          blue += filters[bf][s]*in[x+o];
00872                          o += os;
00873                      }
00874                      red = red / 65536;
00875                      green = green / 65536;
00876                      blue = blue / 65536;
00877                      *out++ = (green << 24) | (red << 16) | (green << 8) | blue;
00878                   }
00879               }
00880     
00881               /* Images here are stored in native format. The
00882                * backend must convert to its own format as needed
00883                */
00884     
00885               if (own_buffer)
00886                   free (bitmap->buffer);
00887               data = data_rgba;
00888               stride = stride_rgba;
00889               format = CAIRO_FORMAT_ARGB32;
00890            }
00891            break;
00892        case FT_PIXEL_MODE_GRAY2:
00893        case FT_PIXEL_MODE_GRAY4:
00894            /* These could be triggered by very rare types of TrueType fonts */
00895        default:
00896            return CAIRO_STATUS_NO_MEMORY;
00897        }
00898     
00899        val->image = (cairo_image_surface_t *)
00900            cairo_image_surface_create_for_data (data,
00901                                            format,
00902                                            width, height, stride);
00903        if (val->image->base.status) {
00904            free (data);
00905            return CAIRO_STATUS_NO_MEMORY;
00906        }
00907        
00908        if (subpixel)
00909            pixman_image_set_component_alpha (val->image->pixman_image, TRUE);
00910 
00911        _cairo_image_surface_assume_ownership_of_data (val->image);
00912     }
00913 
00914     val->size.width = width;
00915     val->size.height = height;
00916 
00917     return CAIRO_STATUS_SUCCESS;
00918 }
00919 
00920 /* Converts an outline FT_GlyphSlot into an image
00921  * 
00922  * This could go through _render_glyph_bitmap as well, letting
00923  * FreeType convert the outline to a bitmap, but doing it ourselves
00924  * has two minor advantages: first, we save a copy of the bitmap
00925  * buffer: we can directly use the buffer that FreeType renders
00926  * into.
00927  *
00928  * Second, it may help when we add support for subpixel
00929  * rendering: the Xft code does it this way. (Keith thinks that
00930  * it may also be possible to get the subpixel rendering with
00931  * FT_Render_Glyph: something worth looking into in more detail
00932  * when we add subpixel support. If so, we may want to eliminate
00933  * this version of the code path entirely.
00934  */
00935 static cairo_status_t
00936 _render_glyph_outline (FT_Face                          face,
00937                      cairo_image_glyph_cache_entry_t *val)
00938 {
00939     int rgba = FC_RGBA_UNKNOWN;
00940     FT_GlyphSlot glyphslot = face->glyph;
00941     FT_Outline *outline = &glyphslot->outline;
00942     FT_Bitmap bitmap;
00943     FT_BBox cbox;
00944     FT_Matrix matrix;
00945     int hmul = 1;
00946     int vmul = 1;
00947     unsigned int width, height, stride;
00948     cairo_format_t format;
00949     cairo_bool_t subpixel = FALSE;
00950     cairo_status_t status;
00951 
00952     FT_Outline_Get_CBox (outline, &cbox);
00953 
00954     cbox.xMin &= -64;
00955     cbox.yMin &= -64;
00956     cbox.xMax = (cbox.xMax + 63) & -64;
00957     cbox.yMax = (cbox.yMax + 63) & -64;
00958 
00959     width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6);
00960     height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6);
00961     stride = (width * hmul + 3) & ~3;
00962 
00963     if (width * height == 0) {
00964        /* Looks like fb handles zero-sized images just fine */
00965        if ((val->key.flags & FT_LOAD_MONOCHROME) != 0)
00966            format = CAIRO_FORMAT_A8;
00967        else if (FT_LOAD_TARGET_MODE (val->key.flags) == FT_RENDER_MODE_LCD ||
00968                FT_LOAD_TARGET_MODE (val->key.flags) == FT_RENDER_MODE_LCD_V)
00969            format= CAIRO_FORMAT_ARGB32;
00970        else
00971            format = CAIRO_FORMAT_A8;
00972 
00973        val->image = (cairo_image_surface_t *)
00974            cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);
00975        if (val->image->base.status)
00976            return CAIRO_STATUS_NO_MEMORY;
00977     } else  {
00978 
00979        matrix.xx = matrix.yy = 0x10000L;
00980        matrix.xy = matrix.yx = 0;
00981        
00982        if ((val->key.flags & FT_LOAD_MONOCHROME) != 0) {
00983            bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
00984            bitmap.num_grays  = 1;
00985            stride = ((width + 31) & -32) >> 3;
00986        } else {
00987            /* XXX not a complete set of flags. This code
00988             * will go away when cworth rewrites the glyph
00989             * cache code */
00990            if (FT_LOAD_TARGET_MODE (val->key.flags) == FT_RENDER_MODE_LCD)
00991               rgba = FC_RGBA_RGB;
00992            else if (FT_LOAD_TARGET_MODE (val->key.flags) == FT_RENDER_MODE_LCD_V)
00993               rgba = FC_RGBA_VBGR;
00994        
00995            switch (rgba) {
00996            case FC_RGBA_RGB:
00997            case FC_RGBA_BGR:
00998               matrix.xx *= 3;
00999               hmul = 3;
01000               subpixel = TRUE;
01001               break;
01002            case FC_RGBA_VRGB:
01003            case FC_RGBA_VBGR:
01004               matrix.yy *= 3;
01005               vmul = 3;
01006               subpixel = TRUE;
01007               break;
01008            }
01009            if (subpixel)
01010               format = CAIRO_FORMAT_ARGB32;
01011            else
01012               format = CAIRO_FORMAT_A8;
01013            
01014            if (subpixel)
01015               FT_Outline_Transform (outline, &matrix);
01016 
01017            bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
01018            bitmap.num_grays  = 256;
01019            stride = (width * hmul + 3) & -4;
01020        }
01021        bitmap.pitch = stride;   
01022        bitmap.width = width * hmul;
01023        bitmap.rows = height * vmul;
01024        bitmap.buffer = calloc (1, stride * bitmap.rows);
01025        
01026        if (bitmap.buffer == NULL) {
01027            return CAIRO_STATUS_NO_MEMORY;
01028        }
01029        
01030        FT_Outline_Translate (outline, -cbox.xMin*hmul, -cbox.yMin*vmul);
01031        
01032        if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) {
01033            free (bitmap.buffer);
01034            return CAIRO_STATUS_NO_MEMORY;
01035        }
01036 
01037        status = _get_bitmap_surface (val, &bitmap, TRUE, rgba);
01038        if (status)
01039            return status;
01040     }
01041 
01042     /*
01043      * Note: the font's coordinate system is upside down from ours, so the
01044      * Y coordinate of the control box needs to be negated.
01045      */
01046 
01047     val->size.x =   (short) (cbox.xMin >> 6);
01048     val->size.y = - (short) (cbox.yMax >> 6);
01049 
01050     return CAIRO_STATUS_SUCCESS;
01051 }
01052 
01053 /* Converts a bitmap (or other) FT_GlyphSlot into an image
01054  * 
01055  * This could go through _render_glyph_bitmap as well, letting
01056  * FreeType convert the outline to a bitmap, but doing it ourselves
01057  * has two minor advantages: first, we save a copy of the bitmap
01058  * buffer: we can directly use the buffer that FreeType renders
01059  * into.
01060  *
01061  * Second, it may help when we add support for subpixel
01062  * rendering: the Xft code does it this way. (Keith thinks that
01063  * it may also be possible to get the subpixel rendering with
01064  * FT_Render_Glyph: something worth looking into in more detail
01065  * when we add subpixel support. If so, we may want to eliminate
01066  * this version of the code path entirely.
01067  */
01068 static cairo_status_t
01069 _render_glyph_bitmap (FT_Face                          face,
01070                     cairo_image_glyph_cache_entry_t *val)
01071 {
01072     FT_GlyphSlot glyphslot = face->glyph;
01073     cairo_status_t status = CAIRO_STATUS_SUCCESS;
01074     FT_Error error;
01075 
01076     /* According to the FreeType docs, glyphslot->format could be
01077      * something other than FT_GLYPH_FORMAT_OUTLINE or
01078      * FT_GLYPH_FORMAT_BITMAP. Calling FT_Render_Glyph gives FreeType
01079      * the opportunity to convert such to
01080      * bitmap. FT_GLYPH_FORMAT_COMPOSITE will not be encountered since
01081      * we avoid the FT_LOAD_NO_RECURSE flag.
01082      */
01083     error = FT_Render_Glyph (glyphslot, FT_RENDER_MODE_NORMAL);
01084     if (error)
01085        return CAIRO_STATUS_NO_MEMORY;
01086 
01087     _get_bitmap_surface (val, &glyphslot->bitmap, FALSE, FC_RGBA_NONE);
01088 
01089     val->size.x = glyphslot->bitmap_left;
01090     val->size.y = - glyphslot->bitmap_top;
01091     
01092     return status;
01093 }
01094 
01095 static cairo_status_t
01096 _transform_glyph_bitmap (cairo_image_glyph_cache_entry_t *val)
01097 {
01098     cairo_ft_font_transform_t sf;
01099     cairo_matrix_t original_to_transformed;
01100     cairo_matrix_t transformed_to_original;
01101     cairo_image_surface_t *old_image;
01102     cairo_surface_t *image;
01103     double x[4], y[4];
01104     double origin_x, origin_y;
01105     int i;
01106     int x_min, y_min, x_max, y_max;
01107     int width, height;
01108     cairo_status_t status;
01109     cairo_surface_pattern_t pattern;
01110     
01111     /* We want to compute a transform that takes the origin
01112      * (val->size.x, val->size.y) to 0,0, then applies the "shape"
01113      * portion of the font transform
01114      */
01115     _compute_transform (&sf, &val->key.scale);
01116 
01117     cairo_matrix_init (&original_to_transformed,
01118                      sf.shape[0][0], sf.shape[0][1],
01119                      sf.shape[1][0], sf.shape[1][1],
01120                      0, 0);
01121 
01122     cairo_matrix_translate (&original_to_transformed,
01123                          val->size.x, val->size.y);
01124 
01125     /* Find the bounding box of the original bitmap under that
01126      * transform
01127      */
01128     x[0] = 0;               y[0] = 0;
01129     x[1] = val->size.width; y[1] = 0;
01130     x[2] = val->size.width; y[2] = val->size.height;
01131     x[3] = 0;               y[3] = val->size.height;
01132 
01133     for (i = 0; i < 4; i++)
01134       cairo_matrix_transform_point (&original_to_transformed,
01135                                 &x[i], &y[i]);
01136 
01137     x_min = floor (x[0]);   y_min = floor (y[0]);
01138     x_max =  ceil (x[0]);   y_max =  ceil (y[0]);
01139     
01140     for (i = 1; i < 4; i++) {
01141        if (x[i] < x_min)
01142            x_min = floor (x[i]);
01143        if (x[i] > x_max)
01144            x_max = ceil (x[i]);
01145        if (y[i] < y_min)
01146            y_min = floor (y[i]);
01147        if (y[i] > y_max)
01148            y_max = ceil (y[i]);
01149     }
01150 
01151     /* Adjust the transform so that the bounding box starts at 0,0 ...
01152      * this gives our final transform from original bitmap to transformed
01153      * bitmap.
01154      */
01155     original_to_transformed.x0 -= x_min;
01156     original_to_transformed.y0 -= y_min;
01157 
01158     /* Create the transformed bitmap
01159      */
01160     width = x_max - x_min;
01161     height = y_max - y_min;
01162 
01163     transformed_to_original = original_to_transformed;
01164     status = cairo_matrix_invert (&transformed_to_original);
01165     if (status)
01166        return status;
01167 
01168     /* We need to pad out the width to 32-bit intervals for cairo-xlib-surface.c */
01169     width = (width + 3) & ~3;
01170     image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
01171     if (image->status)
01172        return CAIRO_STATUS_NO_MEMORY;
01173 
01174     /* Initialize it to empty
01175      */
01176     _cairo_surface_fill_rectangle (image, CAIRO_OPERATOR_CLEAR,
01177                                CAIRO_COLOR_TRANSPARENT,
01178                                0, 0,
01179                                width, height);
01180 
01181     /* Draw the original bitmap transformed into the new bitmap
01182      */
01183     _cairo_pattern_init_for_surface (&pattern, &val->image->base);
01184     cairo_pattern_set_matrix (&pattern.base, &transformed_to_original);
01185 
01186     _cairo_surface_composite (CAIRO_OPERATOR_OVER,
01187                            &pattern.base, NULL, image,
01188                            0, 0, 0, 0, 0, 0,
01189                            width,
01190                            height);
01191 
01192     _cairo_pattern_fini (&pattern.base);
01193 
01194     /* Now update the cache entry for the new bitmap, recomputing
01195      * the origin based on the final transform.
01196      */
01197     origin_x = - val->size.x;
01198     origin_y = - val->size.y;
01199     cairo_matrix_transform_point (&original_to_transformed,
01200                               &origin_x, &origin_y);
01201 
01202     old_image = val->image;
01203     val->image = (cairo_image_surface_t *)image;
01204     cairo_surface_destroy (&old_image->base);
01205 
01206     val->size.width = width;
01207     val->size.height = height;
01208     val->size.x = - floor (origin_x + 0.5);
01209     val->size.y = - floor (origin_y + 0.5);
01210     
01211     return status;
01212 }
01213 
01214 static cairo_status_t 
01215 _cairo_ft_unscaled_font_create_glyph (void                            *abstract_font,
01216                                   cairo_image_glyph_cache_entry_t *val)
01217 {
01218     cairo_ft_unscaled_font_t *unscaled = abstract_font;
01219     FT_GlyphSlot glyphslot;
01220     FT_Face face;
01221     FT_Glyph_Metrics *metrics;
01222     cairo_status_t status = CAIRO_STATUS_SUCCESS;
01223     double x_factor, y_factor;
01224 
01225     face = _cairo_ft_unscaled_font_lock_face (unscaled);
01226     if (!face)
01227        return CAIRO_STATUS_NO_MEMORY;
01228 
01229     glyphslot = face->glyph;
01230     metrics = &glyphslot->metrics;
01231 
01232     _cairo_ft_unscaled_font_set_scale (unscaled, &val->key.scale);
01233 
01234     if (FT_Load_Glyph (face, val->key.index, val->key.flags & ~PRIVATE_FLAGS_MASK) != 0) {
01235        status = CAIRO_STATUS_NO_MEMORY;
01236        goto FAIL;
01237     }
01238 
01239 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
01240     if (val->key.flags & PRIVATE_FLAG_EMBOLDEN &&
01241        (face->style_flags & FT_STYLE_FLAG_BOLD) == 0) {
01242        FT_GlyphSlot_Embolden (glyphslot);
01243     }
01244 #endif
01245            
01246     if (unscaled->x_scale == 0)
01247        x_factor = 0;
01248     else
01249        x_factor = 1 / unscaled->x_scale;
01250     
01251     if (unscaled->y_scale == 0)
01252        y_factor = 0;
01253     else
01254        y_factor = 1 / unscaled->y_scale;
01255 
01256     /*
01257      * Note: the font's coordinate system is upside down from ours, so the
01258      * Y coordinates of the bearing and advance need to be negated.
01259      *
01260      * Scale metrics back to glyph space from the scaled glyph space returned
01261      * by FreeType
01262      *
01263      * If we want hinted metrics but aren't asking for hinted glyphs from
01264      * FreeType, then we need to do the metric hinting ourselves.
01265      */
01266     
01267     if ((val->key.flags & PRIVATE_FLAG_HINT_METRICS) &&
01268        (val->key.flags & FT_LOAD_NO_HINTING)) {
01269        FT_Pos x1, x2;
01270        FT_Pos y1, y2;
01271        FT_Pos advance;
01272        
01273        x1 = (metrics->horiBearingX) & -64;
01274        x2 = (metrics->horiBearingX + metrics->width + 63) & -64;
01275        y1 = (metrics->horiBearingY) & -64;
01276        y2 = (metrics->horiBearingY + metrics->height + 63) & -64;
01277  
01278        advance = ((metrics->horiAdvance + 32) & -64);
01279        
01280        val->extents.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor;
01281        val->extents.y_bearing = -DOUBLE_FROM_26_6 (y1) * y_factor;
01282        
01283        val->extents.width  = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;
01284        val->extents.height  = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;
01285        
01286        /*
01287         * use untransformed advance values
01288         * XXX uses horizontal advance only at present; should provide FT_LOAD_VERTICAL_LAYOUT
01289         */
01290        val->extents.x_advance = DOUBLE_FROM_26_6 (advance) * x_factor;
01291        val->extents.y_advance = 0;
01292      } else {
01293         val->extents.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) * x_factor;
01294         val->extents.y_bearing = -DOUBLE_FROM_26_6 (metrics->horiBearingY) * y_factor;
01295         
01296         val->extents.width  = DOUBLE_FROM_26_6 (metrics->width) * x_factor;
01297         val->extents.height = DOUBLE_FROM_26_6 (metrics->height) * y_factor;
01298         
01299         val->extents.x_advance = DOUBLE_FROM_26_6 (face->glyph->metrics.horiAdvance) * x_factor;
01300         val->extents.y_advance = 0 * y_factor;
01301      }
01302 
01303     if (glyphslot->format == FT_GLYPH_FORMAT_OUTLINE)
01304        status = _render_glyph_outline (face, val);
01305     else
01306        status = _render_glyph_bitmap (face, val);
01307     
01308     if (val->image &&
01309        unscaled->have_shape &&
01310        (unscaled->face->face_flags & FT_FACE_FLAG_SCALABLE) == 0)
01311        status = _transform_glyph_bitmap (val);
01312 
01313  FAIL:
01314     if (status && val->image) {
01315        cairo_surface_destroy (&val->image->base);
01316        val->image = NULL;
01317     }
01318            
01319     _cairo_ft_unscaled_font_unlock_face (unscaled);
01320 
01321     return status;
01322 }
01323 
01324 static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend = {
01325     _cairo_ft_unscaled_font_destroy,
01326     _cairo_ft_unscaled_font_create_glyph
01327 };
01328 
01329 /* cairo_ft_scaled_font_t */
01330 
01331 typedef struct _cairo_ft_scaled_font {
01332     cairo_scaled_font_t base;
01333     cairo_ft_unscaled_font_t *unscaled;
01334     int load_flags;
01335 } cairo_ft_scaled_font_t;
01336 
01337 const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend;
01338 
01339 /* The load flags passed to FT_Load_Glyph control aspects like hinting and
01340  * antialiasing. Here we compute them from the fields of a FcPattern.
01341  */
01342 static int
01343 _get_pattern_load_flags (FcPattern *pattern)
01344 {
01345     FcBool antialias, vertical_layout, hinting, autohint;
01346     int rgba;
01347 #ifdef FC_HINT_STYLE    
01348     int hintstyle;
01349 #endif    
01350     int load_flags = 0;
01351     int target_flags = 0;
01352 
01353     /* disable antialiasing if requested */
01354     if (FcPatternGetBool (pattern,
01355                        FC_ANTIALIAS, 0, &antialias) != FcResultMatch)
01356        antialias = FcTrue;
01357 
01358     if (antialias)
01359        load_flags |= FT_LOAD_NO_BITMAP;
01360     else
01361        load_flags |= FT_LOAD_MONOCHROME;
01362     
01363     /* disable hinting if requested */
01364     if (FcPatternGetBool (pattern,
01365                        FC_HINTING, 0, &hinting) != FcResultMatch)
01366        hinting = FcTrue;
01367 
01368 #ifdef FC_HINT_STYLE    
01369     if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch)
01370        hintstyle = FC_HINT_FULL;
01371 
01372     if (!hinting || hintstyle == FC_HINT_NONE)
01373        load_flags |= FT_LOAD_NO_HINTING;
01374     
01375     if (antialias) {
01376        switch (hintstyle) {
01377        case FC_HINT_SLIGHT:
01378        case FC_HINT_MEDIUM:
01379            target_flags = FT_LOAD_TARGET_LIGHT;
01380            break;
01381        default:
01382            target_flags = FT_LOAD_TARGET_NORMAL;
01383            break;
01384        }
01385     } else {
01386 #ifdef FT_LOAD_TARGET_MONO
01387        target_flags = FT_LOAD_TARGET_MONO;
01388 #endif 
01389     }
01390 #else /* !FC_HINT_STYLE */
01391     if (!hinting)
01392        target_flags = FT_LOAD_NO_HINTING;
01393 #endif /* FC_FHINT_STYLE */
01394 
01395     if (FcPatternGetInteger (pattern,
01396                           FC_RGBA, 0, &rgba) != FcResultMatch)
01397        rgba = FC_RGBA_UNKNOWN;
01398 
01399     switch (rgba) {
01400     case FC_RGBA_UNKNOWN:
01401     case FC_RGBA_NONE:
01402     default:
01403        break;
01404     case FC_RGBA_RGB:
01405     case FC_RGBA_BGR:
01406        target_flags = FT_LOAD_TARGET_LCD;
01407        break;
01408     case FC_RGBA_VRGB:
01409     case FC_RGBA_VBGR:
01410        target_flags = FT_LOAD_TARGET_LCD_V;
01411        break;
01412     }
01413 
01414     load_flags |= target_flags;
01415     
01416     /* force autohinting if requested */
01417     if (FcPatternGetBool (pattern,
01418                        FC_AUTOHINT, 0, &autohint) != FcResultMatch)
01419        autohint = FcFalse;
01420     
01421     if (autohint)
01422        load_flags |= FT_LOAD_FORCE_AUTOHINT;
01423     
01424     if (FcPatternGetBool (pattern,
01425                        FC_VERTICAL_LAYOUT, 0, &vertical_layout) != FcResultMatch)
01426        vertical_layout = FcFalse;
01427     
01428     if (vertical_layout)
01429        load_flags |= FT_LOAD_VERTICAL_LAYOUT;
01430     
01431 #ifdef FC_EMBOLDEN
01432     {
01433        FcBool embolden;
01434 
01435        if (FcPatternGetBool (pattern,
01436                            FC_EMBOLDEN, 0, &embolden) != FcResultMatch)
01437            embolden = FcFalse;
01438        
01439        if (embolden)
01440            load_flags |= PRIVATE_FLAG_EMBOLDEN;
01441     }
01442 #endif
01443     
01444     return load_flags;
01445 }
01446 
01447 static int
01448 _get_options_load_flags (const cairo_font_options_t *options)
01449 {
01450     int load_flags = 0;
01451 
01452     /* disable antialiasing if requested */
01453     switch (options->antialias) {
01454     case CAIRO_ANTIALIAS_NONE:
01455 #ifdef FT_LOAD_TARGET_MONO
01456        load_flags |= FT_LOAD_TARGET_MONO;
01457 #endif
01458        load_flags |= FT_LOAD_MONOCHROME;
01459        break;
01460     case CAIRO_ANTIALIAS_SUBPIXEL:
01461        switch (options->subpixel_order) {
01462        case CAIRO_SUBPIXEL_ORDER_DEFAULT:
01463        case CAIRO_SUBPIXEL_ORDER_RGB:
01464        case CAIRO_SUBPIXEL_ORDER_BGR:
01465            load_flags |= FT_LOAD_TARGET_LCD;
01466            break;
01467        case CAIRO_SUBPIXEL_ORDER_VRGB:
01468        case CAIRO_SUBPIXEL_ORDER_VBGR:
01469            load_flags |= FT_LOAD_TARGET_LCD_V;
01470            break;
01471        }
01472        /* fall through ... */
01473     case CAIRO_ANTIALIAS_DEFAULT:
01474     case CAIRO_ANTIALIAS_GRAY:
01475        load_flags |= FT_LOAD_NO_BITMAP;
01476        break;
01477     }
01478      
01479     /* disable hinting if requested */
01480     switch (options->hint_style) {
01481     case CAIRO_HINT_STYLE_NONE:
01482        load_flags |= FT_LOAD_NO_HINTING;
01483        break;
01484     case CAIRO_HINT_STYLE_SLIGHT:
01485     case CAIRO_HINT_STYLE_MEDIUM:
01486        load_flags |= FT_LOAD_TARGET_LIGHT;
01487        break;
01488     case CAIRO_HINT_STYLE_FULL:
01489     default:
01490        load_flags |= FT_LOAD_TARGET_NORMAL;
01491        break;
01492     }
01493      
01494     return load_flags;
01495 }
01496 
01497 static cairo_scaled_font_t *
01498 _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t   *unscaled,
01499                            cairo_font_face_t             *font_face,
01500                            const cairo_matrix_t   *font_matrix,
01501                            const cairo_matrix_t   *ctm,
01502                            const cairo_font_options_t *options,
01503                            int                     load_flags)
01504 {    
01505     cairo_ft_scaled_font_t *scaled_font = NULL;
01506 
01507     scaled_font = malloc (sizeof(cairo_ft_scaled_font_t));
01508     if (scaled_font == NULL)
01509        return NULL;
01510 
01511     _cairo_scaled_font_init (&scaled_font->base,
01512                           font_face,
01513                           font_matrix, ctm, options,
01514                           &cairo_ft_scaled_font_backend);
01515 
01516     _cairo_unscaled_font_reference (&unscaled->base);
01517     scaled_font->unscaled = unscaled;
01518 
01519     if (options->hint_metrics != CAIRO_HINT_METRICS_OFF)
01520        load_flags |= PRIVATE_FLAG_HINT_METRICS;
01521 
01522     scaled_font->load_flags = load_flags;
01523 
01524     return &scaled_font->base;
01525 }
01526 
01527 cairo_bool_t
01528 _cairo_scaled_font_is_ft (cairo_scaled_font_t *scaled_font)
01529 {
01530     return scaled_font->backend == &cairo_ft_scaled_font_backend;
01531 }
01532 
01533 static cairo_status_t
01534 _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t       *toy_face,
01535                               const cairo_matrix_t            *font_matrix,
01536                               const cairo_matrix_t            *ctm,
01537                               const cairo_font_options_t  *options,
01538                               cairo_scaled_font_t            **font)
01539 {
01540     FcPattern *pattern, *resolved;
01541     cairo_ft_unscaled_font_t *unscaled;
01542     cairo_scaled_font_t *new_font = NULL;
01543     FcResult result;
01544     int fcslant;
01545     int fcweight;
01546     cairo_matrix_t scale;
01547     cairo_ft_font_transform_t sf;
01548     int load_flags;
01549     unsigned char *family = (unsigned char*) toy_face->family;
01550 
01551     pattern = FcPatternCreate ();
01552     if (!pattern)
01553        return CAIRO_STATUS_NO_MEMORY;
01554 
01555     switch (toy_face->weight)
01556     {
01557     case CAIRO_FONT_WEIGHT_BOLD:
01558         fcweight = FC_WEIGHT_BOLD;
01559         break;
01560     case CAIRO_FONT_WEIGHT_NORMAL:
01561     default:
01562         fcweight = FC_WEIGHT_MEDIUM;
01563         break;
01564     }
01565 
01566     switch (toy_face->slant)
01567     {
01568     case CAIRO_FONT_SLANT_ITALIC:
01569         fcslant = FC_SLANT_ITALIC;
01570         break;
01571     case CAIRO_FONT_SLANT_OBLIQUE:
01572        fcslant = FC_SLANT_OBLIQUE;
01573         break;
01574     case CAIRO_FONT_SLANT_NORMAL:
01575     default:
01576         fcslant = FC_SLANT_ROMAN;
01577         break;
01578     }
01579 
01580     if (!FcPatternAddString (pattern, FC_FAMILY, family))
01581        goto FREE_PATTERN;
01582     if (!FcPatternAddInteger (pattern, FC_SLANT, fcslant))
01583        goto FREE_PATTERN;
01584     if (!FcPatternAddInteger (pattern, FC_WEIGHT, fcweight))
01585        goto FREE_PATTERN;
01586 
01587     cairo_matrix_multiply (&scale, font_matrix, ctm);
01588     _compute_transform (&sf, &scale);
01589 
01590     FcPatternAddInteger (pattern, FC_PIXEL_SIZE, sf.y_scale);
01591 
01592     FcConfigSubstitute (NULL, pattern, FcMatchPattern);
01593     cairo_ft_font_options_substitute (options, pattern);
01594     FcDefaultSubstitute (pattern);
01595     
01596     resolved = FcFontMatch (NULL, pattern, &result);
01597     if (!resolved)
01598        goto FREE_PATTERN;
01599 
01600     unscaled = _cairo_ft_unscaled_font_create_for_pattern (resolved);
01601     if (!unscaled)
01602        goto FREE_RESOLVED;
01603 
01604     load_flags = _get_pattern_load_flags (resolved);
01605 
01606     new_font = _cairo_ft_scaled_font_create (unscaled,
01607                                         &toy_face->base,
01608                                         font_matrix, ctm,
01609                                         options, load_flags);
01610 
01611     _cairo_unscaled_font_destroy (&unscaled->base);
01612 
01613  FREE_RESOLVED:
01614     FcPatternDestroy (resolved);
01615 
01616  FREE_PATTERN:
01617     FcPatternDestroy (pattern);
01618 
01619     if (new_font) {
01620        *font = new_font;
01621        return CAIRO_STATUS_SUCCESS;
01622     } else {
01623        return CAIRO_STATUS_NO_MEMORY;
01624     }
01625 }
01626 
01627 static void 
01628 _cairo_ft_scaled_font_fini (void *abstract_font)
01629 {
01630     cairo_ft_scaled_font_t *scaled_font = abstract_font;
01631   
01632     if (scaled_font == NULL)
01633         return;
01634   
01635     _cairo_unscaled_font_destroy (&scaled_font->unscaled->base);
01636 }
01637 
01638 static void
01639 _cairo_ft_scaled_font_get_glyph_cache_key (void                    *abstract_font,
01640                                       cairo_glyph_cache_key_t *key)
01641 {
01642     cairo_ft_scaled_font_t *scaled_font = abstract_font;
01643 
01644     key->unscaled = &scaled_font->unscaled->base;
01645     key->scale = scaled_font->base.scale;
01646     key->flags = scaled_font->load_flags;
01647 }
01648 
01649 static cairo_status_t 
01650 _cairo_ft_scaled_font_text_to_glyphs (void            *abstract_font,
01651                                   const char     *utf8,
01652                                   cairo_glyph_t **glyphs, 
01653                                   int          *num_glyphs)
01654 {
01655     double x = 0., y = 0.;
01656     size_t i;
01657     uint32_t *ucs4 = NULL;
01658     cairo_ft_scaled_font_t *scaled_font = abstract_font;
01659     FT_Face face;
01660     cairo_glyph_cache_key_t key;
01661     cairo_image_glyph_cache_entry_t *val;
01662     cairo_cache_t *cache = NULL;
01663     cairo_status_t status = CAIRO_STATUS_SUCCESS;
01664 
01665     _cairo_lock_global_image_glyph_cache ();
01666     cache = _cairo_get_global_image_glyph_cache ();
01667     if (cache == NULL)
01668        return CAIRO_STATUS_NO_MEMORY;
01669 
01670     _cairo_ft_scaled_font_get_glyph_cache_key (scaled_font, &key);
01671 
01672     status = _cairo_utf8_to_ucs4 ((unsigned char*)utf8, -1, &ucs4, num_glyphs);
01673     if (status)
01674        goto CLEANUP_CACHE;
01675 
01676     face = cairo_ft_scaled_font_lock_face (&scaled_font->base);
01677     if (!face) {
01678        status = CAIRO_STATUS_NO_MEMORY;
01679        goto CLEANUP_UCS4;
01680     }
01681 
01682     *glyphs = (cairo_glyph_t *) malloc ((*num_glyphs) * (sizeof (cairo_glyph_t)));
01683     if (*glyphs == NULL) {
01684        status = CAIRO_STATUS_NO_MEMORY;
01685        goto CLEANUP_SCALED_FONT_LOCK_FACE;
01686     }
01687 
01688     for (i = 0; i < *num_glyphs; i++)
01689     {            
01690         (*glyphs)[i].index = FT_Get_Char_Index (face, ucs4[i]);
01691        (*glyphs)[i].x = x;
01692        (*glyphs)[i].y = y;
01693        
01694        val = NULL;
01695        key.index = (*glyphs)[i].index;
01696 
01697        if (_cairo_cache_lookup (cache, &key, (void **) &val, NULL) 
01698            != CAIRO_STATUS_SUCCESS || val == NULL)
01699            continue;
01700 
01701         x += val->extents.x_advance;
01702         y += val->extents.y_advance;
01703     }
01704 
01705  CLEANUP_SCALED_FONT_LOCK_FACE:
01706     cairo_ft_scaled_font_unlock_face (&scaled_font->base);
01707     
01708  CLEANUP_UCS4:
01709     free (ucs4);
01710 
01711  CLEANUP_CACHE:
01712     if (cache)
01713        _cairo_unlock_global_image_glyph_cache ();
01714 
01715     return status;
01716 }
01717 
01718 
01719 static cairo_status_t 
01720 _cairo_ft_scaled_font_font_extents (void          *abstract_font,
01721                                 cairo_font_extents_t *extents)
01722 {
01723     cairo_ft_scaled_font_t *scaled_font = abstract_font;
01724     FT_Face face;
01725     FT_Size_Metrics *metrics;
01726     
01727     face = _cairo_ft_unscaled_font_lock_face (scaled_font->unscaled);
01728     if (!face)
01729        return CAIRO_STATUS_NO_MEMORY;
01730 
01731     metrics = &face->size->metrics;
01732 
01733     _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
01734                                    &scaled_font->base.scale);
01735 
01736     /*
01737      * Get to unscaled metrics so that the upper level can get back to
01738      * user space
01739      */
01740     if (scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF) {
01741        double x_factor, y_factor;
01742 
01743        if (scaled_font->unscaled->x_scale == 0)
01744            x_factor = 0;
01745        else
01746            x_factor = 1 / scaled_font->unscaled->x_scale;
01747        
01748        if (scaled_font->unscaled->y_scale == 0)
01749            y_factor = 0;
01750        else
01751            y_factor = 1 / scaled_font->unscaled->y_scale;
01752 
01753        extents->ascent =        DOUBLE_FROM_26_6(metrics->ascender) * y_factor;
01754        extents->descent =       DOUBLE_FROM_26_6(- metrics->descender) * y_factor;
01755        extents->height =        DOUBLE_FROM_26_6(metrics->height) * y_factor;
01756        extents->max_x_advance = DOUBLE_FROM_26_6(metrics->max_advance) * x_factor;
01757     } else {
01758        double scale = face->units_per_EM;
01759       
01760        extents->ascent =        face->ascender / scale;
01761        extents->descent =       - face->descender / scale;
01762        extents->height =        face->height / scale;
01763        extents->max_x_advance = face->max_advance_width / scale;
01764     }
01765 
01766     /* FIXME: this doesn't do vertical layout atm. */
01767     extents->max_y_advance = 0.0;
01768 
01769     _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
01770 
01771     return CAIRO_STATUS_SUCCESS;
01772 }
01773 
01774 static cairo_status_t 
01775 _cairo_ft_scaled_font_glyph_extents (void               *abstract_font,
01776                                  cairo_glyph_t          *glyphs, 
01777                                  int                    num_glyphs,
01778                                  cairo_text_extents_t   *extents)
01779 {
01780     int i;
01781     cairo_ft_scaled_font_t *scaled_font = abstract_font;
01782     cairo_point_double_t origin;
01783     cairo_point_double_t glyph_min, glyph_max;
01784     /* Initialize just to squelch anti-helpful compiler warning. */
01785     cairo_point_double_t total_min = { 0, 0}, total_max = {0,0};
01786 
01787     cairo_image_glyph_cache_entry_t *img = NULL;
01788     cairo_cache_t *cache;
01789     cairo_glyph_cache_key_t key;
01790 
01791     if (num_glyphs == 0)
01792     {
01793        extents->x_bearing = 0.0;
01794        extents->y_bearing = 0.0;
01795        extents->width  = 0.0;
01796        extents->height = 0.0;
01797        extents->x_advance = 0.0;
01798        extents->y_advance = 0.0;
01799 
01800        return CAIRO_STATUS_SUCCESS;
01801     }
01802 
01803     origin.x = glyphs[0].x;
01804     origin.y = glyphs[0].y;
01805 
01806     _cairo_lock_global_image_glyph_cache ();
01807     cache = _cairo_get_global_image_glyph_cache ();
01808     if (cache == NULL) {
01809        _cairo_unlock_global_image_glyph_cache ();
01810        return CAIRO_STATUS_NO_MEMORY;
01811     }
01812     
01813     _cairo_ft_scaled_font_get_glyph_cache_key (scaled_font, &key);
01814 
01815     for (i = 0; i < num_glyphs; i++)
01816     {
01817        img = NULL;
01818        key.index = glyphs[i].index;
01819        if (_cairo_cache_lookup (cache, &key, (void **) &img, NULL) 
01820            != CAIRO_STATUS_SUCCESS || img == NULL)
01821            continue;
01822        
01823        /* XXX: Need to add code here to check the font's FcPattern
01824            for FC_VERTICAL_LAYOUT and if set get vertBearingX/Y
01825            instead. This will require that
01826            cairo_ft_font_face_create_for_ft_face accept an
01827            FcPattern. */
01828        glyph_min.x = glyphs[i].x + img->extents.x_bearing;
01829        glyph_min.y = glyphs[i].y + img->extents.y_bearing;
01830        glyph_max.x = glyph_min.x + img->extents.width;
01831        glyph_max.y = glyph_min.y + img->extents.height;
01832     
01833        if (i==0) {
01834            total_min = glyph_min;
01835            total_max = glyph_max;
01836        } else {
01837            if (glyph_min.x < total_min.x)
01838               total_min.x = glyph_min.x;
01839            if (glyph_min.y < total_min.y)
01840               total_min.y = glyph_min.y;
01841 
01842            if (glyph_max.x > total_max.x)
01843               total_max.x = glyph_max.x;
01844            if (glyph_max.y > total_max.y)
01845               total_max.y = glyph_max.y;
01846        }
01847     }
01848     _cairo_unlock_global_image_glyph_cache ();
01849 
01850     extents->x_bearing = (total_min.x - origin.x);
01851     extents->y_bearing = (total_min.y - origin.y);
01852     extents->width     = (total_max.x - total_min.x);
01853     extents->height    = (total_max.y - total_min.y);
01854     extents->x_advance = glyphs[i-1].x + (img == NULL ? 0 : img->extents.x_advance) - origin.x;
01855     extents->y_advance = glyphs[i-1].y + (img == NULL ? 0 : img->extents.y_advance) - origin.y;
01856 
01857     return CAIRO_STATUS_SUCCESS;
01858 }
01859 
01860 
01861 static cairo_status_t 
01862 _cairo_ft_scaled_font_glyph_bbox (void                 *abstract_font,
01863                               const cairo_glyph_t *glyphs,
01864                               int                  num_glyphs,
01865                               cairo_box_t         *bbox)
01866 {
01867     cairo_image_glyph_cache_entry_t *img;
01868     cairo_cache_t *cache;
01869     cairo_glyph_cache_key_t key;
01870     cairo_ft_scaled_font_t *scaled_font = abstract_font;
01871 
01872     cairo_fixed_t x1, y1, x2, y2;
01873     int i;
01874 
01875     bbox->p1.x = bbox->p1.y = CAIRO_MAXSHORT << 16;
01876     bbox->p2.x = bbox->p2.y = CAIRO_MINSHORT << 16;
01877 
01878     _cairo_lock_global_image_glyph_cache ();
01879     cache = _cairo_get_global_image_glyph_cache();
01880 
01881     if (cache == NULL 
01882        || scaled_font == NULL
01883        || glyphs == NULL) {
01884        _cairo_unlock_global_image_glyph_cache ();
01885         return CAIRO_STATUS_NO_MEMORY;
01886     }
01887 
01888     _cairo_ft_scaled_font_get_glyph_cache_key (scaled_font, &key);
01889     
01890     for (i = 0; i < num_glyphs; i++)
01891     {
01892 
01893        img = NULL;
01894        key.index = glyphs[i].index;
01895 
01896        if (_cairo_cache_lookup (cache, &key, (void **) &img, NULL) 
01897            != CAIRO_STATUS_SUCCESS || img == NULL)
01898            continue;
01899 
01900        x1 = _cairo_fixed_from_double (glyphs[i].x + img->size.x);
01901        y1 = _cairo_fixed_from_double (glyphs[i].y + img->size.y);
01902        x2 = x1 + _cairo_fixed_from_double (img->size.width);
01903        y2 = y1 + _cairo_fixed_from_double (img->size.height);
01904        
01905        if (x1 < bbox->p1.x)
01906            bbox->p1.x = x1;
01907        
01908        if (y1 < bbox->p1.y)
01909            bbox->p1.y = y1;
01910        
01911        if (x2 > bbox->p2.x)
01912            bbox->p2.x = x2;
01913        
01914        if (y2 > bbox->p2.y)
01915            bbox->p2.y = y2;
01916     }
01917     _cairo_unlock_global_image_glyph_cache ();
01918 
01919     return CAIRO_STATUS_SUCCESS;
01920 }
01921 
01922 static cairo_format_t
01923 _select_text_mask_format (cairo_bool_t        have_a1_glyphs,
01924                        cairo_bool_t           have_a8_glyphs,
01925                        cairo_bool_t           have_argb32_glyphs)
01926 {
01927     if (have_a8_glyphs)
01928        return CAIRO_FORMAT_A8;
01929 
01930     if (have_a1_glyphs && have_argb32_glyphs)
01931        return CAIRO_FORMAT_A8;
01932 
01933     if (have_a1_glyphs)
01934        return CAIRO_FORMAT_A1;
01935 
01936     if (have_argb32_glyphs)
01937        return CAIRO_FORMAT_ARGB32;
01938 
01939     /* when there are no glyphs to draw, just pick something */
01940     return CAIRO_FORMAT_A8;
01941 }
01942 
01943 static cairo_status_t 
01944 _cairo_ft_scaled_font_show_glyphs (void                 *abstract_font,
01945                                cairo_operator_t         operator,
01946                                cairo_pattern_t     *pattern,
01947                                cairo_surface_t     *surface,
01948                                int                      source_x,
01949                                int                      source_y,
01950                                int               dest_x,
01951                                int               dest_y,
01952                                unsigned int             width,
01953                                unsigned int             height,
01954                                const cairo_glyph_t *glyphs,
01955                                int                      num_glyphs)
01956 {
01957     cairo_image_glyph_cache_entry_t **entries;
01958     cairo_cache_t *cache;
01959     cairo_glyph_cache_key_t key;
01960     cairo_ft_scaled_font_t *scaled_font = abstract_font;
01961     cairo_surface_pattern_t glyph_pattern;
01962     cairo_surface_t *mask;
01963     cairo_surface_pattern_t mask_pattern;
01964     cairo_format_t mask_format = CAIRO_FORMAT_A1;
01965     cairo_status_t status = CAIRO_STATUS_SUCCESS;
01966     cairo_bool_t have_a1_glyphs, have_a8_glyphs, have_argb32_glyphs;
01967     int x, y;
01968     int i;
01969 
01970     _cairo_lock_global_image_glyph_cache ();
01971     cache = _cairo_get_global_image_glyph_cache();
01972 
01973     if (cache == NULL
01974        || scaled_font == NULL 
01975         || pattern == NULL 
01976         || surface == NULL 
01977         || glyphs == NULL) {
01978        _cairo_unlock_global_image_glyph_cache ();
01979         return CAIRO_STATUS_NO_MEMORY;
01980     }
01981 
01982     key.unscaled = &scaled_font->unscaled->base;
01983     key.scale = scaled_font->base.scale;
01984     key.flags = scaled_font->load_flags;
01985 
01986     entries = malloc (num_glyphs * sizeof (cairo_image_glyph_cache_entry_t));
01987     if (!entries)
01988        goto CLEANUP_CACHE;
01989 
01990     have_a1_glyphs = FALSE;
01991     have_a8_glyphs = FALSE;
01992     have_argb32_glyphs = FALSE;
01993     
01994     for (i = 0; i < num_glyphs; i++)
01995     {
01996        entries[i] = NULL;
01997        key.index = glyphs[i].index;
01998 
01999        if (_cairo_cache_lookup (cache, &key, (void **) &entries[i], NULL) != CAIRO_STATUS_SUCCESS)
02000            continue;
02001 
02002        switch (entries[i]->image->format) {
02003        case CAIRO_FORMAT_A1:
02004            have_a1_glyphs = TRUE;
02005            break;
02006        case CAIRO_FORMAT_A8:
02007            have_a8_glyphs = TRUE;
02008            break;
02009        case CAIRO_FORMAT_ARGB32:
02010            have_argb32_glyphs = TRUE;
02011            break;
02012        default:
02013            break;
02014        }
02015     }
02016 
02017     mask_format = _select_text_mask_format (have_a1_glyphs, have_a8_glyphs, have_argb32_glyphs);
02018 
02019     mask = cairo_image_surface_create (mask_format, width, height);
02020     if (!mask)
02021        goto CLEANUP_ENTRIES;
02022 
02023     status = _cairo_surface_fill_rectangle (mask, CAIRO_OPERATOR_CLEAR,
02024                                        CAIRO_COLOR_TRANSPARENT,
02025                                        0, 0, width, height);
02026     if (status)
02027        goto CLEANUP_MASK;
02028        
02029     for (i = 0; i < num_glyphs; i++)
02030     {
02031        if (entries[i] == NULL 
02032            || entries[i]->image == NULL)
02033            continue;
02034    
02035        x = (int) floor (glyphs[i].x + 0.5);
02036        y = (int) floor (glyphs[i].y + 0.5);
02037 
02038        _cairo_pattern_init_for_surface (&glyph_pattern, &(entries[i]->image->base));
02039 
02040        status = _cairo_surface_composite (CAIRO_OPERATOR_ADD, &glyph_pattern.base,
02041                                       NULL,
02042                                       mask,
02043                                       0, 0,
02044                                       0, 0, 
02045                                       x + entries[i]->size.x - dest_x, 
02046                                       y + entries[i]->size.y - dest_y, 
02047                                       entries[i]->size.width,
02048                                       entries[i]->size.height);
02049 
02050        _cairo_pattern_fini (&glyph_pattern.base);
02051 
02052        if (status)
02053            goto CLEANUP_MASK;
02054     }
02055 
02056     if (mask_format == CAIRO_FORMAT_ARGB32)
02057        pixman_image_set_component_alpha (((cairo_image_surface_t *)mask)->pixman_image, TRUE);
02058       
02059     _cairo_pattern_init_for_surface (&mask_pattern, mask);
02060 
02061     status = _cairo_surface_composite (operator, pattern, &mask_pattern.base,
02062                                    surface,
02063                                    source_x, source_y, 
02064                                    0,        0,
02065                                    dest_x,   dest_y,
02066                                    width,    height);
02067 
02068     _cairo_pattern_fini (&mask_pattern.base);
02069        
02070  CLEANUP_MASK:
02071     cairo_surface_destroy (mask);
02072 
02073  CLEANUP_ENTRIES:
02074     free (entries);
02075 
02076  CLEANUP_CACHE:
02077     _cairo_unlock_global_image_glyph_cache ();
02078 
02079     return status;
02080 }
02081 
02082 
02083 static int
02084 _move_to (FT_Vector *to, void *closure)
02085 {
02086     cairo_path_fixed_t *path = closure;
02087     cairo_fixed_t x, y;
02088 
02089     x = _cairo_fixed_from_26_6 (to->x);
02090     y = _cairo_fixed_from_26_6 (to->y);
02091 
02092     _cairo_path_fixed_close_path (path);
02093     _cairo_path_fixed_move_to (path, x, y);
02094 
02095     return 0;
02096 }
02097 
02098 static int
02099 _line_to (FT_Vector *to, void *closure)
02100 {
02101     cairo_path_fixed_t *path = closure;
02102     cairo_fixed_t x, y;
02103 
02104     x = _cairo_fixed_from_26_6 (to->x);
02105     y = _cairo_fixed_from_26_6 (to->y);
02106 
02107     _cairo_path_fixed_line_to (path, x, y);
02108 
02109     return 0;
02110 }
02111 
02112 static int
02113 _conic_to (FT_Vector *control, FT_Vector *to, void *closure)
02114 {
02115     cairo_path_fixed_t *path = closure;
02116 
02117     cairo_fixed_t x0, y0;
02118     cairo_fixed_t x1, y1;
02119     cairo_fixed_t x2, y2;
02120     cairo_fixed_t x3, y3;
02121     cairo_point_t conic;
02122 
02123     _cairo_path_fixed_get_current_point (path, &x0, &y0);
02124 
02125     conic.x = _cairo_fixed_from_26_6 (control->x);
02126     conic.y = _cairo_fixed_from_26_6 (control->y);
02127 
02128     x3 = _cairo_fixed_from_26_6 (to->x);
02129     y3 = _cairo_fixed_from_26_6 (to->y);
02130 
02131     x1 = x0 + 2.0/3.0 * (conic.x - x0);
02132     y1 = y0 + 2.0/3.0 * (conic.y - y0);
02133 
02134     x2 = x3 + 2.0/3.0 * (conic.x - x3);
02135     y2 = y3 + 2.0/3.0 * (conic.y - y3);
02136 
02137     _cairo_path_fixed_curve_to (path,
02138                             x1, y1,
02139                             x2, y2,
02140                             x3, y3);
02141 
02142     return 0;
02143 }
02144 
02145 static int
02146 _cubic_to (FT_Vector *control1, FT_Vector *control2,
02147           FT_Vector *to, void *closure)
02148 {
02149     cairo_path_fixed_t *path = closure;
02150     cairo_fixed_t x0, y0;
02151     cairo_fixed_t x1, y1;
02152     cairo_fixed_t x2, y2;
02153 
02154     x0 = _cairo_fixed_from_26_6 (control1->x);
02155     y0 = _cairo_fixed_from_26_6 (control1->y);
02156 
02157     x1 = _cairo_fixed_from_26_6 (control2->x);
02158     y1 = _cairo_fixed_from_26_6 (control2->y);
02159 
02160     x2 = _cairo_fixed_from_26_6 (to->x);
02161     y2 = _cairo_fixed_from_26_6 (to->y);
02162 
02163     _cairo_path_fixed_curve_to (path,
02164                             x0, y0,
02165                             x1, y1,
02166                             x2, y2);
02167 
02168     return 0;
02169 }
02170 
02171 static cairo_status_t 
02172 _cairo_ft_scaled_font_glyph_path (void                *abstract_font,
02173                               cairo_glyph_t           *glyphs, 
02174                               int               num_glyphs,
02175                               cairo_path_fixed_t *path)
02176 {
02177     int i;
02178     cairo_ft_scaled_font_t *scaled_font = abstract_font;
02179     FT_GlyphSlot glyph;
02180     FT_Face face;
02181     FT_Error error;
02182     FT_Outline_Funcs outline_funcs = {
02183        _move_to,
02184        _line_to,
02185        _conic_to,
02186        _cubic_to,
02187        0, /* shift */
02188        0, /* delta */
02189     };
02190     
02191     face = cairo_ft_scaled_font_lock_face (abstract_font);
02192     if (!face)
02193        return CAIRO_STATUS_NO_MEMORY;
02194 
02195     glyph = face->glyph;
02196 
02197     for (i = 0; i < num_glyphs; i++)
02198     {
02199        FT_Matrix invert_y = {
02200            DOUBLE_TO_16_16 (1.0), 0,
02201            0, DOUBLE_TO_16_16 (-1.0),
02202        };
02203 
02204        error = FT_Load_Glyph (scaled_font->unscaled->face, glyphs[i].index,
02205                             (scaled_font->load_flags & ~PRIVATE_FLAGS_MASK) | FT_LOAD_NO_BITMAP);
02206        /* XXX: What to do in this error case? */
02207        if (error)
02208            continue;
02209        /* XXX: Do we want to support bitmap fonts here? */
02210        if (glyph->format == ft_glyph_format_bitmap)
02211            continue;
02212 
02213 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
02214         /*
02215          * embolden glyhps if required
02216          */
02217         if (scaled_font->load_flags & PRIVATE_FLAG_EMBOLDEN && 
02218            (face->style_flags & FT_STYLE_FLAG_BOLD) == 0)
02219            FT_GlyphSlot_Embolden (glyph);
02220 #endif
02221        
02222        /* Font glyphs have an inverted Y axis compared to cairo. */
02223        FT_Outline_Transform (&glyph->outline, &invert_y);
02224        FT_Outline_Translate (&glyph->outline,
02225                            DOUBLE_TO_26_6(glyphs[i].x),
02226                            DOUBLE_TO_26_6(glyphs[i].y));
02227        FT_Outline_Decompose (&glyph->outline, &outline_funcs, path);
02228     }
02229     _cairo_path_fixed_close_path (path);
02230 
02231     cairo_ft_scaled_font_unlock_face (abstract_font);
02232     
02233     return CAIRO_STATUS_SUCCESS;
02234 }
02235 
02236 const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend = {
02237     _cairo_ft_scaled_font_create_toy,
02238     _cairo_ft_scaled_font_fini,
02239     _cairo_ft_scaled_font_font_extents,
02240     _cairo_ft_scaled_font_text_to_glyphs,
02241     _cairo_ft_scaled_font_glyph_extents,
02242     _cairo_ft_scaled_font_glyph_bbox,
02243     _cairo_ft_scaled_font_show_glyphs,
02244     _cairo_ft_scaled_font_glyph_path,
02245     _cairo_ft_scaled_font_get_glyph_cache_key
02246 };
02247 
02248 /* cairo_ft_font_face_t */
02249 
02250 static void
02251 _cairo_ft_font_face_destroy (void *abstract_face)
02252 {
02253     cairo_ft_font_face_t *font_face = abstract_face;
02254     
02255     cairo_ft_font_face_t *tmp_face = NULL;
02256     cairo_ft_font_face_t *last_face = NULL;
02257 
02258     if (font_face == NULL)
02259        return;
02260 
02261     /* When destroying the face created by cairo_ft_font_face_create_for_ft_face,
02262      * we have a special "zombie" state for the face when the unscaled font
02263      * is still alive but there are no public references to the font face.
02264      *
02265      * We go from:
02266      *
02267      *   font_face ------> unscaled
02268      *        <-....weak....../
02269      *
02270      * To:
02271      *
02272      *    font_face <------- unscaled
02273      */
02274 
02275     if (font_face->unscaled &&
02276        font_face->unscaled->from_face &&
02277        font_face->unscaled->base.ref_count > 1)
02278     {
02279        cairo_font_face_reference (&font_face->base);
02280        
02281        _cairo_unscaled_font_destroy (&font_face->unscaled->base);
02282        font_face->unscaled = NULL;
02283        
02284        return;
02285     }
02286     
02287     if (font_face->unscaled) {
02288        /* Remove face from linked list */
02289        for (tmp_face = font_face->unscaled->faces;
02290             tmp_face;
02291             tmp_face = tmp_face->next)
02292        {
02293            if (tmp_face == font_face) {
02294               if (last_face)
02295                   last_face->next = tmp_face->next;
02296               else
02297                   font_face->unscaled->faces = tmp_face->next;
02298            }
02299            
02300            last_face = tmp_face;
02301        }
02302 
02303        _cairo_unscaled_font_destroy (&font_face->unscaled->base);
02304        font_face->unscaled = NULL;
02305     }
02306 }
02307 
02308 static cairo_status_t
02309 _cairo_ft_font_face_scaled_font_create (void                     *abstract_face,
02310                                    const cairo_matrix_t       *font_matrix,
02311                                    const cairo_matrix_t       *ctm,
02312                                    const cairo_font_options_t *options,
02313                                    cairo_scaled_font_t       **scaled_font)
02314 {
02315     cairo_ft_font_face_t *font_face = abstract_face;
02316     int load_flags;
02317 
02318     /* The handling of font options is different depending on how the
02319      * font face was created. When the user creates a font face with
02320      * cairo_ft_font_face_create_for_ft_face(), then the load flags
02321      * passed in augment the load flags for the options.  But for
02322      * cairo_ft_font_face_create_for_pattern(), the load flags are
02323      * derived from a pattern where the user has called
02324      * cairo_ft_font_options_substitute(), so *just* use those load
02325      * flags and ignore the options.
02326      */
02327     if (font_face->unscaled->from_face)
02328        load_flags = _get_options_load_flags (options) | font_face->load_flags;
02329     else
02330        load_flags = font_face->load_flags;
02331 
02332     *scaled_font = _cairo_ft_scaled_font_create (font_face->unscaled,
02333                                            &font_face->base,
02334                                            font_matrix, ctm,
02335                                            options, load_flags);
02336     if (*scaled_font)
02337        return CAIRO_STATUS_SUCCESS;
02338     else
02339        return CAIRO_STATUS_NO_MEMORY;
02340 }
02341 
02342 static const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
02343     _cairo_ft_font_face_destroy,
02344     _cairo_ft_font_face_scaled_font_create
02345 };
02346 
02347 static cairo_font_face_t *
02348 _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
02349                          int                           load_flags)
02350 {
02351     cairo_ft_font_face_t *font_face;
02352 
02353     /* Looked for an existing matching font face */
02354     for (font_face = unscaled->faces;
02355         font_face;
02356         font_face = font_face->next)
02357     {
02358        if (font_face->load_flags == load_flags)
02359            return cairo_font_face_reference (&font_face->base);
02360     }
02361 
02362     /* No match found, create a new one */
02363     font_face = malloc (sizeof (cairo_ft_font_face_t));
02364     if (!font_face)
02365        return NULL;
02366     
02367     font_face->unscaled = unscaled;
02368     _cairo_unscaled_font_reference (&unscaled->base);
02369     
02370     font_face->load_flags = load_flags;
02371 
02372     font_face->next = unscaled->faces;
02373     unscaled->faces = font_face;
02374     
02375     _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend);
02376 
02377     return &font_face->base;
02378 }
02379 
02380 /* implement the platform-specific interface */
02381 
02393 void
02394 cairo_ft_font_options_substitute (const cairo_font_options_t *options,
02395                               FcPattern                  *pattern)
02396 {
02397     FcValue v;
02398 
02399     if (options->antialias != CAIRO_ANTIALIAS_DEFAULT)
02400     {
02401        if (FcPatternGet (pattern, FC_ANTIALIAS, 0, &v) == FcResultNoMatch)
02402        {
02403            FcPatternAddBool (pattern, FC_ANTIALIAS, options->antialias != CAIRO_ANTIALIAS_NONE);
02404        }
02405     }
02406 
02407     if (options->antialias != CAIRO_ANTIALIAS_DEFAULT)
02408     {
02409        if (FcPatternGet (pattern, FC_RGBA, 0, &v) == FcResultNoMatch)
02410        {
02411            int rgba;
02412            
02413            if (options->antialias == CAIRO_ANTIALIAS_SUBPIXEL) {
02414               switch (options->subpixel_order) {
02415               case CAIRO_SUBPIXEL_ORDER_DEFAULT:
02416               case CAIRO_SUBPIXEL_ORDER_RGB:
02417               default:
02418                   rgba = FC_RGBA_RGB;
02419                   break;
02420               case CAIRO_SUBPIXEL_ORDER_BGR:
02421                   rgba = FC_RGBA_BGR;
02422                   break;
02423               case CAIRO_SUBPIXEL_ORDER_VRGB:
02424                   rgba = FC_RGBA_VRGB;
02425                   break;
02426               case CAIRO_SUBPIXEL_ORDER_VBGR:
02427                   rgba = FC_RGBA_VBGR;
02428                   break;
02429               }
02430            } else {
02431               rgba = FC_RGBA_NONE;
02432            }
02433            
02434            FcPatternAddInteger (pattern, FC_RGBA, rgba);
02435        }
02436     }
02437 
02438     if (options->hint_style != CAIRO_HINT_STYLE_DEFAULT)
02439     {
02440        if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch)
02441        {
02442            FcPatternAddBool (pattern, FC_HINTING, options->hint_style != CAIRO_HINT_STYLE_NONE);
02443        }
02444 
02445 #ifdef FC_HINT_STYLE 
02446        if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch)
02447        {
02448            int hint_style;
02449 
02450            switch (options->hint_style) {
02451            case CAIRO_HINT_STYLE_SLIGHT:
02452               hint_style = FC_HINT_SLIGHT;
02453               break;
02454            case CAIRO_HINT_STYLE_MEDIUM:
02455               hint_style = FC_HINT_MEDIUM;
02456               break;
02457            case CAIRO_HINT_STYLE_FULL:
02458            default:
02459               hint_style = FC_HINT_FULL;
02460               break;
02461            }
02462            
02463            FcPatternAddInteger (pattern, FC_HINT_STYLE, hint_style);
02464        }
02465 #endif 
02466     }
02467 }
02468 
02494 cairo_font_face_t *
02495 cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
02496 {
02497     cairo_ft_unscaled_font_t *unscaled;
02498     cairo_font_face_t *font_face;
02499 
02500     unscaled = _cairo_ft_unscaled_font_create_for_pattern (pattern);
02501     if (unscaled == NULL) {
02502        _cairo_error (CAIRO_STATUS_NO_MEMORY);
02503        return (cairo_font_face_t *)&_cairo_font_face_nil;
02504     }
02505 
02506     font_face = _cairo_ft_font_face_create (unscaled,
02507                                        _get_pattern_load_flags (pattern));
02508     _cairo_unscaled_font_destroy (&unscaled->base);
02509 
02510     if (font_face)
02511        return font_face;
02512     else {
02513        _cairo_error (CAIRO_STATUS_NO_MEMORY);
02514        return (cairo_font_face_t *)&_cairo_font_face_nil;
02515     }
02516 }
02517 
02543 cairo_font_face_t *
02544 cairo_ft_font_face_create_for_ft_face (FT_Face         face,
02545                                    int             load_flags)
02546 {
02547     cairo_ft_unscaled_font_t *unscaled;
02548     cairo_font_face_t *font_face;
02549 
02550     unscaled = _cairo_ft_unscaled_font_create_from_face (face);
02551     if (unscaled == NULL) {
02552        _cairo_error (CAIRO_STATUS_NO_MEMORY);
02553        return (cairo_font_face_t *)&_cairo_font_face_nil;
02554     }
02555 
02556     font_face = _cairo_ft_font_face_create (unscaled, load_flags);
02557     _cairo_unscaled_font_destroy (&unscaled->base);
02558 
02559     if (font_face) {
02560        return font_face;
02561     } else {
02562        _cairo_error (CAIRO_STATUS_NO_MEMORY);
02563        return (cairo_font_face_t *)&_cairo_font_face_nil;
02564     }
02565 }
02566 
02596 FT_Face
02597 cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font)
02598 {
02599     cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
02600     FT_Face face;
02601 
02602     if (scaled_font->base.status)
02603        return NULL;
02604 
02605     face = _cairo_ft_unscaled_font_lock_face (scaled_font->unscaled);
02606     if (face == NULL) {
02607        _cairo_scaled_font_set_error (&scaled_font->base, CAIRO_STATUS_NO_MEMORY);
02608        return NULL;
02609     }
02610     
02611     _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
02612                                    &scaled_font->base.scale);
02613 
02614     return face;
02615 }
02616 
02626 void
02627 cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t *abstract_font)
02628 {
02629     cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
02630 
02631     if (scaled_font->base.status)
02632        return;
02633 
02634     _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
02635 }
02636 
02637 /* We expose our unscaled font implementation internally for the the
02638  * PDF backend, which needs to keep track of the the different
02639  * fonts-on-disk used by a document, so it can embed them.
02640  */
02641 cairo_unscaled_font_t *
02642 _cairo_ft_scaled_font_get_unscaled_font (cairo_scaled_font_t *abstract_font)
02643 {
02644     cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
02645 
02646     return &scaled_font->unscaled->base;
02647 }
02648 
02649 void
02650 _cairo_ft_font_reset_static_data (void)
02651 {
02652     _cairo_ft_unscaled_font_map_destroy ();
02653 }