1 /***************************************************************************/
5 /* The FreeType basic cache interface (body). */
7 /* Copyright 2003-2007, 2009-2011, 2013 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
)
114 FT_TRACE1(( "ftc_basic_family_get_count: too large number of glyphs " ));
115 FT_TRACE1(( "in this face, truncated\n", face
->num_glyphs
));
119 result
= (FT_UInt
)face
->num_glyphs
;
125 FT_CALLBACK_DEF( FT_Error
)
126 ftc_basic_family_load_bitmap( FTC_Family ftcfamily
,
131 FTC_BasicFamily family
= (FTC_BasicFamily
)ftcfamily
;
136 error
= FTC_Manager_LookupSize( manager
, &family
->attrs
.scaler
, &size
);
139 FT_Face face
= size
->face
;
142 error
= FT_Load_Glyph( face
, gindex
,
143 family
->attrs
.load_flags
| FT_LOAD_RENDER
);
152 FT_CALLBACK_DEF( FT_Error
)
153 ftc_basic_family_load_glyph( FTC_Family ftcfamily
,
158 FTC_BasicFamily family
= (FTC_BasicFamily
)ftcfamily
;
160 FTC_Scaler scaler
= &family
->attrs
.scaler
;
165 /* we will now load the glyph image */
166 error
= FTC_Manager_LookupSize( cache
->manager
,
173 error
= FT_Load_Glyph( face
, gindex
, family
->attrs
.load_flags
);
176 if ( face
->glyph
->format
== FT_GLYPH_FORMAT_BITMAP
||
177 face
->glyph
->format
== FT_GLYPH_FORMAT_OUTLINE
)
183 error
= FT_Get_Glyph( face
->glyph
, &glyph
);
191 error
= FT_THROW( Invalid_Argument
);
200 FT_CALLBACK_DEF( FT_Bool
)
201 ftc_basic_gnode_compare_faceid( FTC_Node ftcgnode
,
202 FT_Pointer ftcface_id
,
204 FT_Bool
* list_changed
)
206 FTC_GNode gnode
= (FTC_GNode
)ftcgnode
;
207 FTC_FaceID face_id
= (FTC_FaceID
)ftcface_id
;
208 FTC_BasicFamily family
= (FTC_BasicFamily
)gnode
->family
;
213 *list_changed
= FALSE
;
214 result
= FT_BOOL( family
->attrs
.scaler
.face_id
== face_id
);
217 /* we must call this function to avoid this node from appearing
218 * in later lookups with the same face_id!
220 FTC_GNode_UnselectFamily( gnode
, cache
);
232 FT_CALLBACK_TABLE_DEF
233 const FTC_IFamilyClassRec ftc_basic_image_family_class
=
236 sizeof ( FTC_BasicFamilyRec
),
237 ftc_basic_family_compare
,
238 ftc_basic_family_init
,
239 0, /* FTC_MruNode_ResetFunc */
240 0 /* FTC_MruNode_DoneFunc */
242 ftc_basic_family_load_glyph
246 FT_CALLBACK_TABLE_DEF
247 const FTC_GCacheClassRec ftc_basic_image_cache_class
=
253 ftc_basic_gnode_compare_faceid
,
256 sizeof ( FTC_GCacheRec
),
260 (FTC_MruListClass
)&ftc_basic_image_family_class
264 /* documentation is in ftcache.h */
266 FT_EXPORT_DEF( FT_Error
)
267 FTC_ImageCache_New( FTC_Manager manager
,
268 FTC_ImageCache
*acache
)
270 return FTC_GCache_New( manager
, &ftc_basic_image_cache_class
,
271 (FTC_GCache
*)acache
);
275 /* documentation is in ftcache.h */
277 FT_EXPORT_DEF( FT_Error
)
278 FTC_ImageCache_Lookup( FTC_ImageCache cache
,
284 FTC_BasicQueryRec query
;
285 FTC_Node node
= 0; /* make compiler happy */
290 /* some argument checks are delayed to FTC_Cache_Lookup */
293 error
= FT_THROW( Invalid_Argument
);
302 if ( (FT_ULong
)(type
->flags
- FT_INT_MIN
) > FT_UINT_MAX
)
304 FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" ));
305 FT_TRACE1(( "0x%x are dropped\n", (type
->flags
& ~((FT_ULong
)FT_UINT_MAX
)) ));
308 query
.attrs
.scaler
.face_id
= type
->face_id
;
309 query
.attrs
.scaler
.width
= type
->width
;
310 query
.attrs
.scaler
.height
= type
->height
;
311 query
.attrs
.load_flags
= (FT_UInt
)type
->flags
;
314 query
.attrs
.scaler
.pixel
= 1;
315 query
.attrs
.scaler
.x_res
= 0; /* make compilers happy */
316 query
.attrs
.scaler
.y_res
= 0;
318 hash
= FTC_BASIC_ATTR_HASH( &query
.attrs
) + gindex
;
320 #if 1 /* inlining is about 50% faster! */
321 FTC_GCACHE_LOOKUP_CMP( cache
,
322 ftc_basic_family_compare
,
329 error
= FTC_GCache_Lookup( FTC_GCACHE( cache
),
331 FTC_GQUERY( &query
),
336 *aglyph
= FTC_INODE( node
)->glyph
;
350 /* documentation is in ftcache.h */
352 FT_EXPORT_DEF( FT_Error
)
353 FTC_ImageCache_LookupScaler( FTC_ImageCache cache
,
360 FTC_BasicQueryRec query
;
361 FTC_Node node
= 0; /* make compiler happy */
366 /* some argument checks are delayed to FTC_Cache_Lookup */
367 if ( !aglyph
|| !scaler
)
369 error
= FT_THROW( Invalid_Argument
);
377 /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */
378 if ( load_flags
> FT_UINT_MAX
)
380 FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" ));
381 FT_TRACE1(( "0x%x are dropped\n", (load_flags
& ~((FT_ULong
)FT_UINT_MAX
)) ));
384 query
.attrs
.scaler
= scaler
[0];
385 query
.attrs
.load_flags
= (FT_UInt
)load_flags
;
387 hash
= FTC_BASIC_ATTR_HASH( &query
.attrs
) + gindex
;
389 FTC_GCACHE_LOOKUP_CMP( cache
,
390 ftc_basic_family_compare
,
398 *aglyph
= FTC_INODE( node
)->glyph
;
414 * basic small bitmap cache
418 FT_CALLBACK_TABLE_DEF
419 const FTC_SFamilyClassRec ftc_basic_sbit_family_class
=
422 sizeof ( FTC_BasicFamilyRec
),
423 ftc_basic_family_compare
,
424 ftc_basic_family_init
,
425 0, /* FTC_MruNode_ResetFunc */
426 0 /* FTC_MruNode_DoneFunc */
428 ftc_basic_family_get_count
,
429 ftc_basic_family_load_bitmap
433 FT_CALLBACK_TABLE_DEF
434 const FTC_GCacheClassRec ftc_basic_sbit_cache_class
=
440 ftc_basic_gnode_compare_faceid
,
443 sizeof ( FTC_GCacheRec
),
447 (FTC_MruListClass
)&ftc_basic_sbit_family_class
451 /* documentation is in ftcache.h */
453 FT_EXPORT_DEF( FT_Error
)
454 FTC_SBitCache_New( FTC_Manager manager
,
455 FTC_SBitCache
*acache
)
457 return FTC_GCache_New( manager
, &ftc_basic_sbit_cache_class
,
458 (FTC_GCache
*)acache
);
462 /* documentation is in ftcache.h */
464 FT_EXPORT_DEF( FT_Error
)
465 FTC_SBitCache_Lookup( FTC_SBitCache cache
,
472 FTC_BasicQueryRec query
;
473 FTC_Node node
= 0; /* make compiler happy */
480 /* other argument checks delayed to FTC_Cache_Lookup */
482 return FT_THROW( Invalid_Argument
);
487 if ( (FT_ULong
)(type
->flags
- FT_INT_MIN
) > FT_UINT_MAX
)
489 FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" ));
490 FT_TRACE1(( "0x%x are dropped\n", (type
->flags
& ~((FT_ULong
)FT_UINT_MAX
)) ));
493 query
.attrs
.scaler
.face_id
= type
->face_id
;
494 query
.attrs
.scaler
.width
= type
->width
;
495 query
.attrs
.scaler
.height
= type
->height
;
496 query
.attrs
.load_flags
= (FT_UInt
)type
->flags
;
499 query
.attrs
.scaler
.pixel
= 1;
500 query
.attrs
.scaler
.x_res
= 0; /* make compilers happy */
501 query
.attrs
.scaler
.y_res
= 0;
503 /* beware, the hash must be the same for all glyph ranges! */
504 hash
= FTC_BASIC_ATTR_HASH( &query
.attrs
) +
505 gindex
/ FTC_SBIT_ITEMS_PER_NODE
;
507 #if 1 /* inlining is about 50% faster! */
508 FTC_GCACHE_LOOKUP_CMP( cache
,
509 ftc_basic_family_compare
,
516 error
= FTC_GCache_Lookup( FTC_GCACHE( cache
),
519 FTC_GQUERY( &query
),
525 *ansbit
= FTC_SNODE( node
)->sbits
+
526 ( gindex
- FTC_GNODE( node
)->gindex
);
539 /* documentation is in ftcache.h */
541 FT_EXPORT_DEF( FT_Error
)
542 FTC_SBitCache_LookupScaler( FTC_SBitCache cache
,
550 FTC_BasicQueryRec query
;
551 FTC_Node node
= 0; /* make compiler happy */
558 /* other argument checks delayed to FTC_Cache_Lookup */
559 if ( !ansbit
|| !scaler
)
560 return FT_THROW( Invalid_Argument
);
564 /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */
565 if ( load_flags
> FT_UINT_MAX
)
567 FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" ));
568 FT_TRACE1(( "0x%x are dropped\n", (load_flags
& ~((FT_ULong
)FT_UINT_MAX
)) ));
571 query
.attrs
.scaler
= scaler
[0];
572 query
.attrs
.load_flags
= (FT_UInt
)load_flags
;
574 /* beware, the hash must be the same for all glyph ranges! */
575 hash
= FTC_BASIC_ATTR_HASH( &query
.attrs
) +
576 gindex
/ FTC_SBIT_ITEMS_PER_NODE
;
578 FTC_GCACHE_LOOKUP_CMP( cache
,
579 ftc_basic_family_compare
,
588 *ansbit
= FTC_SNODE( node
)->sbits
+
589 ( gindex
- FTC_GNODE( node
)->gindex
);