1 /***************************************************************************/
5 /* The FreeType basic cache interface (body). */
7 /* Copyright 2003-2007, 2009-2011, 2013, 2014 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
20 #include FT_INTERNAL_OBJECTS_H
21 #include FT_INTERNAL_DEBUG_H
30 #define FT_COMPONENT trace_cache
37 typedef struct FTC_BasicAttrRec_
42 } FTC_BasicAttrRec, *FTC_BasicAttrs;
44 #define FTC_BASIC_ATTR_COMPARE( a, b ) \
45 FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \
46 (a)->load_flags == (b)->load_flags )
48 #define FTC_BASIC_ATTR_HASH( a ) \
49 ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags )
52 typedef struct FTC_BasicQueryRec_
55 FTC_BasicAttrRec attrs;
57 } FTC_BasicQueryRec, *FTC_BasicQuery;
60 typedef struct FTC_BasicFamilyRec_
63 FTC_BasicAttrRec attrs;
65 } FTC_BasicFamilyRec, *FTC_BasicFamily;
68 FT_CALLBACK_DEF( FT_Bool )
69 ftc_basic_family_compare( FTC_MruNode ftcfamily,
72 FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily;
73 FTC_BasicQuery query = (FTC_BasicQuery)ftcquery;
76 return FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs );
80 FT_CALLBACK_DEF( FT_Error )
81 ftc_basic_family_init( FTC_MruNode ftcfamily,
85 FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily;
86 FTC_BasicQuery query = (FTC_BasicQuery)ftcquery;
87 FTC_Cache cache = (FTC_Cache)ftccache;
90 FTC_Family_Init( FTC_FAMILY( family ), cache );
91 family->attrs = query->attrs;
96 FT_CALLBACK_DEF( FT_UInt )
97 ftc_basic_family_get_count( FTC_Family ftcfamily,
100 FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily;
106 error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id,
109 if ( error || !face )
112 if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs )
113 FT_TRACE1(( "ftc_basic_family_get_count:"
114 " too large number of glyphs in this face, truncated\n",
118 result = (FT_UInt)face->num_glyphs;
124 FT_CALLBACK_DEF( FT_Error )
125 ftc_basic_family_load_bitmap( FTC_Family ftcfamily,
130 FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily;
135 error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size );
138 FT_Face face = size->face;
141 error = FT_Load_Glyph( face, gindex,
142 family->attrs.load_flags | FT_LOAD_RENDER );
151 FT_CALLBACK_DEF( FT_Error )
152 ftc_basic_family_load_glyph( FTC_Family ftcfamily,
157 FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily;
159 FTC_Scaler scaler = &family->attrs.scaler;
164 /* we will now load the glyph image */
165 error = FTC_Manager_LookupSize( cache->manager,
172 error = FT_Load_Glyph( face, gindex, family->attrs.load_flags );
175 if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP ||
176 face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
182 error = FT_Get_Glyph( face->glyph, &glyph );
190 error = FT_THROW( Invalid_Argument );
199 FT_CALLBACK_DEF( FT_Bool )
200 ftc_basic_gnode_compare_faceid( FTC_Node ftcgnode,
201 FT_Pointer ftcface_id,
203 FT_Bool* list_changed )
205 FTC_GNode gnode = (FTC_GNode)ftcgnode;
206 FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
207 FTC_BasicFamily family = (FTC_BasicFamily)gnode->family;
212 *list_changed = FALSE;
213 result = FT_BOOL( family->attrs.scaler.face_id == face_id );
216 /* we must call this function to avoid this node from appearing
217 * in later lookups with the same face_id!
219 FTC_GNode_UnselectFamily( gnode, cache );
232 const FTC_IFamilyClassRec ftc_basic_image_family_class =
235 sizeof ( FTC_BasicFamilyRec ),
236 ftc_basic_family_compare,
237 ftc_basic_family_init,
238 0, /* FTC_MruNode_ResetFunc */
239 0 /* FTC_MruNode_DoneFunc */
241 ftc_basic_family_load_glyph
246 const FTC_GCacheClassRec ftc_basic_image_cache_class =
252 ftc_basic_gnode_compare_faceid,
255 sizeof ( FTC_GCacheRec ),
259 (FTC_MruListClass)&ftc_basic_image_family_class
263 /* documentation is in ftcache.h */
265 FT_EXPORT_DEF( FT_Error )
266 FTC_ImageCache_New( FTC_Manager manager,
267 FTC_ImageCache *acache )
269 return FTC_GCache_New( manager, &ftc_basic_image_cache_class,
270 (FTC_GCache*)acache );
274 /* documentation is in ftcache.h */
276 FT_EXPORT_DEF( FT_Error )
277 FTC_ImageCache_Lookup( FTC_ImageCache cache,
283 FTC_BasicQueryRec query;
284 FTC_Node node = 0; /* make compiler happy */
289 /* some argument checks are delayed to `FTC_Cache_Lookup' */
292 error = FT_THROW( Invalid_Argument );
300 if ( (FT_ULong)( type->flags - FT_INT_MIN ) > FT_UINT_MAX )
301 FT_TRACE1(( "FTC_ImageCache_Lookup:"
302 " higher bits in load_flags 0x%x are dropped\n",
303 type->flags & ~((FT_ULong)FT_UINT_MAX) ));
305 query.attrs.scaler.face_id = type->face_id;
306 query.attrs.scaler.width = type->width;
307 query.attrs.scaler.height = type->height;
308 query.attrs.load_flags = (FT_UInt)type->flags;
310 query.attrs.scaler.pixel = 1;
311 query.attrs.scaler.x_res = 0; /* make compilers happy */
312 query.attrs.scaler.y_res = 0;
314 hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;
316 #if 1 /* inlining is about 50% faster! */
317 FTC_GCACHE_LOOKUP_CMP( cache,
318 ftc_basic_family_compare,
325 error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
327 FTC_GQUERY( &query ),
332 *aglyph = FTC_INODE( node )->glyph;
346 /* documentation is in ftcache.h */
348 FT_EXPORT_DEF( FT_Error )
349 FTC_ImageCache_LookupScaler( FTC_ImageCache cache,
356 FTC_BasicQueryRec query;
357 FTC_Node node = 0; /* make compiler happy */
362 /* some argument checks are delayed to `FTC_Cache_Lookup' */
363 if ( !aglyph || !scaler )
365 error = FT_THROW( Invalid_Argument );
373 /* `FT_Load_Glyph' and `FT_Load_Char' take FT_UInt flags */
374 if ( load_flags > FT_UINT_MAX )
375 FT_TRACE1(( "FTC_ImageCache_LookupScaler:"
376 " higher bits in load_flags 0x%x are dropped\n",
377 load_flags & ~((FT_ULong)FT_UINT_MAX) ));
379 query.attrs.scaler = scaler[0];
380 query.attrs.load_flags = (FT_UInt)load_flags;
382 hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;
384 FTC_GCACHE_LOOKUP_CMP( cache,
385 ftc_basic_family_compare,
393 *aglyph = FTC_INODE( node )->glyph;
409 * basic small bitmap cache
414 const FTC_SFamilyClassRec ftc_basic_sbit_family_class =
417 sizeof ( FTC_BasicFamilyRec ),
418 ftc_basic_family_compare,
419 ftc_basic_family_init,
420 0, /* FTC_MruNode_ResetFunc */
421 0 /* FTC_MruNode_DoneFunc */
423 ftc_basic_family_get_count,
424 ftc_basic_family_load_bitmap
429 const FTC_GCacheClassRec ftc_basic_sbit_cache_class =
435 ftc_basic_gnode_compare_faceid,
438 sizeof ( FTC_GCacheRec ),
442 (FTC_MruListClass)&ftc_basic_sbit_family_class
446 /* documentation is in ftcache.h */
448 FT_EXPORT_DEF( FT_Error )
449 FTC_SBitCache_New( FTC_Manager manager,
450 FTC_SBitCache *acache )
452 return FTC_GCache_New( manager, &ftc_basic_sbit_cache_class,
453 (FTC_GCache*)acache );
457 /* documentation is in ftcache.h */
459 FT_EXPORT_DEF( FT_Error )
460 FTC_SBitCache_Lookup( FTC_SBitCache cache,
467 FTC_BasicQueryRec query;
468 FTC_Node node = 0; /* make compiler happy */
475 /* other argument checks delayed to `FTC_Cache_Lookup' */
477 return FT_THROW( Invalid_Argument );
481 if ( (FT_ULong)( type->flags - FT_INT_MIN ) > FT_UINT_MAX )
482 FT_TRACE1(( "FTC_ImageCache_Lookup:"
483 " higher bits in load_flags 0x%x are dropped\n",
484 type->flags & ~((FT_ULong)FT_UINT_MAX) ));
486 query.attrs.scaler.face_id = type->face_id;
487 query.attrs.scaler.width = type->width;
488 query.attrs.scaler.height = type->height;
489 query.attrs.load_flags = (FT_UInt)type->flags;
491 query.attrs.scaler.pixel = 1;
492 query.attrs.scaler.x_res = 0; /* make compilers happy */
493 query.attrs.scaler.y_res = 0;
495 /* beware, the hash must be the same for all glyph ranges! */
496 hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
497 gindex / FTC_SBIT_ITEMS_PER_NODE;
499 #if 1 /* inlining is about 50% faster! */
500 FTC_GCACHE_LOOKUP_CMP( cache,
501 ftc_basic_family_compare,
508 error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
511 FTC_GQUERY( &query ),
517 *ansbit = FTC_SNODE( node )->sbits +
518 ( gindex - FTC_GNODE( node )->gindex );
531 /* documentation is in ftcache.h */
533 FT_EXPORT_DEF( FT_Error )
534 FTC_SBitCache_LookupScaler( FTC_SBitCache cache,
542 FTC_BasicQueryRec query;
543 FTC_Node node = 0; /* make compiler happy */
550 /* other argument checks delayed to `FTC_Cache_Lookup' */
551 if ( !ansbit || !scaler )
552 return FT_THROW( Invalid_Argument );
556 /* `FT_Load_Glyph' and `FT_Load_Char' take FT_UInt flags */
557 if ( load_flags > FT_UINT_MAX )
558 FT_TRACE1(( "FTC_ImageCache_LookupScaler:"
559 " higher bits in load_flags 0x%x are dropped\n",
560 load_flags & ~((FT_ULong)FT_UINT_MAX) ));
562 query.attrs.scaler = scaler[0];
563 query.attrs.load_flags = (FT_UInt)load_flags;
565 /* beware, the hash must be the same for all glyph ranges! */
566 hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
567 gindex / FTC_SBIT_ITEMS_PER_NODE;
569 FTC_GCACHE_LOOKUP_CMP( cache,
570 ftc_basic_family_compare,
579 *ansbit = FTC_SNODE( node )->sbits +
580 ( gindex - FTC_GNODE( node )->gindex );