xref: /inferno-os/libfreetype/ftcsbits.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth /***************************************************************************/
2*37da2899SCharles.Forsyth /*                                                                         */
3*37da2899SCharles.Forsyth /*  ftcsbits.c                                                             */
4*37da2899SCharles.Forsyth /*                                                                         */
5*37da2899SCharles.Forsyth /*    FreeType sbits manager (body).                                       */
6*37da2899SCharles.Forsyth /*                                                                         */
7*37da2899SCharles.Forsyth /*  Copyright 2000-2001, 2002 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_SMALL_BITMAPS_H
22*37da2899SCharles.Forsyth #include FT_CACHE_INTERNAL_GLYPH_H
23*37da2899SCharles.Forsyth #include FT_INTERNAL_OBJECTS_H
24*37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H
25*37da2899SCharles.Forsyth #include FT_ERRORS_H
26*37da2899SCharles.Forsyth 
27*37da2899SCharles.Forsyth #include "ftcerror.h"
28*37da2899SCharles.Forsyth 
29*37da2899SCharles.Forsyth 
30*37da2899SCharles.Forsyth #define FTC_SBIT_ITEMS_PER_NODE  16
31*37da2899SCharles.Forsyth 
32*37da2899SCharles.Forsyth 
33*37da2899SCharles.Forsyth   typedef struct FTC_SBitNodeRec_*  FTC_SBitNode;
34*37da2899SCharles.Forsyth 
35*37da2899SCharles.Forsyth   typedef struct  FTC_SBitNodeRec_
36*37da2899SCharles.Forsyth   {
37*37da2899SCharles.Forsyth     FTC_GlyphNodeRec  gnode;
38*37da2899SCharles.Forsyth     FTC_SBitRec       sbits[FTC_SBIT_ITEMS_PER_NODE];
39*37da2899SCharles.Forsyth 
40*37da2899SCharles.Forsyth   } FTC_SBitNodeRec;
41*37da2899SCharles.Forsyth 
42*37da2899SCharles.Forsyth 
43*37da2899SCharles.Forsyth #define FTC_SBIT_NODE( x )  ( (FTC_SBitNode)( x ) )
44*37da2899SCharles.Forsyth 
45*37da2899SCharles.Forsyth 
46*37da2899SCharles.Forsyth   typedef struct  FTC_SBitQueryRec_
47*37da2899SCharles.Forsyth   {
48*37da2899SCharles.Forsyth     FTC_GlyphQueryRec  gquery;
49*37da2899SCharles.Forsyth     FTC_ImageTypeRec   type;
50*37da2899SCharles.Forsyth 
51*37da2899SCharles.Forsyth   } FTC_SBitQueryRec, *FTC_SBitQuery;
52*37da2899SCharles.Forsyth 
53*37da2899SCharles.Forsyth 
54*37da2899SCharles.Forsyth #define FTC_SBIT_QUERY( x ) ( (FTC_SBitQuery)( x ) )
55*37da2899SCharles.Forsyth 
56*37da2899SCharles.Forsyth 
57*37da2899SCharles.Forsyth   typedef struct FTC_SBitFamilyRec_*  FTC_SBitFamily;
58*37da2899SCharles.Forsyth 
59*37da2899SCharles.Forsyth   /* sbit family structure */
60*37da2899SCharles.Forsyth   typedef struct  FTC_SBitFamilyRec_
61*37da2899SCharles.Forsyth   {
62*37da2899SCharles.Forsyth     FTC_GlyphFamilyRec  gfam;
63*37da2899SCharles.Forsyth     FTC_ImageTypeRec    type;
64*37da2899SCharles.Forsyth 
65*37da2899SCharles.Forsyth   } FTC_SBitFamilyRec;
66*37da2899SCharles.Forsyth 
67*37da2899SCharles.Forsyth 
68*37da2899SCharles.Forsyth #define FTC_SBIT_FAMILY( x )         ( (FTC_SBitFamily)( x ) )
69*37da2899SCharles.Forsyth #define FTC_SBIT_FAMILY_MEMORY( x )  FTC_GLYPH_FAMILY_MEMORY( &( x )->cset )
70*37da2899SCharles.Forsyth 
71*37da2899SCharles.Forsyth 
72*37da2899SCharles.Forsyth   /*************************************************************************/
73*37da2899SCharles.Forsyth   /*************************************************************************/
74*37da2899SCharles.Forsyth   /*****                                                               *****/
75*37da2899SCharles.Forsyth   /*****                     SBIT CACHE NODES                          *****/
76*37da2899SCharles.Forsyth   /*****                                                               *****/
77*37da2899SCharles.Forsyth   /*************************************************************************/
78*37da2899SCharles.Forsyth   /*************************************************************************/
79*37da2899SCharles.Forsyth 
80*37da2899SCharles.Forsyth 
81*37da2899SCharles.Forsyth   static FT_Error
ftc_sbit_copy_bitmap(FTC_SBit sbit,FT_Bitmap * bitmap,FT_Memory memory)82*37da2899SCharles.Forsyth   ftc_sbit_copy_bitmap( FTC_SBit    sbit,
83*37da2899SCharles.Forsyth                         FT_Bitmap*  bitmap,
84*37da2899SCharles.Forsyth                         FT_Memory   memory )
85*37da2899SCharles.Forsyth   {
86*37da2899SCharles.Forsyth     FT_Error  error;
87*37da2899SCharles.Forsyth     FT_Int    pitch = bitmap->pitch;
88*37da2899SCharles.Forsyth     FT_ULong  size;
89*37da2899SCharles.Forsyth 
90*37da2899SCharles.Forsyth 
91*37da2899SCharles.Forsyth     if ( pitch < 0 )
92*37da2899SCharles.Forsyth       pitch = -pitch;
93*37da2899SCharles.Forsyth 
94*37da2899SCharles.Forsyth     size = (FT_ULong)( pitch * bitmap->rows );
95*37da2899SCharles.Forsyth 
96*37da2899SCharles.Forsyth     if ( !FT_ALLOC( sbit->buffer, size ) )
97*37da2899SCharles.Forsyth       FT_MEM_COPY( sbit->buffer, bitmap->buffer, size );
98*37da2899SCharles.Forsyth 
99*37da2899SCharles.Forsyth     return error;
100*37da2899SCharles.Forsyth   }
101*37da2899SCharles.Forsyth 
102*37da2899SCharles.Forsyth 
103*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( void )
ftc_sbit_node_done(FTC_SBitNode snode,FTC_Cache cache)104*37da2899SCharles.Forsyth   ftc_sbit_node_done( FTC_SBitNode  snode,
105*37da2899SCharles.Forsyth                       FTC_Cache     cache )
106*37da2899SCharles.Forsyth   {
107*37da2899SCharles.Forsyth     FTC_SBit   sbit   = snode->sbits;
108*37da2899SCharles.Forsyth     FT_UInt    count  = FTC_GLYPH_NODE( snode )->item_count;
109*37da2899SCharles.Forsyth     FT_Memory  memory = cache->memory;
110*37da2899SCharles.Forsyth 
111*37da2899SCharles.Forsyth 
112*37da2899SCharles.Forsyth     for ( ; count > 0; sbit++, count-- )
113*37da2899SCharles.Forsyth       FT_FREE( sbit->buffer );
114*37da2899SCharles.Forsyth 
115*37da2899SCharles.Forsyth     ftc_glyph_node_done( FTC_GLYPH_NODE( snode ), cache );
116*37da2899SCharles.Forsyth   }
117*37da2899SCharles.Forsyth 
118*37da2899SCharles.Forsyth 
119*37da2899SCharles.Forsyth   static FT_Error
ftc_sbit_node_load(FTC_SBitNode snode,FTC_Manager manager,FTC_SBitFamily sfam,FT_UInt gindex,FT_ULong * asize)120*37da2899SCharles.Forsyth   ftc_sbit_node_load( FTC_SBitNode    snode,
121*37da2899SCharles.Forsyth                       FTC_Manager     manager,
122*37da2899SCharles.Forsyth                       FTC_SBitFamily  sfam,
123*37da2899SCharles.Forsyth                       FT_UInt         gindex,
124*37da2899SCharles.Forsyth                       FT_ULong       *asize )
125*37da2899SCharles.Forsyth   {
126*37da2899SCharles.Forsyth     FT_Error       error;
127*37da2899SCharles.Forsyth     FTC_GlyphNode  gnode = FTC_GLYPH_NODE( snode );
128*37da2899SCharles.Forsyth     FT_Memory      memory;
129*37da2899SCharles.Forsyth     FT_Face        face;
130*37da2899SCharles.Forsyth     FT_Size        size;
131*37da2899SCharles.Forsyth     FTC_SBit       sbit;
132*37da2899SCharles.Forsyth 
133*37da2899SCharles.Forsyth 
134*37da2899SCharles.Forsyth     if ( gindex <  (FT_UInt)gnode->item_start                     ||
135*37da2899SCharles.Forsyth          gindex >= (FT_UInt)gnode->item_start + gnode->item_count )
136*37da2899SCharles.Forsyth     {
137*37da2899SCharles.Forsyth       FT_ERROR(( "ftc_sbit_node_load: invalid glyph index" ));
138*37da2899SCharles.Forsyth       return FTC_Err_Invalid_Argument;
139*37da2899SCharles.Forsyth     }
140*37da2899SCharles.Forsyth 
141*37da2899SCharles.Forsyth     memory = manager->library->memory;
142*37da2899SCharles.Forsyth 
143*37da2899SCharles.Forsyth     sbit = snode->sbits + ( gindex - gnode->item_start );
144*37da2899SCharles.Forsyth 
145*37da2899SCharles.Forsyth     error = FTC_Manager_Lookup_Size( manager, &sfam->type.font,
146*37da2899SCharles.Forsyth                                      &face, &size );
147*37da2899SCharles.Forsyth     if ( !error )
148*37da2899SCharles.Forsyth     {
149*37da2899SCharles.Forsyth       /* by default, indicates a `missing' glyph */
150*37da2899SCharles.Forsyth       sbit->buffer = 0;
151*37da2899SCharles.Forsyth 
152*37da2899SCharles.Forsyth       error = FT_Load_Glyph( face, gindex, sfam->type.flags | FT_LOAD_RENDER );
153*37da2899SCharles.Forsyth       if ( !error )
154*37da2899SCharles.Forsyth       {
155*37da2899SCharles.Forsyth         FT_Int        temp;
156*37da2899SCharles.Forsyth         FT_GlyphSlot  slot   = face->glyph;
157*37da2899SCharles.Forsyth         FT_Bitmap*    bitmap = &slot->bitmap;
158*37da2899SCharles.Forsyth         FT_Int        xadvance, yadvance;
159*37da2899SCharles.Forsyth 
160*37da2899SCharles.Forsyth 
161*37da2899SCharles.Forsyth         /* check that our values fit into 8-bit containers!       */
162*37da2899SCharles.Forsyth         /* If this is not the case, our bitmap is too large       */
163*37da2899SCharles.Forsyth         /* and we will leave it as `missing' with sbit.buffer = 0 */
164*37da2899SCharles.Forsyth 
165*37da2899SCharles.Forsyth #define CHECK_CHAR( d )  ( temp = (FT_Char)d, temp == d )
166*37da2899SCharles.Forsyth #define CHECK_BYTE( d )  ( temp = (FT_Byte)d, temp == d )
167*37da2899SCharles.Forsyth 
168*37da2899SCharles.Forsyth         /* XXX: FIXME: add support for vertical layouts maybe */
169*37da2899SCharles.Forsyth 
170*37da2899SCharles.Forsyth         /* horizontal advance in pixels */
171*37da2899SCharles.Forsyth         xadvance = ( slot->metrics.horiAdvance + 32 ) >> 6;
172*37da2899SCharles.Forsyth         yadvance = ( slot->metrics.vertAdvance + 32 ) >> 6;
173*37da2899SCharles.Forsyth 
174*37da2899SCharles.Forsyth         if ( CHECK_BYTE( bitmap->rows  )     &&
175*37da2899SCharles.Forsyth              CHECK_BYTE( bitmap->width )     &&
176*37da2899SCharles.Forsyth              CHECK_CHAR( bitmap->pitch )     &&
177*37da2899SCharles.Forsyth              CHECK_CHAR( slot->bitmap_left ) &&
178*37da2899SCharles.Forsyth              CHECK_CHAR( slot->bitmap_top  ) &&
179*37da2899SCharles.Forsyth              CHECK_CHAR( xadvance )          &&
180*37da2899SCharles.Forsyth              CHECK_CHAR( yadvance )          )
181*37da2899SCharles.Forsyth         {
182*37da2899SCharles.Forsyth           sbit->width     = (FT_Byte)bitmap->width;
183*37da2899SCharles.Forsyth           sbit->height    = (FT_Byte)bitmap->rows;
184*37da2899SCharles.Forsyth           sbit->pitch     = (FT_Char)bitmap->pitch;
185*37da2899SCharles.Forsyth           sbit->left      = (FT_Char)slot->bitmap_left;
186*37da2899SCharles.Forsyth           sbit->top       = (FT_Char)slot->bitmap_top;
187*37da2899SCharles.Forsyth           sbit->xadvance  = (FT_Char)xadvance;
188*37da2899SCharles.Forsyth           sbit->yadvance  = (FT_Char)yadvance;
189*37da2899SCharles.Forsyth           sbit->format    = (FT_Byte)bitmap->pixel_mode;
190*37da2899SCharles.Forsyth           sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1);
191*37da2899SCharles.Forsyth 
192*37da2899SCharles.Forsyth #if 0 /* this doesn't work well with embedded bitmaps !! */
193*37da2899SCharles.Forsyth 
194*37da2899SCharles.Forsyth           /* grab the bitmap when possible - this is a hack! */
195*37da2899SCharles.Forsyth           if ( slot->flags & FT_GLYPH_OWN_BITMAP )
196*37da2899SCharles.Forsyth           {
197*37da2899SCharles.Forsyth             slot->flags &= ~FT_GLYPH_OWN_BITMAP;
198*37da2899SCharles.Forsyth             sbit->buffer = bitmap->buffer;
199*37da2899SCharles.Forsyth           }
200*37da2899SCharles.Forsyth           else
201*37da2899SCharles.Forsyth #endif
202*37da2899SCharles.Forsyth           {
203*37da2899SCharles.Forsyth             /* copy the bitmap into a new buffer -- ignore error */
204*37da2899SCharles.Forsyth             error = ftc_sbit_copy_bitmap( sbit, bitmap, memory );
205*37da2899SCharles.Forsyth           }
206*37da2899SCharles.Forsyth 
207*37da2899SCharles.Forsyth           /* now, compute size */
208*37da2899SCharles.Forsyth           if ( asize )
209*37da2899SCharles.Forsyth             *asize = ABS( sbit->pitch ) * sbit->height;
210*37da2899SCharles.Forsyth 
211*37da2899SCharles.Forsyth         }  /* glyph dimensions ok */
212*37da2899SCharles.Forsyth 
213*37da2899SCharles.Forsyth       } /* glyph loading successful */
214*37da2899SCharles.Forsyth 
215*37da2899SCharles.Forsyth       /* ignore the errors that might have occurred --   */
216*37da2899SCharles.Forsyth       /* we mark unloaded glyphs with `sbit.buffer == 0' */
217*37da2899SCharles.Forsyth       /* and 'width == 255', 'height == 0'               */
218*37da2899SCharles.Forsyth       /*                                                 */
219*37da2899SCharles.Forsyth       if ( error )
220*37da2899SCharles.Forsyth       {
221*37da2899SCharles.Forsyth         sbit->width = 255;
222*37da2899SCharles.Forsyth         error       = 0;
223*37da2899SCharles.Forsyth         /* sbit->buffer == NULL too! */
224*37da2899SCharles.Forsyth       }
225*37da2899SCharles.Forsyth     }
226*37da2899SCharles.Forsyth 
227*37da2899SCharles.Forsyth     return error;
228*37da2899SCharles.Forsyth   }
229*37da2899SCharles.Forsyth 
230*37da2899SCharles.Forsyth 
231*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Error )
ftc_sbit_node_init(FTC_SBitNode snode,FTC_GlyphQuery gquery,FTC_Cache cache)232*37da2899SCharles.Forsyth   ftc_sbit_node_init( FTC_SBitNode    snode,
233*37da2899SCharles.Forsyth                       FTC_GlyphQuery  gquery,
234*37da2899SCharles.Forsyth                       FTC_Cache       cache )
235*37da2899SCharles.Forsyth   {
236*37da2899SCharles.Forsyth     FT_Error  error;
237*37da2899SCharles.Forsyth 
238*37da2899SCharles.Forsyth 
239*37da2899SCharles.Forsyth     ftc_glyph_node_init( FTC_GLYPH_NODE( snode ),
240*37da2899SCharles.Forsyth                          gquery->gindex,
241*37da2899SCharles.Forsyth                          FTC_GLYPH_FAMILY( gquery->query.family ) );
242*37da2899SCharles.Forsyth 
243*37da2899SCharles.Forsyth     error = ftc_sbit_node_load( snode,
244*37da2899SCharles.Forsyth                                 cache->manager,
245*37da2899SCharles.Forsyth                                 FTC_SBIT_FAMILY( FTC_QUERY( gquery )->family ),
246*37da2899SCharles.Forsyth                                 gquery->gindex,
247*37da2899SCharles.Forsyth                                 NULL );
248*37da2899SCharles.Forsyth     if ( error )
249*37da2899SCharles.Forsyth       ftc_glyph_node_done( FTC_GLYPH_NODE( snode ), cache );
250*37da2899SCharles.Forsyth 
251*37da2899SCharles.Forsyth     return error;
252*37da2899SCharles.Forsyth   }
253*37da2899SCharles.Forsyth 
254*37da2899SCharles.Forsyth 
255*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_ULong )
ftc_sbit_node_weight(FTC_SBitNode snode)256*37da2899SCharles.Forsyth   ftc_sbit_node_weight( FTC_SBitNode  snode )
257*37da2899SCharles.Forsyth   {
258*37da2899SCharles.Forsyth     FTC_GlyphNode  gnode = FTC_GLYPH_NODE( snode );
259*37da2899SCharles.Forsyth     FT_UInt        count = gnode->item_count;
260*37da2899SCharles.Forsyth     FTC_SBit       sbit  = snode->sbits;
261*37da2899SCharles.Forsyth     FT_Int         pitch;
262*37da2899SCharles.Forsyth     FT_ULong       size;
263*37da2899SCharles.Forsyth 
264*37da2899SCharles.Forsyth 
265*37da2899SCharles.Forsyth     /* the node itself */
266*37da2899SCharles.Forsyth     size = sizeof ( *snode );
267*37da2899SCharles.Forsyth 
268*37da2899SCharles.Forsyth     /* the sbit records */
269*37da2899SCharles.Forsyth     size += FTC_GLYPH_NODE( snode )->item_count * sizeof ( FTC_SBitRec );
270*37da2899SCharles.Forsyth 
271*37da2899SCharles.Forsyth     for ( ; count > 0; count--, sbit++ )
272*37da2899SCharles.Forsyth     {
273*37da2899SCharles.Forsyth       if ( sbit->buffer )
274*37da2899SCharles.Forsyth       {
275*37da2899SCharles.Forsyth         pitch = sbit->pitch;
276*37da2899SCharles.Forsyth         if ( pitch < 0 )
277*37da2899SCharles.Forsyth           pitch = -pitch;
278*37da2899SCharles.Forsyth 
279*37da2899SCharles.Forsyth         /* add the size of a given glyph image */
280*37da2899SCharles.Forsyth         size += pitch * sbit->height;
281*37da2899SCharles.Forsyth       }
282*37da2899SCharles.Forsyth     }
283*37da2899SCharles.Forsyth 
284*37da2899SCharles.Forsyth     return size;
285*37da2899SCharles.Forsyth   }
286*37da2899SCharles.Forsyth 
287*37da2899SCharles.Forsyth 
288*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Bool )
ftc_sbit_node_compare(FTC_SBitNode snode,FTC_SBitQuery squery,FTC_Cache cache)289*37da2899SCharles.Forsyth   ftc_sbit_node_compare( FTC_SBitNode   snode,
290*37da2899SCharles.Forsyth                          FTC_SBitQuery  squery,
291*37da2899SCharles.Forsyth                          FTC_Cache      cache )
292*37da2899SCharles.Forsyth   {
293*37da2899SCharles.Forsyth     FTC_GlyphQuery  gquery = FTC_GLYPH_QUERY( squery );
294*37da2899SCharles.Forsyth     FTC_GlyphNode   gnode  = FTC_GLYPH_NODE( snode );
295*37da2899SCharles.Forsyth     FT_Bool         result;
296*37da2899SCharles.Forsyth 
297*37da2899SCharles.Forsyth 
298*37da2899SCharles.Forsyth     result = ftc_glyph_node_compare( gnode, gquery );
299*37da2899SCharles.Forsyth     if ( result )
300*37da2899SCharles.Forsyth     {
301*37da2899SCharles.Forsyth       /* check if we need to load the glyph bitmap now */
302*37da2899SCharles.Forsyth       FT_UInt   gindex = gquery->gindex;
303*37da2899SCharles.Forsyth       FTC_SBit  sbit   = snode->sbits + ( gindex - gnode->item_start );
304*37da2899SCharles.Forsyth 
305*37da2899SCharles.Forsyth 
306*37da2899SCharles.Forsyth       if ( sbit->buffer == NULL && sbit->width != 255 )
307*37da2899SCharles.Forsyth       {
308*37da2899SCharles.Forsyth         FT_ULong  size;
309*37da2899SCharles.Forsyth 
310*37da2899SCharles.Forsyth 
311*37da2899SCharles.Forsyth         /* yes, it's safe to ignore errors here */
312*37da2899SCharles.Forsyth         ftc_sbit_node_load( snode,
313*37da2899SCharles.Forsyth                             cache->manager,
314*37da2899SCharles.Forsyth                             FTC_SBIT_FAMILY( FTC_QUERY( squery )->family ),
315*37da2899SCharles.Forsyth                             gindex,
316*37da2899SCharles.Forsyth                             &size );
317*37da2899SCharles.Forsyth 
318*37da2899SCharles.Forsyth         cache->manager->cur_weight += size;
319*37da2899SCharles.Forsyth       }
320*37da2899SCharles.Forsyth     }
321*37da2899SCharles.Forsyth 
322*37da2899SCharles.Forsyth     return result;
323*37da2899SCharles.Forsyth   }
324*37da2899SCharles.Forsyth 
325*37da2899SCharles.Forsyth 
326*37da2899SCharles.Forsyth   /*************************************************************************/
327*37da2899SCharles.Forsyth   /*************************************************************************/
328*37da2899SCharles.Forsyth   /*****                                                               *****/
329*37da2899SCharles.Forsyth   /*****                     SBITS FAMILIES                            *****/
330*37da2899SCharles.Forsyth   /*****                                                               *****/
331*37da2899SCharles.Forsyth   /*************************************************************************/
332*37da2899SCharles.Forsyth   /*************************************************************************/
333*37da2899SCharles.Forsyth 
334*37da2899SCharles.Forsyth 
335*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Error )
ftc_sbit_family_init(FTC_SBitFamily sfam,FTC_SBitQuery squery,FTC_Cache cache)336*37da2899SCharles.Forsyth   ftc_sbit_family_init( FTC_SBitFamily  sfam,
337*37da2899SCharles.Forsyth                         FTC_SBitQuery   squery,
338*37da2899SCharles.Forsyth                         FTC_Cache       cache )
339*37da2899SCharles.Forsyth   {
340*37da2899SCharles.Forsyth     FTC_Manager  manager = cache->manager;
341*37da2899SCharles.Forsyth     FT_Error     error;
342*37da2899SCharles.Forsyth     FT_Face      face;
343*37da2899SCharles.Forsyth 
344*37da2899SCharles.Forsyth 
345*37da2899SCharles.Forsyth     sfam->type = squery->type;
346*37da2899SCharles.Forsyth 
347*37da2899SCharles.Forsyth     /* we need to compute "cquery.item_total" now */
348*37da2899SCharles.Forsyth     error = FTC_Manager_Lookup_Face( manager,
349*37da2899SCharles.Forsyth                                      squery->type.font.face_id,
350*37da2899SCharles.Forsyth                                      &face );
351*37da2899SCharles.Forsyth     if ( !error )
352*37da2899SCharles.Forsyth     {
353*37da2899SCharles.Forsyth       error = ftc_glyph_family_init( FTC_GLYPH_FAMILY( sfam ),
354*37da2899SCharles.Forsyth                                      FTC_IMAGE_TYPE_HASH( &sfam->type ),
355*37da2899SCharles.Forsyth                                      FTC_SBIT_ITEMS_PER_NODE,
356*37da2899SCharles.Forsyth                                      face->num_glyphs,
357*37da2899SCharles.Forsyth                                      FTC_GLYPH_QUERY( squery ),
358*37da2899SCharles.Forsyth                                      cache );
359*37da2899SCharles.Forsyth     }
360*37da2899SCharles.Forsyth 
361*37da2899SCharles.Forsyth     return error;
362*37da2899SCharles.Forsyth   }
363*37da2899SCharles.Forsyth 
364*37da2899SCharles.Forsyth 
365*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Bool )
ftc_sbit_family_compare(FTC_SBitFamily sfam,FTC_SBitQuery squery)366*37da2899SCharles.Forsyth   ftc_sbit_family_compare( FTC_SBitFamily  sfam,
367*37da2899SCharles.Forsyth                            FTC_SBitQuery   squery )
368*37da2899SCharles.Forsyth   {
369*37da2899SCharles.Forsyth     FT_Bool  result;
370*37da2899SCharles.Forsyth 
371*37da2899SCharles.Forsyth 
372*37da2899SCharles.Forsyth     /* we need to set the "cquery.cset" field or our query for */
373*37da2899SCharles.Forsyth     /* faster glyph comparisons in ftc_sbit_node_compare       */
374*37da2899SCharles.Forsyth     /*                                                         */
375*37da2899SCharles.Forsyth     result = FT_BOOL( FTC_IMAGE_TYPE_COMPARE( &sfam->type, &squery->type ) );
376*37da2899SCharles.Forsyth     if ( result )
377*37da2899SCharles.Forsyth       FTC_GLYPH_FAMILY_FOUND( sfam, squery );
378*37da2899SCharles.Forsyth 
379*37da2899SCharles.Forsyth     return result;
380*37da2899SCharles.Forsyth   }
381*37da2899SCharles.Forsyth 
382*37da2899SCharles.Forsyth 
383*37da2899SCharles.Forsyth   /*************************************************************************/
384*37da2899SCharles.Forsyth   /*************************************************************************/
385*37da2899SCharles.Forsyth   /*****                                                               *****/
386*37da2899SCharles.Forsyth   /*****                     SBITS CACHE                               *****/
387*37da2899SCharles.Forsyth   /*****                                                               *****/
388*37da2899SCharles.Forsyth   /*************************************************************************/
389*37da2899SCharles.Forsyth   /*************************************************************************/
390*37da2899SCharles.Forsyth 
391*37da2899SCharles.Forsyth 
392*37da2899SCharles.Forsyth   FT_CALLBACK_TABLE_DEF
393*37da2899SCharles.Forsyth   const FTC_Cache_ClassRec  ftc_sbit_cache_class =
394*37da2899SCharles.Forsyth   {
395*37da2899SCharles.Forsyth     sizeof ( FTC_CacheRec ),
396*37da2899SCharles.Forsyth     (FTC_Cache_InitFunc) ftc_cache_init,
397*37da2899SCharles.Forsyth     (FTC_Cache_ClearFunc)ftc_cache_clear,
398*37da2899SCharles.Forsyth     (FTC_Cache_DoneFunc) ftc_cache_done,
399*37da2899SCharles.Forsyth 
400*37da2899SCharles.Forsyth     sizeof ( FTC_SBitFamilyRec ),
401*37da2899SCharles.Forsyth     (FTC_Family_InitFunc)   ftc_sbit_family_init,
402*37da2899SCharles.Forsyth     (FTC_Family_CompareFunc)ftc_sbit_family_compare,
403*37da2899SCharles.Forsyth     (FTC_Family_DoneFunc)   ftc_glyph_family_done,
404*37da2899SCharles.Forsyth 
405*37da2899SCharles.Forsyth     sizeof ( FTC_SBitNodeRec ),
406*37da2899SCharles.Forsyth     (FTC_Node_InitFunc)   ftc_sbit_node_init,
407*37da2899SCharles.Forsyth     (FTC_Node_WeightFunc) ftc_sbit_node_weight,
408*37da2899SCharles.Forsyth     (FTC_Node_CompareFunc)ftc_sbit_node_compare,
409*37da2899SCharles.Forsyth     (FTC_Node_DoneFunc)   ftc_sbit_node_done
410*37da2899SCharles.Forsyth   };
411*37da2899SCharles.Forsyth 
412*37da2899SCharles.Forsyth 
413*37da2899SCharles.Forsyth   /* documentation is in ftcsbits.h */
414*37da2899SCharles.Forsyth 
415*37da2899SCharles.Forsyth   FT_EXPORT_DEF( FT_Error )
FTC_SBitCache_New(FTC_Manager manager,FTC_SBitCache * acache)416*37da2899SCharles.Forsyth   FTC_SBitCache_New( FTC_Manager     manager,
417*37da2899SCharles.Forsyth                      FTC_SBitCache  *acache )
418*37da2899SCharles.Forsyth   {
419*37da2899SCharles.Forsyth     return FTC_Manager_Register_Cache( manager,
420*37da2899SCharles.Forsyth                                        &ftc_sbit_cache_class,
421*37da2899SCharles.Forsyth                                        (FTC_Cache*)acache );
422*37da2899SCharles.Forsyth   }
423*37da2899SCharles.Forsyth 
424*37da2899SCharles.Forsyth 
425*37da2899SCharles.Forsyth   /* documentation is in ftcsbits.h */
426*37da2899SCharles.Forsyth 
427*37da2899SCharles.Forsyth #ifdef FTC_CACHE_USE_INLINE
428*37da2899SCharles.Forsyth 
429*37da2899SCharles.Forsyth #define GEN_CACHE_FAMILY_COMPARE( f, q, c ) \
430*37da2899SCharles.Forsyth           ftc_sbit_family_compare( (FTC_SBitFamily)(f), (FTC_SBitQuery)(q) )
431*37da2899SCharles.Forsyth 
432*37da2899SCharles.Forsyth #define GEN_CACHE_NODE_COMPARE( n, q, c ) \
433*37da2899SCharles.Forsyth           ftc_sbit_node_compare( (FTC_SBitNode)(n), (FTC_SBitQuery)(q), c )
434*37da2899SCharles.Forsyth 
435*37da2899SCharles.Forsyth #define GEN_CACHE_LOOKUP  ftc_sbit_cache_lookup
436*37da2899SCharles.Forsyth #include "ftccache.i"
437*37da2899SCharles.Forsyth 
438*37da2899SCharles.Forsyth #else  /* !FTC_CACHE_USE_INLINE */
439*37da2899SCharles.Forsyth 
440*37da2899SCharles.Forsyth #define ftc_sbit_cache_lookup  ftc_cache_lookup
441*37da2899SCharles.Forsyth 
442*37da2899SCharles.Forsyth #endif /* !FTC_CACHE_USE_INLINE */
443*37da2899SCharles.Forsyth 
444*37da2899SCharles.Forsyth   FT_EXPORT_DEF( FT_Error )
FTC_SBitCache_Lookup(FTC_SBitCache cache,FTC_ImageType type,FT_UInt gindex,FTC_SBit * ansbit,FTC_Node * anode)445*37da2899SCharles.Forsyth   FTC_SBitCache_Lookup( FTC_SBitCache   cache,
446*37da2899SCharles.Forsyth                         FTC_ImageType   type,
447*37da2899SCharles.Forsyth                         FT_UInt         gindex,
448*37da2899SCharles.Forsyth                         FTC_SBit       *ansbit,
449*37da2899SCharles.Forsyth                         FTC_Node       *anode )
450*37da2899SCharles.Forsyth   {
451*37da2899SCharles.Forsyth     FT_Error          error;
452*37da2899SCharles.Forsyth     FTC_SBitQueryRec  squery;
453*37da2899SCharles.Forsyth     FTC_SBitNode      node;
454*37da2899SCharles.Forsyth 
455*37da2899SCharles.Forsyth 
456*37da2899SCharles.Forsyth     /* other argument checks delayed to ftc_cache_lookup */
457*37da2899SCharles.Forsyth     if ( !ansbit )
458*37da2899SCharles.Forsyth       return FTC_Err_Invalid_Argument;
459*37da2899SCharles.Forsyth 
460*37da2899SCharles.Forsyth     *ansbit = NULL;
461*37da2899SCharles.Forsyth 
462*37da2899SCharles.Forsyth     if ( anode )
463*37da2899SCharles.Forsyth       *anode = NULL;
464*37da2899SCharles.Forsyth 
465*37da2899SCharles.Forsyth     squery.gquery.gindex = gindex;
466*37da2899SCharles.Forsyth     squery.type          = *type;
467*37da2899SCharles.Forsyth 
468*37da2899SCharles.Forsyth     error = ftc_sbit_cache_lookup( FTC_CACHE( cache ),
469*37da2899SCharles.Forsyth                                    FTC_QUERY( &squery ),
470*37da2899SCharles.Forsyth                                    (FTC_Node*)&node );
471*37da2899SCharles.Forsyth     if ( !error )
472*37da2899SCharles.Forsyth     {
473*37da2899SCharles.Forsyth       *ansbit = node->sbits + ( gindex - FTC_GLYPH_NODE( node )->item_start );
474*37da2899SCharles.Forsyth 
475*37da2899SCharles.Forsyth       if ( anode )
476*37da2899SCharles.Forsyth       {
477*37da2899SCharles.Forsyth         *anode = FTC_NODE( node );
478*37da2899SCharles.Forsyth         FTC_NODE( node )->ref_count++;
479*37da2899SCharles.Forsyth       }
480*37da2899SCharles.Forsyth     }
481*37da2899SCharles.Forsyth     return error;
482*37da2899SCharles.Forsyth   }
483*37da2899SCharles.Forsyth 
484*37da2899SCharles.Forsyth 
485*37da2899SCharles.Forsyth   /* backwards-compatibility functions */
486*37da2899SCharles.Forsyth 
487*37da2899SCharles.Forsyth   FT_EXPORT_DEF( FT_Error )
FTC_SBit_Cache_New(FTC_Manager manager,FTC_SBit_Cache * acache)488*37da2899SCharles.Forsyth   FTC_SBit_Cache_New( FTC_Manager      manager,
489*37da2899SCharles.Forsyth                       FTC_SBit_Cache  *acache )
490*37da2899SCharles.Forsyth   {
491*37da2899SCharles.Forsyth     return FTC_SBitCache_New( manager, (FTC_SBitCache*)acache );
492*37da2899SCharles.Forsyth   }
493*37da2899SCharles.Forsyth 
494*37da2899SCharles.Forsyth 
495*37da2899SCharles.Forsyth   FT_EXPORT_DEF( FT_Error )
FTC_SBit_Cache_Lookup(FTC_SBit_Cache cache,FTC_Image_Desc * desc,FT_UInt gindex,FTC_SBit * ansbit)496*37da2899SCharles.Forsyth   FTC_SBit_Cache_Lookup( FTC_SBit_Cache   cache,
497*37da2899SCharles.Forsyth                          FTC_Image_Desc*  desc,
498*37da2899SCharles.Forsyth                          FT_UInt          gindex,
499*37da2899SCharles.Forsyth                          FTC_SBit        *ansbit )
500*37da2899SCharles.Forsyth   {
501*37da2899SCharles.Forsyth     FTC_ImageTypeRec  type0;
502*37da2899SCharles.Forsyth 
503*37da2899SCharles.Forsyth 
504*37da2899SCharles.Forsyth     if ( !desc )
505*37da2899SCharles.Forsyth       return FTC_Err_Invalid_Argument;
506*37da2899SCharles.Forsyth 
507*37da2899SCharles.Forsyth     type0.font  = desc->font;
508*37da2899SCharles.Forsyth     type0.flags = 0;
509*37da2899SCharles.Forsyth 
510*37da2899SCharles.Forsyth     /* convert image type flags to load flags */
511*37da2899SCharles.Forsyth     {
512*37da2899SCharles.Forsyth       FT_UInt  load_flags = FT_LOAD_DEFAULT;
513*37da2899SCharles.Forsyth       FT_UInt  type       = desc->image_type;
514*37da2899SCharles.Forsyth 
515*37da2899SCharles.Forsyth 
516*37da2899SCharles.Forsyth       /* determine load flags, depending on the font description's */
517*37da2899SCharles.Forsyth       /* image type                                                */
518*37da2899SCharles.Forsyth 
519*37da2899SCharles.Forsyth       if ( ftc_image_format( type ) == ftc_image_format_bitmap )
520*37da2899SCharles.Forsyth       {
521*37da2899SCharles.Forsyth         if ( type & ftc_image_flag_monochrome )
522*37da2899SCharles.Forsyth           load_flags |= FT_LOAD_MONOCHROME;
523*37da2899SCharles.Forsyth 
524*37da2899SCharles.Forsyth         /* disable embedded bitmaps loading if necessary */
525*37da2899SCharles.Forsyth         if ( type & ftc_image_flag_no_sbits )
526*37da2899SCharles.Forsyth           load_flags |= FT_LOAD_NO_BITMAP;
527*37da2899SCharles.Forsyth       }
528*37da2899SCharles.Forsyth       else
529*37da2899SCharles.Forsyth       {
530*37da2899SCharles.Forsyth         /* we want an outline, don't load embedded bitmaps */
531*37da2899SCharles.Forsyth         load_flags |= FT_LOAD_NO_BITMAP;
532*37da2899SCharles.Forsyth 
533*37da2899SCharles.Forsyth         if ( type & ftc_image_flag_unscaled )
534*37da2899SCharles.Forsyth           load_flags |= FT_LOAD_NO_SCALE;
535*37da2899SCharles.Forsyth       }
536*37da2899SCharles.Forsyth 
537*37da2899SCharles.Forsyth       /* always render glyphs to bitmaps */
538*37da2899SCharles.Forsyth       load_flags |= FT_LOAD_RENDER;
539*37da2899SCharles.Forsyth 
540*37da2899SCharles.Forsyth       if ( type & ftc_image_flag_unhinted )
541*37da2899SCharles.Forsyth         load_flags |= FT_LOAD_NO_HINTING;
542*37da2899SCharles.Forsyth 
543*37da2899SCharles.Forsyth       if ( type & ftc_image_flag_autohinted )
544*37da2899SCharles.Forsyth         load_flags |= FT_LOAD_FORCE_AUTOHINT;
545*37da2899SCharles.Forsyth 
546*37da2899SCharles.Forsyth       type0.flags = load_flags;
547*37da2899SCharles.Forsyth     }
548*37da2899SCharles.Forsyth 
549*37da2899SCharles.Forsyth     return FTC_SBitCache_Lookup( (FTC_SBitCache)cache,
550*37da2899SCharles.Forsyth                                   &type0,
551*37da2899SCharles.Forsyth                                   gindex,
552*37da2899SCharles.Forsyth                                   ansbit,
553*37da2899SCharles.Forsyth                                   NULL );
554*37da2899SCharles.Forsyth   }
555*37da2899SCharles.Forsyth 
556*37da2899SCharles.Forsyth 
557*37da2899SCharles.Forsyth /* END */
558