source: trunk/poppler/freetype-2.1.10/src/cache/ftcbasic.c @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 15 years ago

First import

File size: 11.8 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  ftcbasic.c                                                             */
4/*                                                                         */
5/*    The FreeType basic cache interface (body).                           */
6/*                                                                         */
7/*  Copyright 2003, 2004, 2005 by                                          */
8/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9/*                                                                         */
10/*  This file is part of the FreeType project, and may only be used,       */
11/*  modified, and distributed under the terms of the FreeType project      */
12/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13/*  this file you indicate that you have read the license and              */
14/*  understand and accept it fully.                                        */
15/*                                                                         */
16/***************************************************************************/
17
18
19#include <ft2build.h>
20#include FT_CACHE_H
21#include FT_CACHE_INTERNAL_GLYPH_H
22#include FT_CACHE_INTERNAL_IMAGE_H
23#include FT_CACHE_INTERNAL_SBITS_H
24#include FT_INTERNAL_MEMORY_H
25
26#include "ftccback.h"
27#include "ftcerror.h"
28
29
30  /*
31   *  Basic Families
32   *
33   */
34  typedef struct  FTC_BasicAttrRec_
35  {
36    FTC_ScalerRec  scaler;
37    FT_UInt        load_flags;
38
39  } FTC_BasicAttrRec, *FTC_BasicAttrs;
40
41#define FTC_BASIC_ATTR_COMPARE( a, b )                                 \
42          FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \
43                   (a)->load_flags == (b)->load_flags               )
44
45#define FTC_BASIC_ATTR_HASH( a )                                   \
46          ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags )
47
48
49  typedef struct  FTC_BasicQueryRec_
50  {
51    FTC_GQueryRec     gquery;
52    FTC_BasicAttrRec  attrs;
53
54  } FTC_BasicQueryRec, *FTC_BasicQuery;
55
56
57  typedef struct  FTC_BasicFamilyRec_
58  {
59    FTC_FamilyRec     family;
60    FTC_BasicAttrRec  attrs;
61
62  } FTC_BasicFamilyRec, *FTC_BasicFamily;
63
64
65  FT_CALLBACK_DEF( FT_Bool )
66  ftc_basic_family_compare( FTC_MruNode  ftcfamily,
67                            FT_Pointer   ftcquery )
68  {
69    FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;
70    FTC_BasicQuery   query  = (FTC_BasicQuery)ftcquery;
71
72
73    return FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs );
74  }
75
76
77  FT_CALLBACK_DEF( FT_Error )
78  ftc_basic_family_init( FTC_MruNode  ftcfamily,
79                         FT_Pointer   ftcquery,
80                         FT_Pointer   ftccache )
81  {
82    FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;
83    FTC_BasicQuery   query  = (FTC_BasicQuery)ftcquery;
84    FTC_Cache        cache  = (FTC_Cache)ftccache;
85
86
87    FTC_Family_Init( FTC_FAMILY( family ), cache );
88    family->attrs = query->attrs;
89    return 0;
90  }
91
92
93  FT_CALLBACK_DEF( FT_UInt )
94  ftc_basic_family_get_count( FTC_Family   ftcfamily,
95                              FTC_Manager  manager )
96  {
97    FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;
98    FT_Error         error;
99    FT_Face          face;
100    FT_UInt          result = 0;
101
102
103    error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id,
104                                    &face );
105    if ( !error )
106      result = face->num_glyphs;
107
108    return result;
109  }
110
111
112  FT_CALLBACK_DEF( FT_Error )
113  ftc_basic_family_load_bitmap( FTC_Family   ftcfamily,
114                                FT_UInt      gindex,
115                                FTC_Manager  manager,
116                                FT_Face     *aface )
117  {
118    FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;
119    FT_Error         error;
120    FT_Size          size;
121
122
123    error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size );
124    if ( !error )
125    {
126      FT_Face  face = size->face;
127
128
129      error = FT_Load_Glyph( face, gindex,
130                             family->attrs.load_flags | FT_LOAD_RENDER );
131      if ( !error )
132        *aface = face;
133    }
134
135    return error;
136  }
137
138
139  FT_CALLBACK_DEF( FT_Error )
140  ftc_basic_family_load_glyph( FTC_Family  ftcfamily,
141                               FT_UInt     gindex,
142                               FTC_Cache   cache,
143                               FT_Glyph   *aglyph )
144  {
145    FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;
146    FT_Error         error;
147    FTC_Scaler       scaler = &family->attrs.scaler;
148    FT_Face          face;
149    FT_Size          size;
150
151
152    /* we will now load the glyph image */
153    error = FTC_Manager_LookupSize( cache->manager,
154                                    scaler,
155                                    &size );
156    if ( !error )
157    {
158      face = size->face;
159
160      error = FT_Load_Glyph( face, gindex, family->attrs.load_flags );
161      if ( !error )
162      {
163        if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP  ||
164             face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
165        {
166          /* ok, copy it */
167          FT_Glyph  glyph;
168
169
170          error = FT_Get_Glyph( face->glyph, &glyph );
171          if ( !error )
172          {
173            *aglyph = glyph;
174            goto Exit;
175          }
176        }
177        else
178          error = FTC_Err_Invalid_Argument;
179      }
180    }
181
182  Exit:
183    return error;
184  }
185
186
187  FT_CALLBACK_DEF( FT_Bool )
188  ftc_basic_gnode_compare_faceid( FTC_Node    ftcgnode,
189                                  FT_Pointer  ftcface_id,
190                                  FTC_Cache   cache )
191  {
192    FTC_GNode        gnode   = (FTC_GNode)ftcgnode;
193    FTC_FaceID       face_id = (FTC_FaceID)ftcface_id;
194    FTC_BasicFamily  family  = (FTC_BasicFamily)gnode->family;
195    FT_Bool          result;
196
197
198    result = FT_BOOL( family->attrs.scaler.face_id == face_id );
199    if ( result )
200    {
201      /* we must call this function to avoid this node from appearing
202       * in later lookups with the same face_id!
203       */
204      FTC_GNode_UnselectFamily( gnode, cache );
205    }
206    return result;
207  }
208
209
210 /*
211  *
212  * basic image cache
213  *
214  */
215
216  FT_CALLBACK_TABLE_DEF
217  const FTC_IFamilyClassRec  ftc_basic_image_family_class =
218  {
219    {
220      sizeof ( FTC_BasicFamilyRec ),
221      ftc_basic_family_compare,
222      ftc_basic_family_init,
223      0,                        /* FTC_MruNode_ResetFunc */
224      0                         /* FTC_MruNode_DoneFunc  */
225    },
226    ftc_basic_family_load_glyph
227  };
228
229
230  FT_CALLBACK_TABLE_DEF
231  const FTC_GCacheClassRec  ftc_basic_image_cache_class =
232  {
233    {
234      ftc_inode_new,
235      ftc_inode_weight,
236      ftc_gnode_compare,
237      ftc_basic_gnode_compare_faceid,
238      ftc_inode_free,
239
240      sizeof ( FTC_GCacheRec ),
241      ftc_gcache_init,
242      ftc_gcache_done
243    },
244    (FTC_MruListClass)&ftc_basic_image_family_class
245  };
246
247
248  /* documentation is in ftcache.h */
249
250  FT_EXPORT_DEF( FT_Error )
251  FTC_ImageCache_New( FTC_Manager      manager,
252                      FTC_ImageCache  *acache )
253  {
254    return FTC_GCache_New( manager, &ftc_basic_image_cache_class,
255                           (FTC_GCache*)acache );
256  }
257
258
259  /* documentation is in ftcache.h */
260
261  FT_EXPORT_DEF( FT_Error )
262  FTC_ImageCache_Lookup( FTC_ImageCache  cache,
263                         FTC_ImageType   type,
264                         FT_UInt         gindex,
265                         FT_Glyph       *aglyph,
266                         FTC_Node       *anode )
267  {
268    FTC_BasicQueryRec  query;
269    FTC_INode          node = 0;  /* make compiler happy */
270    FT_Error           error;
271    FT_UInt32          hash;
272
273
274    /* some argument checks are delayed to FTC_Cache_Lookup */
275    if ( !aglyph )
276    {
277      error = FTC_Err_Invalid_Argument;
278      goto Exit;
279    }
280
281    *aglyph = NULL;
282    if ( anode )
283      *anode  = NULL;
284
285    query.attrs.scaler.face_id = type->face_id;
286    query.attrs.scaler.width   = type->width;
287    query.attrs.scaler.height  = type->height;
288    query.attrs.scaler.pixel   = 1;
289    query.attrs.load_flags     = type->flags;
290
291    query.attrs.scaler.x_res   = 0;  /* make compilers happy */
292    query.attrs.scaler.y_res   = 0;
293
294    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;
295
296#if 1  /* inlining is about 50% faster! */
297    FTC_GCACHE_LOOKUP_CMP( cache,
298                           ftc_basic_family_compare,
299                           FTC_GNode_Compare,
300                           hash, gindex,
301                           &query,
302                           node,
303                           error );
304#else
305    error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
306                               hash, gindex,
307                               FTC_GQUERY( &query ),
308                               (FTC_Node*) &node );
309#endif
310    if ( !error )
311    {
312      *aglyph = FTC_INODE( node )->glyph;
313
314      if ( anode )
315      {
316        *anode = FTC_NODE( node );
317        FTC_NODE( node )->ref_count++;
318      }
319    }
320
321  Exit:
322    return error;
323  }
324
325
326 /*
327  *
328  * basic small bitmap cache
329  *
330  */
331
332
333  FT_CALLBACK_TABLE_DEF
334  const FTC_SFamilyClassRec  ftc_basic_sbit_family_class =
335  {
336    {
337      sizeof( FTC_BasicFamilyRec ),
338      ftc_basic_family_compare,
339      ftc_basic_family_init,
340      0,                            /* FTC_MruNode_ResetFunc */
341      0                             /* FTC_MruNode_DoneFunc  */
342    },
343    ftc_basic_family_get_count,
344    ftc_basic_family_load_bitmap
345  };
346
347
348  FT_CALLBACK_TABLE_DEF
349  const FTC_GCacheClassRec  ftc_basic_sbit_cache_class =
350  {
351    {
352      ftc_snode_new,
353      ftc_snode_weight,
354      ftc_snode_compare,
355      ftc_basic_gnode_compare_faceid,
356      ftc_snode_free,
357
358      sizeof ( FTC_GCacheRec ),
359      ftc_gcache_init,
360      ftc_gcache_done
361    },
362    (FTC_MruListClass)&ftc_basic_sbit_family_class
363  };
364
365
366  /* documentation is in ftcache.h */
367
368  FT_EXPORT_DEF( FT_Error )
369  FTC_SBitCache_New( FTC_Manager     manager,
370                     FTC_SBitCache  *acache )
371  {
372    return FTC_GCache_New( manager, &ftc_basic_sbit_cache_class,
373                           (FTC_GCache*)acache );
374  }
375
376
377  /* documentation is in ftcache.h */
378
379  FT_EXPORT_DEF( FT_Error )
380  FTC_SBitCache_Lookup( FTC_SBitCache  cache,
381                        FTC_ImageType  type,
382                        FT_UInt        gindex,
383                        FTC_SBit      *ansbit,
384                        FTC_Node      *anode )
385  {
386    FT_Error           error;
387    FTC_BasicQueryRec  query;
388    FTC_SNode          node = 0; /* make compiler happy */
389    FT_UInt32          hash;
390
391
392    if ( anode )
393      *anode = NULL;
394
395    /* other argument checks delayed to FTC_Cache_Lookup */
396    if ( !ansbit )
397      return FTC_Err_Invalid_Argument;
398
399    *ansbit = NULL;
400
401    query.attrs.scaler.face_id = type->face_id;
402    query.attrs.scaler.width   = type->width;
403    query.attrs.scaler.height  = type->height;
404    query.attrs.scaler.pixel   = 1;
405    query.attrs.load_flags     = type->flags;
406
407    query.attrs.scaler.x_res   = 0;  /* make compilers happy */
408    query.attrs.scaler.y_res   = 0;
409
410    /* beware, the hash must be the same for all glyph ranges! */
411    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
412           gindex / FTC_SBIT_ITEMS_PER_NODE;
413
414#if 1  /* inlining is about 50% faster! */
415    FTC_GCACHE_LOOKUP_CMP( cache,
416                           ftc_basic_family_compare,
417                           FTC_SNode_Compare,
418                           hash, gindex,
419                           &query,
420                           node,
421                           error );
422#else
423    error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
424                               hash,
425                               gindex,
426                               FTC_GQUERY( &query ),
427                               (FTC_Node*)&node );
428#endif
429    if ( error )
430      goto Exit;
431
432    *ansbit = node->sbits + ( gindex - FTC_GNODE( node )->gindex );
433
434    if ( anode )
435    {
436      *anode = FTC_NODE( node );
437      FTC_NODE( node )->ref_count++;
438    }
439
440  Exit:
441    return error;
442  }
443
444
445/* END */
Note: See TracBrowser for help on using the repository browser.