xref: /inferno-os/libfreetype/ftcimage.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth /***************************************************************************/
2*37da2899SCharles.Forsyth /*                                                                         */
3*37da2899SCharles.Forsyth /*  ftcimage.c                                                             */
4*37da2899SCharles.Forsyth /*                                                                         */
5*37da2899SCharles.Forsyth /*    FreeType Image cache (body).                                         */
6*37da2899SCharles.Forsyth /*                                                                         */
7*37da2899SCharles.Forsyth /*  Copyright 2000-2001 by                                                 */
8*37da2899SCharles.Forsyth /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9*37da2899SCharles.Forsyth /*                                                                         */
10*37da2899SCharles.Forsyth /*  This file is part of the FreeType project, and may only be used,       */
11*37da2899SCharles.Forsyth /*  modified, and distributed under the terms of the FreeType project      */
12*37da2899SCharles.Forsyth /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13*37da2899SCharles.Forsyth /*  this file you indicate that you have read the license and              */
14*37da2899SCharles.Forsyth /*  understand and accept it fully.                                        */
15*37da2899SCharles.Forsyth /*                                                                         */
16*37da2899SCharles.Forsyth /***************************************************************************/
17*37da2899SCharles.Forsyth 
18*37da2899SCharles.Forsyth 
19*37da2899SCharles.Forsyth #include <ft2build.h>
20*37da2899SCharles.Forsyth #include FT_CACHE_H
21*37da2899SCharles.Forsyth #include FT_CACHE_IMAGE_H
22*37da2899SCharles.Forsyth #include FT_CACHE_INTERNAL_GLYPH_H
23*37da2899SCharles.Forsyth #include FT_INTERNAL_MEMORY_H
24*37da2899SCharles.Forsyth 
25*37da2899SCharles.Forsyth #include "ftcerror.h"
26*37da2899SCharles.Forsyth 
27*37da2899SCharles.Forsyth 
28*37da2899SCharles.Forsyth   /* the FT_Glyph image node type */
29*37da2899SCharles.Forsyth   typedef struct  FTC_ImageNodeRec_
30*37da2899SCharles.Forsyth   {
31*37da2899SCharles.Forsyth     FTC_GlyphNodeRec  gnode;
32*37da2899SCharles.Forsyth     FT_Glyph          glyph;
33*37da2899SCharles.Forsyth 
34*37da2899SCharles.Forsyth   } FTC_ImageNodeRec, *FTC_ImageNode;
35*37da2899SCharles.Forsyth 
36*37da2899SCharles.Forsyth 
37*37da2899SCharles.Forsyth #define FTC_IMAGE_NODE( x )         ( (FTC_ImageNode)( x ) )
38*37da2899SCharles.Forsyth #define FTC_IMAGE_NODE_GINDEX( x )  FTC_GLYPH_NODE_GINDEX( x )
39*37da2899SCharles.Forsyth 
40*37da2899SCharles.Forsyth 
41*37da2899SCharles.Forsyth   /* the glyph image query */
42*37da2899SCharles.Forsyth   typedef struct  FTC_ImageQueryRec_
43*37da2899SCharles.Forsyth   {
44*37da2899SCharles.Forsyth     FTC_GlyphQueryRec  gquery;
45*37da2899SCharles.Forsyth     FTC_ImageTypeRec   type;
46*37da2899SCharles.Forsyth 
47*37da2899SCharles.Forsyth   } FTC_ImageQueryRec, *FTC_ImageQuery;
48*37da2899SCharles.Forsyth 
49*37da2899SCharles.Forsyth 
50*37da2899SCharles.Forsyth #define FTC_IMAGE_QUERY( x )  ( (FTC_ImageQuery)( x ) )
51*37da2899SCharles.Forsyth 
52*37da2899SCharles.Forsyth 
53*37da2899SCharles.Forsyth   /* the glyph image set type */
54*37da2899SCharles.Forsyth   typedef struct  FTC_ImageFamilyRec_
55*37da2899SCharles.Forsyth   {
56*37da2899SCharles.Forsyth     FTC_GlyphFamilyRec  gfam;
57*37da2899SCharles.Forsyth     FTC_ImageTypeRec    type;
58*37da2899SCharles.Forsyth 
59*37da2899SCharles.Forsyth   } FTC_ImageFamilyRec, *FTC_ImageFamily;
60*37da2899SCharles.Forsyth 
61*37da2899SCharles.Forsyth 
62*37da2899SCharles.Forsyth #define FTC_IMAGE_FAMILY( x )         ( (FTC_ImageFamily)( x ) )
63*37da2899SCharles.Forsyth #define FTC_IMAGE_FAMILY_MEMORY( x )  FTC_GLYPH_FAMILY_MEMORY( &(x)->gfam )
64*37da2899SCharles.Forsyth 
65*37da2899SCharles.Forsyth 
66*37da2899SCharles.Forsyth   /*************************************************************************/
67*37da2899SCharles.Forsyth   /*************************************************************************/
68*37da2899SCharles.Forsyth   /*****                                                               *****/
69*37da2899SCharles.Forsyth   /*****                    GLYPH IMAGE NODES                          *****/
70*37da2899SCharles.Forsyth   /*****                                                               *****/
71*37da2899SCharles.Forsyth   /*************************************************************************/
72*37da2899SCharles.Forsyth   /*************************************************************************/
73*37da2899SCharles.Forsyth 
74*37da2899SCharles.Forsyth 
75*37da2899SCharles.Forsyth   /* finalize a given glyph image node */
76*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( void )
ftc_image_node_done(FTC_ImageNode inode,FTC_Cache cache)77*37da2899SCharles.Forsyth   ftc_image_node_done( FTC_ImageNode  inode,
78*37da2899SCharles.Forsyth                        FTC_Cache      cache )
79*37da2899SCharles.Forsyth   {
80*37da2899SCharles.Forsyth     if ( inode->glyph )
81*37da2899SCharles.Forsyth     {
82*37da2899SCharles.Forsyth       FT_Done_Glyph( inode->glyph );
83*37da2899SCharles.Forsyth       inode->glyph = NULL;
84*37da2899SCharles.Forsyth     }
85*37da2899SCharles.Forsyth 
86*37da2899SCharles.Forsyth     ftc_glyph_node_done( FTC_GLYPH_NODE( inode ), cache );
87*37da2899SCharles.Forsyth   }
88*37da2899SCharles.Forsyth 
89*37da2899SCharles.Forsyth 
90*37da2899SCharles.Forsyth   /* initialize a new glyph image node */
91*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Error )
ftc_image_node_init(FTC_ImageNode inode,FTC_GlyphQuery gquery,FTC_Cache cache)92*37da2899SCharles.Forsyth   ftc_image_node_init( FTC_ImageNode   inode,
93*37da2899SCharles.Forsyth                        FTC_GlyphQuery  gquery,
94*37da2899SCharles.Forsyth                        FTC_Cache       cache )
95*37da2899SCharles.Forsyth   {
96*37da2899SCharles.Forsyth     FTC_ImageFamily  ifam = FTC_IMAGE_FAMILY( gquery->query.family );
97*37da2899SCharles.Forsyth     FT_Error         error;
98*37da2899SCharles.Forsyth     FT_Face          face;
99*37da2899SCharles.Forsyth     FT_Size          size;
100*37da2899SCharles.Forsyth 
101*37da2899SCharles.Forsyth 
102*37da2899SCharles.Forsyth     /* initialize its inner fields */
103*37da2899SCharles.Forsyth     ftc_glyph_node_init( FTC_GLYPH_NODE( inode ),
104*37da2899SCharles.Forsyth                          gquery->gindex,
105*37da2899SCharles.Forsyth                          FTC_GLYPH_FAMILY( ifam ) );
106*37da2899SCharles.Forsyth 
107*37da2899SCharles.Forsyth     /* we will now load the glyph image */
108*37da2899SCharles.Forsyth     error = FTC_Manager_Lookup_Size( FTC_FAMILY( ifam )->cache->manager,
109*37da2899SCharles.Forsyth                                      &ifam->type.font,
110*37da2899SCharles.Forsyth                                      &face, &size );
111*37da2899SCharles.Forsyth     if ( !error )
112*37da2899SCharles.Forsyth     {
113*37da2899SCharles.Forsyth       FT_UInt  gindex = FTC_GLYPH_NODE_GINDEX( inode );
114*37da2899SCharles.Forsyth 
115*37da2899SCharles.Forsyth 
116*37da2899SCharles.Forsyth       error = FT_Load_Glyph( face, gindex, ifam->type.flags );
117*37da2899SCharles.Forsyth       if ( !error )
118*37da2899SCharles.Forsyth       {
119*37da2899SCharles.Forsyth         if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP  ||
120*37da2899SCharles.Forsyth              face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
121*37da2899SCharles.Forsyth         {
122*37da2899SCharles.Forsyth           /* ok, copy it */
123*37da2899SCharles.Forsyth           FT_Glyph  glyph;
124*37da2899SCharles.Forsyth 
125*37da2899SCharles.Forsyth 
126*37da2899SCharles.Forsyth           error = FT_Get_Glyph( face->glyph, &glyph );
127*37da2899SCharles.Forsyth           if ( !error )
128*37da2899SCharles.Forsyth           {
129*37da2899SCharles.Forsyth             inode->glyph = glyph;
130*37da2899SCharles.Forsyth             goto Exit;
131*37da2899SCharles.Forsyth           }
132*37da2899SCharles.Forsyth         }
133*37da2899SCharles.Forsyth         else
134*37da2899SCharles.Forsyth           error = FTC_Err_Invalid_Argument;
135*37da2899SCharles.Forsyth       }
136*37da2899SCharles.Forsyth     }
137*37da2899SCharles.Forsyth 
138*37da2899SCharles.Forsyth     /* in case of error */
139*37da2899SCharles.Forsyth     ftc_glyph_node_done( FTC_GLYPH_NODE(inode), cache );
140*37da2899SCharles.Forsyth 
141*37da2899SCharles.Forsyth   Exit:
142*37da2899SCharles.Forsyth     return error;
143*37da2899SCharles.Forsyth   }
144*37da2899SCharles.Forsyth 
145*37da2899SCharles.Forsyth 
146*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_ULong )
ftc_image_node_weight(FTC_ImageNode inode)147*37da2899SCharles.Forsyth   ftc_image_node_weight( FTC_ImageNode  inode )
148*37da2899SCharles.Forsyth   {
149*37da2899SCharles.Forsyth     FT_ULong  size  = 0;
150*37da2899SCharles.Forsyth     FT_Glyph  glyph = inode->glyph;
151*37da2899SCharles.Forsyth 
152*37da2899SCharles.Forsyth 
153*37da2899SCharles.Forsyth     switch ( glyph->format )
154*37da2899SCharles.Forsyth     {
155*37da2899SCharles.Forsyth     case FT_GLYPH_FORMAT_BITMAP:
156*37da2899SCharles.Forsyth       {
157*37da2899SCharles.Forsyth         FT_BitmapGlyph  bitg;
158*37da2899SCharles.Forsyth 
159*37da2899SCharles.Forsyth 
160*37da2899SCharles.Forsyth         bitg = (FT_BitmapGlyph)glyph;
161*37da2899SCharles.Forsyth         size = bitg->bitmap.rows * labs( bitg->bitmap.pitch ) +
162*37da2899SCharles.Forsyth                sizeof ( *bitg );
163*37da2899SCharles.Forsyth       }
164*37da2899SCharles.Forsyth       break;
165*37da2899SCharles.Forsyth 
166*37da2899SCharles.Forsyth     case FT_GLYPH_FORMAT_OUTLINE:
167*37da2899SCharles.Forsyth       {
168*37da2899SCharles.Forsyth         FT_OutlineGlyph  outg;
169*37da2899SCharles.Forsyth 
170*37da2899SCharles.Forsyth 
171*37da2899SCharles.Forsyth         outg = (FT_OutlineGlyph)glyph;
172*37da2899SCharles.Forsyth         size = outg->outline.n_points *
173*37da2899SCharles.Forsyth                  ( sizeof ( FT_Vector ) + sizeof ( FT_Byte ) ) +
174*37da2899SCharles.Forsyth                outg->outline.n_contours * sizeof ( FT_Short ) +
175*37da2899SCharles.Forsyth                sizeof ( *outg );
176*37da2899SCharles.Forsyth       }
177*37da2899SCharles.Forsyth       break;
178*37da2899SCharles.Forsyth 
179*37da2899SCharles.Forsyth     default:
180*37da2899SCharles.Forsyth       ;
181*37da2899SCharles.Forsyth     }
182*37da2899SCharles.Forsyth 
183*37da2899SCharles.Forsyth     size += sizeof ( *inode );
184*37da2899SCharles.Forsyth     return size;
185*37da2899SCharles.Forsyth   }
186*37da2899SCharles.Forsyth 
187*37da2899SCharles.Forsyth 
188*37da2899SCharles.Forsyth   /*************************************************************************/
189*37da2899SCharles.Forsyth   /*************************************************************************/
190*37da2899SCharles.Forsyth   /*****                                                               *****/
191*37da2899SCharles.Forsyth   /*****                    GLYPH IMAGE SETS                           *****/
192*37da2899SCharles.Forsyth   /*****                                                               *****/
193*37da2899SCharles.Forsyth   /*************************************************************************/
194*37da2899SCharles.Forsyth   /*************************************************************************/
195*37da2899SCharles.Forsyth 
196*37da2899SCharles.Forsyth 
197*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Error )
ftc_image_family_init(FTC_ImageFamily ifam,FTC_ImageQuery iquery,FTC_Cache cache)198*37da2899SCharles.Forsyth   ftc_image_family_init( FTC_ImageFamily  ifam,
199*37da2899SCharles.Forsyth                          FTC_ImageQuery   iquery,
200*37da2899SCharles.Forsyth                          FTC_Cache        cache )
201*37da2899SCharles.Forsyth   {
202*37da2899SCharles.Forsyth     FTC_Manager  manager = cache->manager;
203*37da2899SCharles.Forsyth     FT_Error     error;
204*37da2899SCharles.Forsyth     FT_Face      face;
205*37da2899SCharles.Forsyth 
206*37da2899SCharles.Forsyth 
207*37da2899SCharles.Forsyth     ifam->type = iquery->type;
208*37da2899SCharles.Forsyth 
209*37da2899SCharles.Forsyth     /* we need to compute "iquery.item_total" now */
210*37da2899SCharles.Forsyth     error = FTC_Manager_Lookup_Face( manager,
211*37da2899SCharles.Forsyth                                      iquery->type.font.face_id,
212*37da2899SCharles.Forsyth                                      &face );
213*37da2899SCharles.Forsyth     if ( !error )
214*37da2899SCharles.Forsyth     {
215*37da2899SCharles.Forsyth       error = ftc_glyph_family_init( FTC_GLYPH_FAMILY( ifam ),
216*37da2899SCharles.Forsyth                                      FTC_IMAGE_TYPE_HASH( &ifam->type ),
217*37da2899SCharles.Forsyth                                      1,
218*37da2899SCharles.Forsyth                                      face->num_glyphs,
219*37da2899SCharles.Forsyth                                      FTC_GLYPH_QUERY( iquery ),
220*37da2899SCharles.Forsyth                                      cache );
221*37da2899SCharles.Forsyth     }
222*37da2899SCharles.Forsyth 
223*37da2899SCharles.Forsyth     return error;
224*37da2899SCharles.Forsyth   }
225*37da2899SCharles.Forsyth 
226*37da2899SCharles.Forsyth 
227*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Bool )
ftc_image_family_compare(FTC_ImageFamily ifam,FTC_ImageQuery iquery)228*37da2899SCharles.Forsyth   ftc_image_family_compare( FTC_ImageFamily  ifam,
229*37da2899SCharles.Forsyth                             FTC_ImageQuery   iquery )
230*37da2899SCharles.Forsyth   {
231*37da2899SCharles.Forsyth     FT_Bool  result;
232*37da2899SCharles.Forsyth 
233*37da2899SCharles.Forsyth 
234*37da2899SCharles.Forsyth     result = FT_BOOL( FTC_IMAGE_TYPE_COMPARE( &ifam->type, &iquery->type ) );
235*37da2899SCharles.Forsyth     if ( result )
236*37da2899SCharles.Forsyth       FTC_GLYPH_FAMILY_FOUND( ifam, iquery );
237*37da2899SCharles.Forsyth 
238*37da2899SCharles.Forsyth     return result;
239*37da2899SCharles.Forsyth   }
240*37da2899SCharles.Forsyth 
241*37da2899SCharles.Forsyth 
242*37da2899SCharles.Forsyth   /*************************************************************************/
243*37da2899SCharles.Forsyth   /*************************************************************************/
244*37da2899SCharles.Forsyth   /*****                                                               *****/
245*37da2899SCharles.Forsyth   /*****                    GLYPH IMAGE CACHE                          *****/
246*37da2899SCharles.Forsyth   /*****                                                               *****/
247*37da2899SCharles.Forsyth   /*************************************************************************/
248*37da2899SCharles.Forsyth   /*************************************************************************/
249*37da2899SCharles.Forsyth 
250*37da2899SCharles.Forsyth 
251*37da2899SCharles.Forsyth 
252*37da2899SCharles.Forsyth   FT_CALLBACK_TABLE_DEF
253*37da2899SCharles.Forsyth   const FTC_Cache_ClassRec  ftc_image_cache_class =
254*37da2899SCharles.Forsyth   {
255*37da2899SCharles.Forsyth     sizeof ( FTC_CacheRec ),
256*37da2899SCharles.Forsyth     (FTC_Cache_InitFunc) ftc_cache_init,
257*37da2899SCharles.Forsyth     (FTC_Cache_ClearFunc)ftc_cache_clear,
258*37da2899SCharles.Forsyth     (FTC_Cache_DoneFunc) ftc_cache_done,
259*37da2899SCharles.Forsyth 
260*37da2899SCharles.Forsyth     sizeof ( FTC_ImageFamilyRec ),
261*37da2899SCharles.Forsyth     (FTC_Family_InitFunc)   ftc_image_family_init,
262*37da2899SCharles.Forsyth     (FTC_Family_CompareFunc)ftc_image_family_compare,
263*37da2899SCharles.Forsyth     (FTC_Family_DoneFunc)   ftc_glyph_family_done,
264*37da2899SCharles.Forsyth 
265*37da2899SCharles.Forsyth     sizeof ( FTC_ImageNodeRec ),
266*37da2899SCharles.Forsyth     (FTC_Node_InitFunc)   ftc_image_node_init,
267*37da2899SCharles.Forsyth     (FTC_Node_WeightFunc) ftc_image_node_weight,
268*37da2899SCharles.Forsyth     (FTC_Node_CompareFunc)ftc_glyph_node_compare,
269*37da2899SCharles.Forsyth     (FTC_Node_DoneFunc)   ftc_image_node_done
270*37da2899SCharles.Forsyth   };
271*37da2899SCharles.Forsyth 
272*37da2899SCharles.Forsyth 
273*37da2899SCharles.Forsyth   /* documentation is in ftcimage.h */
274*37da2899SCharles.Forsyth 
275*37da2899SCharles.Forsyth   FT_EXPORT_DEF( FT_Error )
FTC_ImageCache_New(FTC_Manager manager,FTC_ImageCache * acache)276*37da2899SCharles.Forsyth   FTC_ImageCache_New( FTC_Manager      manager,
277*37da2899SCharles.Forsyth                       FTC_ImageCache  *acache )
278*37da2899SCharles.Forsyth   {
279*37da2899SCharles.Forsyth     return FTC_Manager_Register_Cache(
280*37da2899SCharles.Forsyth              manager,
281*37da2899SCharles.Forsyth              (FTC_Cache_Class)&ftc_image_cache_class,
282*37da2899SCharles.Forsyth              FTC_CACHE_P( acache ) );
283*37da2899SCharles.Forsyth   }
284*37da2899SCharles.Forsyth 
285*37da2899SCharles.Forsyth 
286*37da2899SCharles.Forsyth   /* documentation is in ftcimage.h */
287*37da2899SCharles.Forsyth 
288*37da2899SCharles.Forsyth   FT_EXPORT_DEF( FT_Error )
FTC_ImageCache_Lookup(FTC_ImageCache cache,FTC_ImageType type,FT_UInt gindex,FT_Glyph * aglyph,FTC_Node * anode)289*37da2899SCharles.Forsyth   FTC_ImageCache_Lookup( FTC_ImageCache  cache,
290*37da2899SCharles.Forsyth                          FTC_ImageType   type,
291*37da2899SCharles.Forsyth                          FT_UInt         gindex,
292*37da2899SCharles.Forsyth                          FT_Glyph       *aglyph,
293*37da2899SCharles.Forsyth                          FTC_Node       *anode )
294*37da2899SCharles.Forsyth   {
295*37da2899SCharles.Forsyth     FTC_ImageQueryRec  iquery;
296*37da2899SCharles.Forsyth     FTC_ImageNode      node;
297*37da2899SCharles.Forsyth     FT_Error           error;
298*37da2899SCharles.Forsyth 
299*37da2899SCharles.Forsyth 
300*37da2899SCharles.Forsyth     /* some argument checks are delayed to ftc_cache_lookup */
301*37da2899SCharles.Forsyth     if ( !aglyph )
302*37da2899SCharles.Forsyth       return FTC_Err_Invalid_Argument;
303*37da2899SCharles.Forsyth 
304*37da2899SCharles.Forsyth     if ( anode )
305*37da2899SCharles.Forsyth       *anode  = NULL;
306*37da2899SCharles.Forsyth 
307*37da2899SCharles.Forsyth     iquery.gquery.gindex = gindex;
308*37da2899SCharles.Forsyth     iquery.type          = *type;
309*37da2899SCharles.Forsyth 
310*37da2899SCharles.Forsyth     error = ftc_cache_lookup( FTC_CACHE( cache ),
311*37da2899SCharles.Forsyth                               FTC_QUERY( &iquery ),
312*37da2899SCharles.Forsyth                               (FTC_Node*)&node );
313*37da2899SCharles.Forsyth     if ( !error )
314*37da2899SCharles.Forsyth     {
315*37da2899SCharles.Forsyth       *aglyph = node->glyph;
316*37da2899SCharles.Forsyth 
317*37da2899SCharles.Forsyth       if ( anode )
318*37da2899SCharles.Forsyth       {
319*37da2899SCharles.Forsyth         *anode = (FTC_Node)node;
320*37da2899SCharles.Forsyth         FTC_NODE( node )->ref_count++;
321*37da2899SCharles.Forsyth       }
322*37da2899SCharles.Forsyth     }
323*37da2899SCharles.Forsyth 
324*37da2899SCharles.Forsyth     return error;
325*37da2899SCharles.Forsyth   }
326*37da2899SCharles.Forsyth 
327*37da2899SCharles.Forsyth 
328*37da2899SCharles.Forsyth   /* backwards-compatibility functions */
329*37da2899SCharles.Forsyth 
330*37da2899SCharles.Forsyth   FT_EXPORT_DEF( FT_Error )
FTC_Image_Cache_New(FTC_Manager manager,FTC_Image_Cache * acache)331*37da2899SCharles.Forsyth   FTC_Image_Cache_New( FTC_Manager       manager,
332*37da2899SCharles.Forsyth                        FTC_Image_Cache  *acache )
333*37da2899SCharles.Forsyth   {
334*37da2899SCharles.Forsyth     return FTC_ImageCache_New( manager, (FTC_ImageCache*)acache );
335*37da2899SCharles.Forsyth   }
336*37da2899SCharles.Forsyth 
337*37da2899SCharles.Forsyth 
338*37da2899SCharles.Forsyth   FT_EXPORT_DEF( FT_Error )
FTC_Image_Cache_Lookup(FTC_Image_Cache icache,FTC_Image_Desc * desc,FT_UInt gindex,FT_Glyph * aglyph)339*37da2899SCharles.Forsyth   FTC_Image_Cache_Lookup( FTC_Image_Cache  icache,
340*37da2899SCharles.Forsyth                           FTC_Image_Desc*  desc,
341*37da2899SCharles.Forsyth                           FT_UInt          gindex,
342*37da2899SCharles.Forsyth                           FT_Glyph        *aglyph )
343*37da2899SCharles.Forsyth   {
344*37da2899SCharles.Forsyth     FTC_ImageTypeRec  type0;
345*37da2899SCharles.Forsyth 
346*37da2899SCharles.Forsyth 
347*37da2899SCharles.Forsyth     if ( !desc )
348*37da2899SCharles.Forsyth       return FTC_Err_Invalid_Argument;
349*37da2899SCharles.Forsyth 
350*37da2899SCharles.Forsyth     type0.font = desc->font;
351*37da2899SCharles.Forsyth 
352*37da2899SCharles.Forsyth     /* convert image type flags to load flags */
353*37da2899SCharles.Forsyth     {
354*37da2899SCharles.Forsyth       FT_UInt  load_flags = FT_LOAD_DEFAULT;
355*37da2899SCharles.Forsyth       FT_UInt  type       = desc->image_type;
356*37da2899SCharles.Forsyth 
357*37da2899SCharles.Forsyth 
358*37da2899SCharles.Forsyth       /* determine load flags, depending on the font description's */
359*37da2899SCharles.Forsyth       /* image type                                                */
360*37da2899SCharles.Forsyth 
361*37da2899SCharles.Forsyth       if ( ftc_image_format( type ) == ftc_image_format_bitmap )
362*37da2899SCharles.Forsyth       {
363*37da2899SCharles.Forsyth         if ( type & ftc_image_flag_monochrome )
364*37da2899SCharles.Forsyth           load_flags |= FT_LOAD_MONOCHROME;
365*37da2899SCharles.Forsyth 
366*37da2899SCharles.Forsyth         /* disable embedded bitmaps loading if necessary */
367*37da2899SCharles.Forsyth         if ( type & ftc_image_flag_no_sbits )
368*37da2899SCharles.Forsyth           load_flags |= FT_LOAD_NO_BITMAP;
369*37da2899SCharles.Forsyth       }
370*37da2899SCharles.Forsyth       else
371*37da2899SCharles.Forsyth       {
372*37da2899SCharles.Forsyth         /* we want an outline, don't load embedded bitmaps */
373*37da2899SCharles.Forsyth         load_flags |= FT_LOAD_NO_BITMAP;
374*37da2899SCharles.Forsyth 
375*37da2899SCharles.Forsyth         if ( type & ftc_image_flag_unscaled )
376*37da2899SCharles.Forsyth           load_flags |= FT_LOAD_NO_SCALE;
377*37da2899SCharles.Forsyth       }
378*37da2899SCharles.Forsyth 
379*37da2899SCharles.Forsyth       /* always render glyphs to bitmaps */
380*37da2899SCharles.Forsyth       load_flags |= FT_LOAD_RENDER;
381*37da2899SCharles.Forsyth 
382*37da2899SCharles.Forsyth       if ( type & ftc_image_flag_unhinted )
383*37da2899SCharles.Forsyth         load_flags |= FT_LOAD_NO_HINTING;
384*37da2899SCharles.Forsyth 
385*37da2899SCharles.Forsyth       if ( type & ftc_image_flag_autohinted )
386*37da2899SCharles.Forsyth         load_flags |= FT_LOAD_FORCE_AUTOHINT;
387*37da2899SCharles.Forsyth 
388*37da2899SCharles.Forsyth       type0.flags = load_flags;
389*37da2899SCharles.Forsyth     }
390*37da2899SCharles.Forsyth 
391*37da2899SCharles.Forsyth     return FTC_ImageCache_Lookup( (FTC_ImageCache)icache,
392*37da2899SCharles.Forsyth                                    &type0,
393*37da2899SCharles.Forsyth                                    gindex,
394*37da2899SCharles.Forsyth                                    aglyph,
395*37da2899SCharles.Forsyth                                    NULL );
396*37da2899SCharles.Forsyth   }
397*37da2899SCharles.Forsyth 
398*37da2899SCharles.Forsyth 
399*37da2899SCharles.Forsyth /* END */
400