1bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/***************************************************************************/
2bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/*                                                                         */
3bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/*  ftcbasic.c                                                             */
4bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/*                                                                         */
5bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/*    The FreeType basic cache interface (body).                           */
6bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/*                                                                         */
79c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod/*  Copyright 2003-2007, 2009-2011, 2013, 2014 by                          */
8bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/*                                                                         */
10bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/*  This file is part of the FreeType project, and may only be used,       */
11bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/*  modified, and distributed under the terms of the FreeType project      */
12bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/*  this file you indicate that you have read the license and              */
14bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/*  understand and accept it fully.                                        */
15bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/*                                                                         */
16bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/***************************************************************************/
17bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
18bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
19bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#include <ft2build.h>
20bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#include FT_INTERNAL_OBJECTS_H
21bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#include FT_INTERNAL_DEBUG_H
22bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#include FT_CACHE_H
23bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#include "ftcglyph.h"
24bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#include "ftcimage.h"
25bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#include "ftcsbits.h"
26bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
27bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#include "ftccback.h"
28bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#include "ftcerror.h"
29bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
30bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define FT_COMPONENT  trace_cache
31bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
32bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
33bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  /*
34bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly   *  Basic Families
35bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly   *
36bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly   */
37bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  typedef struct  FTC_BasicAttrRec_
38bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
39bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_ScalerRec  scaler;
40bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_UInt        load_flags;
41bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
42bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  } FTC_BasicAttrRec, *FTC_BasicAttrs;
43bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
44bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define FTC_BASIC_ATTR_COMPARE( a, b )                                 \
45bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \
46bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                   (a)->load_flags == (b)->load_flags               )
47bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
48bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define FTC_BASIC_ATTR_HASH( a )                                   \
49bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags )
50bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
51bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
52bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  typedef struct  FTC_BasicQueryRec_
53bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
54bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_GQueryRec     gquery;
55bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_BasicAttrRec  attrs;
56bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
57bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  } FTC_BasicQueryRec, *FTC_BasicQuery;
58bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
59bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
60bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  typedef struct  FTC_BasicFamilyRec_
61bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
62bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_FamilyRec     family;
63bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_BasicAttrRec  attrs;
64bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
65bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  } FTC_BasicFamilyRec, *FTC_BasicFamily;
66bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
67bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
68bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_CALLBACK_DEF( FT_Bool )
69bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  ftc_basic_family_compare( FTC_MruNode  ftcfamily,
70bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                            FT_Pointer   ftcquery )
71bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
72bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;
73bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_BasicQuery   query  = (FTC_BasicQuery)ftcquery;
74bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
75bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
76bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    return FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs );
77bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  }
78bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
79bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
80bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_CALLBACK_DEF( FT_Error )
81bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  ftc_basic_family_init( FTC_MruNode  ftcfamily,
82bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                         FT_Pointer   ftcquery,
83bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                         FT_Pointer   ftccache )
84bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
85bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;
86bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_BasicQuery   query  = (FTC_BasicQuery)ftcquery;
87bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_Cache        cache  = (FTC_Cache)ftccache;
88bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
89bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
90bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_Family_Init( FTC_FAMILY( family ), cache );
91bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    family->attrs = query->attrs;
92bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    return 0;
93bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  }
94bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
95bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
96bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_CALLBACK_DEF( FT_UInt )
97bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  ftc_basic_family_get_count( FTC_Family   ftcfamily,
98bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                              FTC_Manager  manager )
99bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
100bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;
101bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Error         error;
102bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Face          face;
103bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_UInt          result = 0;
104bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
105bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
106bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id,
107bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                                    &face );
108bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
109bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( error || !face )
110bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      return result;
111bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
112bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs )
113bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
114bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE1(( "ftc_basic_family_get_count: too large number of glyphs " ));
115bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE1(( "in this face, truncated\n", face->num_glyphs ));
116bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
117bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
118bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( !error )
119bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      result = (FT_UInt)face->num_glyphs;
120bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
121bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    return result;
122bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  }
123bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
124bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
125bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_CALLBACK_DEF( FT_Error )
126bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  ftc_basic_family_load_bitmap( FTC_Family   ftcfamily,
127bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                                FT_UInt      gindex,
128bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                                FTC_Manager  manager,
129bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                                FT_Face     *aface )
130bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
131bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;
132bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Error         error;
133bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Size          size;
134bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
135bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
136bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size );
137bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( !error )
138bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
139bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_Face  face = size->face;
140bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
141bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
142bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      error = FT_Load_Glyph( face, gindex,
143bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                             family->attrs.load_flags | FT_LOAD_RENDER );
144bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      if ( !error )
145bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        *aface = face;
146bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
147bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
148bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    return error;
149bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  }
150bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
151bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
152bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_CALLBACK_DEF( FT_Error )
153bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  ftc_basic_family_load_glyph( FTC_Family  ftcfamily,
154bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                               FT_UInt     gindex,
155bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                               FTC_Cache   cache,
156bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                               FT_Glyph   *aglyph )
157bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
158bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;
159bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Error         error;
160bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_Scaler       scaler = &family->attrs.scaler;
161bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Face          face;
162bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Size          size;
163bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
164bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
165bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    /* we will now load the glyph image */
166bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    error = FTC_Manager_LookupSize( cache->manager,
167bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                                    scaler,
168bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                                    &size );
169bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( !error )
170bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
171bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      face = size->face;
172bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
173bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      error = FT_Load_Glyph( face, gindex, family->attrs.load_flags );
174bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      if ( !error )
175bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      {
176bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP  ||
177bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly             face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
178bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        {
179bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          /* ok, copy it */
180bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          FT_Glyph  glyph;
181bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
182bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
183bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          error = FT_Get_Glyph( face->glyph, &glyph );
184bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          if ( !error )
185bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          {
186bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            *aglyph = glyph;
187bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            goto Exit;
188bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          }
189bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        }
190bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        else
191727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          error = FT_THROW( Invalid_Argument );
192bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      }
193bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
194bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
195bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  Exit:
196bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    return error;
197bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  }
198bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
199bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
200bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_CALLBACK_DEF( FT_Bool )
201bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  ftc_basic_gnode_compare_faceid( FTC_Node    ftcgnode,
202bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                                  FT_Pointer  ftcface_id,
203bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                                  FTC_Cache   cache,
204bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                                  FT_Bool*    list_changed )
205bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
206bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_GNode        gnode   = (FTC_GNode)ftcgnode;
207bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_FaceID       face_id = (FTC_FaceID)ftcface_id;
208bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_BasicFamily  family  = (FTC_BasicFamily)gnode->family;
209bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Bool          result;
210bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
211bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
212bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( list_changed )
213bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      *list_changed = FALSE;
214bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    result = FT_BOOL( family->attrs.scaler.face_id == face_id );
215bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( result )
216bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
217bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      /* we must call this function to avoid this node from appearing
218bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly       * in later lookups with the same face_id!
219bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly       */
220bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FTC_GNode_UnselectFamily( gnode, cache );
221bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
222bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    return result;
223bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  }
224bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
225bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
226bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly /*
227bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  *
228bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  * basic image cache
229bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  *
230bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  */
231bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2329c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  static
233bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  const FTC_IFamilyClassRec  ftc_basic_image_family_class =
234bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
235bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
236bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      sizeof ( FTC_BasicFamilyRec ),
237bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_basic_family_compare,
238bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_basic_family_init,
239bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      0,                        /* FTC_MruNode_ResetFunc */
240bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      0                         /* FTC_MruNode_DoneFunc  */
241bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    },
242bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    ftc_basic_family_load_glyph
243bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  };
244bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
245bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2469c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  static
247bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  const FTC_GCacheClassRec  ftc_basic_image_cache_class =
248bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
249bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
250bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_inode_new,
251bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_inode_weight,
252bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_gnode_compare,
253bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_basic_gnode_compare_faceid,
254bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_inode_free,
255bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
256bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      sizeof ( FTC_GCacheRec ),
257bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_gcache_init,
258bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_gcache_done
259bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    },
260bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    (FTC_MruListClass)&ftc_basic_image_family_class
261bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  };
262bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
263bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
264bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  /* documentation is in ftcache.h */
265bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
266bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_EXPORT_DEF( FT_Error )
267bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FTC_ImageCache_New( FTC_Manager      manager,
268bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                      FTC_ImageCache  *acache )
269bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
270bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    return FTC_GCache_New( manager, &ftc_basic_image_cache_class,
271bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           (FTC_GCache*)acache );
272bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  }
273bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
274bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
275bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  /* documentation is in ftcache.h */
276bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
277bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_EXPORT_DEF( FT_Error )
278bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FTC_ImageCache_Lookup( FTC_ImageCache  cache,
279bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                         FTC_ImageType   type,
280bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                         FT_UInt         gindex,
281bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                         FT_Glyph       *aglyph,
282bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                         FTC_Node       *anode )
283bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
284bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_BasicQueryRec  query;
285bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_Node           node = 0; /* make compiler happy */
286bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Error           error;
287bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_PtrDist         hash;
288bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
289bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
290bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    /* some argument checks are delayed to FTC_Cache_Lookup */
291bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( !aglyph )
292bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
293727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_Argument );
294bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      goto Exit;
295bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
296bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
297bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    *aglyph = NULL;
298bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( anode )
299bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      *anode  = NULL;
300bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
301bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
302bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX )
303bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      {
304bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" ));
305bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) ));
306bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      }
307bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
308bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      query.attrs.scaler.face_id = type->face_id;
309bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      query.attrs.scaler.width   = type->width;
310bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      query.attrs.scaler.height  = type->height;
311bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      query.attrs.load_flags     = (FT_UInt)type->flags;
312bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
313bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
314bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    query.attrs.scaler.pixel = 1;
315bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    query.attrs.scaler.x_res = 0;  /* make compilers happy */
316bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    query.attrs.scaler.y_res = 0;
317bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
318bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;
319bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
320bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#if 1  /* inlining is about 50% faster! */
321bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_GCACHE_LOOKUP_CMP( cache,
322bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           ftc_basic_family_compare,
323bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           FTC_GNode_Compare,
324bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           hash, gindex,
325bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           &query,
326bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           node,
327bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           error );
328bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#else
329bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
330bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                               hash, gindex,
331bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                               FTC_GQUERY( &query ),
332bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                               &node );
333bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#endif
334bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( !error )
335bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
336bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      *aglyph = FTC_INODE( node )->glyph;
337bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
338bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      if ( anode )
339bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      {
340bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        *anode = node;
341bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        node->ref_count++;
342bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      }
343bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
344bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
345bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  Exit:
346bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    return error;
347bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  }
348bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
349bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
350bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  /* documentation is in ftcache.h */
351bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
352bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_EXPORT_DEF( FT_Error )
353bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FTC_ImageCache_LookupScaler( FTC_ImageCache  cache,
354bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                               FTC_Scaler      scaler,
355bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                               FT_ULong        load_flags,
356bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                               FT_UInt         gindex,
357bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                               FT_Glyph       *aglyph,
358bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                               FTC_Node       *anode )
359bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
360bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_BasicQueryRec  query;
361bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_Node           node = 0; /* make compiler happy */
362bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Error           error;
363bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_PtrDist         hash;
364bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
365bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
366bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    /* some argument checks are delayed to FTC_Cache_Lookup */
367bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( !aglyph || !scaler )
368bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
369727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_Argument );
370bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      goto Exit;
371bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
372bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
373bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    *aglyph = NULL;
374bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( anode )
375bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      *anode  = NULL;
376bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
377bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */
378bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( load_flags > FT_UINT_MAX )
379bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
380bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" ));
381bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) ));
382bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
383bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
384bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    query.attrs.scaler     = scaler[0];
385bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    query.attrs.load_flags = (FT_UInt)load_flags;
386bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
387bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;
388bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
389bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_GCACHE_LOOKUP_CMP( cache,
390bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           ftc_basic_family_compare,
391bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           FTC_GNode_Compare,
392bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           hash, gindex,
393bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           &query,
394bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           node,
395bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           error );
396bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( !error )
397bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
398bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      *aglyph = FTC_INODE( node )->glyph;
399bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
400bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      if ( anode )
401bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      {
402bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        *anode = node;
403bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        node->ref_count++;
404bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      }
405bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
406bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
407bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  Exit:
408bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    return error;
409bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  }
410bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
411bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
412727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /*
413727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   *
414727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   * basic small bitmap cache
415727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   *
416727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   */
417bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
4189c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  static
419bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  const FTC_SFamilyClassRec  ftc_basic_sbit_family_class =
420bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
421bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
42241371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      sizeof ( FTC_BasicFamilyRec ),
423bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_basic_family_compare,
424bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_basic_family_init,
425bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      0,                            /* FTC_MruNode_ResetFunc */
426bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      0                             /* FTC_MruNode_DoneFunc  */
427bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    },
428bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    ftc_basic_family_get_count,
429bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    ftc_basic_family_load_bitmap
430bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  };
431bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
432bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
4339c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  static
434bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  const FTC_GCacheClassRec  ftc_basic_sbit_cache_class =
435bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
436bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
437bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_snode_new,
438bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_snode_weight,
439bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_snode_compare,
440bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_basic_gnode_compare_faceid,
441bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_snode_free,
442bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
443bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      sizeof ( FTC_GCacheRec ),
444bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_gcache_init,
445bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      ftc_gcache_done
446bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    },
447bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    (FTC_MruListClass)&ftc_basic_sbit_family_class
448bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  };
449bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
450bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
451bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  /* documentation is in ftcache.h */
452bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
453bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_EXPORT_DEF( FT_Error )
454bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FTC_SBitCache_New( FTC_Manager     manager,
455bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                     FTC_SBitCache  *acache )
456bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
457bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    return FTC_GCache_New( manager, &ftc_basic_sbit_cache_class,
458bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           (FTC_GCache*)acache );
459bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  }
460bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
461bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
462bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  /* documentation is in ftcache.h */
463bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
464bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_EXPORT_DEF( FT_Error )
465bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FTC_SBitCache_Lookup( FTC_SBitCache  cache,
466bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                        FTC_ImageType  type,
467bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                        FT_UInt        gindex,
468bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                        FTC_SBit      *ansbit,
469bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                        FTC_Node      *anode )
470bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
471bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Error           error;
472bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_BasicQueryRec  query;
473bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_Node           node = 0; /* make compiler happy */
474bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_PtrDist         hash;
475bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
476bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
477bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( anode )
478bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      *anode = NULL;
479bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
480bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    /* other argument checks delayed to FTC_Cache_Lookup */
481bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( !ansbit )
482727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
483bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
484bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    *ansbit = NULL;
485bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
486bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
487bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX )
488bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      {
489bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" ));
490bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) ));
491bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      }
492bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
493bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      query.attrs.scaler.face_id = type->face_id;
494bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      query.attrs.scaler.width   = type->width;
495bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      query.attrs.scaler.height  = type->height;
496bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      query.attrs.load_flags     = (FT_UInt)type->flags;
497bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
498bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
499bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    query.attrs.scaler.pixel = 1;
500bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    query.attrs.scaler.x_res = 0;  /* make compilers happy */
501bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    query.attrs.scaler.y_res = 0;
502bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
503bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    /* beware, the hash must be the same for all glyph ranges! */
504bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
505bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly           gindex / FTC_SBIT_ITEMS_PER_NODE;
506bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
507bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#if 1  /* inlining is about 50% faster! */
508bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_GCACHE_LOOKUP_CMP( cache,
509bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           ftc_basic_family_compare,
510bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           FTC_SNode_Compare,
511bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           hash, gindex,
512bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           &query,
513bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           node,
514bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           error );
515bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#else
516bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
517bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                               hash,
518bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                               gindex,
519bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                               FTC_GQUERY( &query ),
520bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                               &node );
521bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#endif
522bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( error )
523bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      goto Exit;
524bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
525bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    *ansbit = FTC_SNODE( node )->sbits +
526bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              ( gindex - FTC_GNODE( node )->gindex );
527bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
528bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( anode )
529bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
530bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      *anode = node;
531bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      node->ref_count++;
532bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
533bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
534bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  Exit:
535bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    return error;
536bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  }
537bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
538bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
539bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  /* documentation is in ftcache.h */
540bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
541bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_EXPORT_DEF( FT_Error )
542bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FTC_SBitCache_LookupScaler( FTC_SBitCache  cache,
543bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                              FTC_Scaler     scaler,
544bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                              FT_ULong       load_flags,
545bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                              FT_UInt        gindex,
546bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                              FTC_SBit      *ansbit,
547bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                              FTC_Node      *anode )
548bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
549bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Error           error;
550bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_BasicQueryRec  query;
551bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_Node           node = 0; /* make compiler happy */
552bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_PtrDist         hash;
553bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
554bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
555bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( anode )
556bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        *anode = NULL;
557bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
558bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    /* other argument checks delayed to FTC_Cache_Lookup */
559bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( !ansbit || !scaler )
560727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        return FT_THROW( Invalid_Argument );
561bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
562bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    *ansbit = NULL;
563bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
564bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */
565bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( load_flags > FT_UINT_MAX )
566bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
567bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" ));
568bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) ));
569bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
570bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
571bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    query.attrs.scaler     = scaler[0];
572bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    query.attrs.load_flags = (FT_UInt)load_flags;
573bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
574bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    /* beware, the hash must be the same for all glyph ranges! */
575bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
576bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly             gindex / FTC_SBIT_ITEMS_PER_NODE;
577bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
578bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FTC_GCACHE_LOOKUP_CMP( cache,
579bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           ftc_basic_family_compare,
580bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           FTC_SNode_Compare,
581bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           hash, gindex,
582bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           &query,
583bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           node,
584bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                           error );
585bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( error )
586bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      goto Exit;
587bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
588bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    *ansbit = FTC_SNODE( node )->sbits +
589bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              ( gindex - FTC_GNODE( node )->gindex );
590bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
591bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( anode )
592bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
593bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      *anode = node;
594bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      node->ref_count++;
595bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
596bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
597bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  Exit:
598bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    return error;
599bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  }
600bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
601bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
602bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/* END */
603