1 /***************************************************************************/
5 /* The FreeType basic cache interface (body). */
7 /* Copyright 2003, 2004, 2005, 2006, 2007, 2009 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_DEBUG_H
29 #define FT_COMPONENT trace_cache
32 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
35 * These structures correspond to the FTC_Font and FTC_ImageDesc types
36 * that were defined in version 2.1.7.
38 typedef struct FTC_OldFontRec_
44 } FTC_OldFontRec
, *FTC_OldFont
;
47 typedef struct FTC_OldImageDescRec_
52 } FTC_OldImageDescRec
, *FTC_OldImageDesc
;
56 * Notice that FTC_OldImageDescRec and FTC_ImageTypeRec are nearly
57 * identical, bit-wise. The only difference is that the `width' and
58 * `height' fields are expressed as 16-bit integers in the old structure,
59 * and as normal `int' in the new one.
61 * We are going to perform a weird hack to detect which structure is
62 * being passed to the image and sbit caches. If the new structure's
63 * `width' is larger than 0x10000, we assume that we are really receiving
64 * an FTC_OldImageDesc.
67 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
74 typedef struct FTC_BasicAttrRec_
79 } FTC_BasicAttrRec
, *FTC_BasicAttrs
;
81 #define FTC_BASIC_ATTR_COMPARE( a, b ) \
82 FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \
83 (a)->load_flags == (b)->load_flags )
85 #define FTC_BASIC_ATTR_HASH( a ) \
86 ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags )
89 typedef struct FTC_BasicQueryRec_
92 FTC_BasicAttrRec attrs
;
94 } FTC_BasicQueryRec
, *FTC_BasicQuery
;
97 typedef struct FTC_BasicFamilyRec_
100 FTC_BasicAttrRec attrs
;
102 } FTC_BasicFamilyRec
, *FTC_BasicFamily
;
105 FT_CALLBACK_DEF( FT_Bool
)
106 ftc_basic_family_compare( FTC_MruNode ftcfamily
,
107 FT_Pointer ftcquery
)
109 FTC_BasicFamily family
= (FTC_BasicFamily
)ftcfamily
;
110 FTC_BasicQuery query
= (FTC_BasicQuery
)ftcquery
;
113 return FTC_BASIC_ATTR_COMPARE( &family
->attrs
, &query
->attrs
);
117 FT_CALLBACK_DEF( FT_Error
)
118 ftc_basic_family_init( FTC_MruNode ftcfamily
,
120 FT_Pointer ftccache
)
122 FTC_BasicFamily family
= (FTC_BasicFamily
)ftcfamily
;
123 FTC_BasicQuery query
= (FTC_BasicQuery
)ftcquery
;
124 FTC_Cache cache
= (FTC_Cache
)ftccache
;
127 FTC_Family_Init( FTC_FAMILY( family
), cache
);
128 family
->attrs
= query
->attrs
;
133 FT_CALLBACK_DEF( FT_UInt
)
134 ftc_basic_family_get_count( FTC_Family ftcfamily
,
135 FTC_Manager manager
)
137 FTC_BasicFamily family
= (FTC_BasicFamily
)ftcfamily
;
143 error
= FTC_Manager_LookupFace( manager
, family
->attrs
.scaler
.face_id
,
146 if ( error
|| !face
)
149 if ( (FT_ULong
)face
->num_glyphs
> FT_UINT_MAX
|| 0 > face
->num_glyphs
)
151 FT_TRACE1(( "ftc_basic_family_get_count: too large number of glyphs " ));
152 FT_TRACE1(( "in this face, truncated\n", face
->num_glyphs
));
156 result
= (FT_UInt
)face
->num_glyphs
;
162 FT_CALLBACK_DEF( FT_Error
)
163 ftc_basic_family_load_bitmap( FTC_Family ftcfamily
,
168 FTC_BasicFamily family
= (FTC_BasicFamily
)ftcfamily
;
173 error
= FTC_Manager_LookupSize( manager
, &family
->attrs
.scaler
, &size
);
176 FT_Face face
= size
->face
;
179 error
= FT_Load_Glyph( face
, gindex
,
180 family
->attrs
.load_flags
| FT_LOAD_RENDER
);
189 FT_CALLBACK_DEF( FT_Error
)
190 ftc_basic_family_load_glyph( FTC_Family ftcfamily
,
195 FTC_BasicFamily family
= (FTC_BasicFamily
)ftcfamily
;
197 FTC_Scaler scaler
= &family
->attrs
.scaler
;
202 /* we will now load the glyph image */
203 error
= FTC_Manager_LookupSize( cache
->manager
,
210 error
= FT_Load_Glyph( face
, gindex
, family
->attrs
.load_flags
);
213 if ( face
->glyph
->format
== FT_GLYPH_FORMAT_BITMAP
||
214 face
->glyph
->format
== FT_GLYPH_FORMAT_OUTLINE
)
220 error
= FT_Get_Glyph( face
->glyph
, &glyph
);
228 error
= FTC_Err_Invalid_Argument
;
237 FT_CALLBACK_DEF( FT_Bool
)
238 ftc_basic_gnode_compare_faceid( FTC_Node ftcgnode
,
239 FT_Pointer ftcface_id
,
242 FTC_GNode gnode
= (FTC_GNode
)ftcgnode
;
243 FTC_FaceID face_id
= (FTC_FaceID
)ftcface_id
;
244 FTC_BasicFamily family
= (FTC_BasicFamily
)gnode
->family
;
248 result
= FT_BOOL( family
->attrs
.scaler
.face_id
== face_id
);
251 /* we must call this function to avoid this node from appearing
252 * in later lookups with the same face_id!
254 FTC_GNode_UnselectFamily( gnode
, cache
);
266 FT_CALLBACK_TABLE_DEF
267 const FTC_IFamilyClassRec ftc_basic_image_family_class
=
270 sizeof ( FTC_BasicFamilyRec
),
271 ftc_basic_family_compare
,
272 ftc_basic_family_init
,
273 0, /* FTC_MruNode_ResetFunc */
274 0 /* FTC_MruNode_DoneFunc */
276 ftc_basic_family_load_glyph
280 FT_CALLBACK_TABLE_DEF
281 const FTC_GCacheClassRec ftc_basic_image_cache_class
=
287 ftc_basic_gnode_compare_faceid
,
290 sizeof ( FTC_GCacheRec
),
294 (FTC_MruListClass
)&ftc_basic_image_family_class
298 /* documentation is in ftcache.h */
300 FT_EXPORT_DEF( FT_Error
)
301 FTC_ImageCache_New( FTC_Manager manager
,
302 FTC_ImageCache
*acache
)
304 return FTC_GCache_New( manager
, &ftc_basic_image_cache_class
,
305 (FTC_GCache
*)acache
);
309 /* documentation is in ftcache.h */
311 FT_EXPORT_DEF( FT_Error
)
312 FTC_ImageCache_Lookup( FTC_ImageCache cache
,
318 FTC_BasicQueryRec query
;
319 FTC_Node node
= 0; /* make compiler happy */
324 /* some argument checks are delayed to FTC_Cache_Lookup */
327 error
= FTC_Err_Invalid_Argument
;
335 #if defined( FT_CONFIG_OPTION_OLD_INTERNALS ) && ( FT_INT_MAX > 0xFFFFU )
338 * This one is a major hack used to detect whether we are passed a
339 * regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one.
341 if ( (FT_ULong
)type
->width
>= 0x10000L
)
343 FTC_OldImageDesc desc
= (FTC_OldImageDesc
)type
;
346 query
.attrs
.scaler
.face_id
= desc
->font
.face_id
;
347 query
.attrs
.scaler
.width
= desc
->font
.pix_width
;
348 query
.attrs
.scaler
.height
= desc
->font
.pix_height
;
349 query
.attrs
.load_flags
= desc
->flags
;
353 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
356 if ( (FT_ULong
)(type
->flags
- FT_INT_MIN
) > FT_UINT_MAX
)
358 FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" ));
359 FT_TRACE1(( "0x%x are dropped\n", (type
->flags
& ~((FT_ULong
)FT_UINT_MAX
)) ));
362 query
.attrs
.scaler
.face_id
= type
->face_id
;
363 query
.attrs
.scaler
.width
= type
->width
;
364 query
.attrs
.scaler
.height
= type
->height
;
365 query
.attrs
.load_flags
= (FT_UInt
)type
->flags
;
368 query
.attrs
.scaler
.pixel
= 1;
369 query
.attrs
.scaler
.x_res
= 0; /* make compilers happy */
370 query
.attrs
.scaler
.y_res
= 0;
372 hash
= FTC_BASIC_ATTR_HASH( &query
.attrs
) + gindex
;
374 #if 1 /* inlining is about 50% faster! */
375 FTC_GCACHE_LOOKUP_CMP( cache
,
376 ftc_basic_family_compare
,
383 error
= FTC_GCache_Lookup( FTC_GCACHE( cache
),
385 FTC_GQUERY( &query
),
390 *aglyph
= FTC_INODE( node
)->glyph
;
404 /* documentation is in ftcache.h */
406 FT_EXPORT_DEF( FT_Error
)
407 FTC_ImageCache_LookupScaler( FTC_ImageCache cache
,
414 FTC_BasicQueryRec query
;
415 FTC_Node node
= 0; /* make compiler happy */
420 /* some argument checks are delayed to FTC_Cache_Lookup */
421 if ( !aglyph
|| !scaler
)
423 error
= FTC_Err_Invalid_Argument
;
431 /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */
432 if ( load_flags
> FT_UINT_MAX
)
434 FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" ));
435 FT_TRACE1(( "0x%x are dropped\n", (load_flags
& ~((FT_ULong
)FT_UINT_MAX
)) ));
438 query
.attrs
.scaler
= scaler
[0];
439 query
.attrs
.load_flags
= (FT_UInt
)load_flags
;
441 hash
= FTC_BASIC_ATTR_HASH( &query
.attrs
) + gindex
;
443 FTC_GCACHE_LOOKUP_CMP( cache
,
444 ftc_basic_family_compare
,
452 *aglyph
= FTC_INODE( node
)->glyph
;
467 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
469 /* yet another backwards-legacy structure */
470 typedef struct FTC_OldImage_Desc_
478 #define FTC_OLD_IMAGE_FORMAT( x ) ( (x) & 7 )
481 #define ftc_old_image_format_bitmap 0x0000
482 #define ftc_old_image_format_outline 0x0001
484 #define ftc_old_image_format_mask 0x000F
486 #define ftc_old_image_flag_monochrome 0x0010
487 #define ftc_old_image_flag_unhinted 0x0020
488 #define ftc_old_image_flag_autohinted 0x0040
489 #define ftc_old_image_flag_unscaled 0x0080
490 #define ftc_old_image_flag_no_sbits 0x0100
492 /* monochrome bitmap */
493 #define ftc_old_image_mono ftc_old_image_format_bitmap | \
494 ftc_old_image_flag_monochrome
496 /* anti-aliased bitmap */
497 #define ftc_old_image_grays ftc_old_image_format_bitmap
500 #define ftc_old_image_outline ftc_old_image_format_outline
504 ftc_image_type_from_old_desc( FTC_ImageType typ
,
505 FTC_OldImage_Desc
* desc
)
507 typ
->face_id
= desc
->font
.face_id
;
508 typ
->width
= desc
->font
.pix_width
;
509 typ
->height
= desc
->font
.pix_height
;
511 /* convert image type flags to load flags */
513 FT_UInt load_flags
= FT_LOAD_DEFAULT
;
514 FT_UInt type
= desc
->image_type
;
517 /* determine load flags, depending on the font description's */
520 if ( FTC_OLD_IMAGE_FORMAT( type
) == ftc_old_image_format_bitmap
)
522 if ( type
& ftc_old_image_flag_monochrome
)
523 load_flags
|= FT_LOAD_MONOCHROME
;
525 /* disable embedded bitmaps loading if necessary */
526 if ( type
& ftc_old_image_flag_no_sbits
)
527 load_flags
|= FT_LOAD_NO_BITMAP
;
531 /* we want an outline, don't load embedded bitmaps */
532 load_flags
|= FT_LOAD_NO_BITMAP
;
534 if ( type
& ftc_old_image_flag_unscaled
)
535 load_flags
|= FT_LOAD_NO_SCALE
;
538 /* always render glyphs to bitmaps */
539 load_flags
|= FT_LOAD_RENDER
;
541 if ( type
& ftc_old_image_flag_unhinted
)
542 load_flags
|= FT_LOAD_NO_HINTING
;
544 if ( type
& ftc_old_image_flag_autohinted
)
545 load_flags
|= FT_LOAD_FORCE_AUTOHINT
;
547 typ
->flags
= load_flags
;
552 FT_EXPORT( FT_Error
)
553 FTC_Image_Cache_New( FTC_Manager manager
,
554 FTC_ImageCache
*acache
);
556 FT_EXPORT( FT_Error
)
557 FTC_Image_Cache_Lookup( FTC_ImageCache icache
,
558 FTC_OldImage_Desc
* desc
,
563 FT_EXPORT_DEF( FT_Error
)
564 FTC_Image_Cache_New( FTC_Manager manager
,
565 FTC_ImageCache
*acache
)
567 return FTC_ImageCache_New( manager
, (FTC_ImageCache
*)acache
);
572 FT_EXPORT_DEF( FT_Error
)
573 FTC_Image_Cache_Lookup( FTC_ImageCache icache
,
574 FTC_OldImage_Desc
* desc
,
578 FTC_ImageTypeRec type0
;
582 return FTC_Err_Invalid_Argument
;
584 ftc_image_type_from_old_desc( &type0
, desc
);
586 return FTC_ImageCache_Lookup( (FTC_ImageCache
)icache
,
593 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
598 * basic small bitmap cache
603 FT_CALLBACK_TABLE_DEF
604 const FTC_SFamilyClassRec ftc_basic_sbit_family_class
=
607 sizeof( FTC_BasicFamilyRec
),
608 ftc_basic_family_compare
,
609 ftc_basic_family_init
,
610 0, /* FTC_MruNode_ResetFunc */
611 0 /* FTC_MruNode_DoneFunc */
613 ftc_basic_family_get_count
,
614 ftc_basic_family_load_bitmap
618 FT_CALLBACK_TABLE_DEF
619 const FTC_GCacheClassRec ftc_basic_sbit_cache_class
=
625 ftc_basic_gnode_compare_faceid
,
628 sizeof ( FTC_GCacheRec
),
632 (FTC_MruListClass
)&ftc_basic_sbit_family_class
636 /* documentation is in ftcache.h */
638 FT_EXPORT_DEF( FT_Error
)
639 FTC_SBitCache_New( FTC_Manager manager
,
640 FTC_SBitCache
*acache
)
642 return FTC_GCache_New( manager
, &ftc_basic_sbit_cache_class
,
643 (FTC_GCache
*)acache
);
647 /* documentation is in ftcache.h */
649 FT_EXPORT_DEF( FT_Error
)
650 FTC_SBitCache_Lookup( FTC_SBitCache cache
,
657 FTC_BasicQueryRec query
;
658 FTC_Node node
= 0; /* make compiler happy */
665 /* other argument checks delayed to FTC_Cache_Lookup */
667 return FTC_Err_Invalid_Argument
;
671 #if defined( FT_CONFIG_OPTION_OLD_INTERNALS ) && ( FT_INT_MAX > 0xFFFFU )
673 /* This one is a major hack used to detect whether we are passed a
674 * regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one.
676 if ( (FT_ULong
)type
->width
>= 0x10000L
)
678 FTC_OldImageDesc desc
= (FTC_OldImageDesc
)type
;
681 query
.attrs
.scaler
.face_id
= desc
->font
.face_id
;
682 query
.attrs
.scaler
.width
= desc
->font
.pix_width
;
683 query
.attrs
.scaler
.height
= desc
->font
.pix_height
;
684 query
.attrs
.load_flags
= desc
->flags
;
688 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
691 if ( (FT_ULong
)(type
->flags
- FT_INT_MIN
) > FT_UINT_MAX
)
693 FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" ));
694 FT_TRACE1(( "0x%x are dropped\n", (type
->flags
& ~((FT_ULong
)FT_UINT_MAX
)) ));
697 query
.attrs
.scaler
.face_id
= type
->face_id
;
698 query
.attrs
.scaler
.width
= type
->width
;
699 query
.attrs
.scaler
.height
= type
->height
;
700 query
.attrs
.load_flags
= (FT_UInt
)type
->flags
;
703 query
.attrs
.scaler
.pixel
= 1;
704 query
.attrs
.scaler
.x_res
= 0; /* make compilers happy */
705 query
.attrs
.scaler
.y_res
= 0;
707 /* beware, the hash must be the same for all glyph ranges! */
708 hash
= FTC_BASIC_ATTR_HASH( &query
.attrs
) +
709 gindex
/ FTC_SBIT_ITEMS_PER_NODE
;
711 #if 1 /* inlining is about 50% faster! */
712 FTC_GCACHE_LOOKUP_CMP( cache
,
713 ftc_basic_family_compare
,
720 error
= FTC_GCache_Lookup( FTC_GCACHE( cache
),
723 FTC_GQUERY( &query
),
729 *ansbit
= FTC_SNODE( node
)->sbits
+
730 ( gindex
- FTC_GNODE( node
)->gindex
);
743 /* documentation is in ftcache.h */
745 FT_EXPORT_DEF( FT_Error
)
746 FTC_SBitCache_LookupScaler( FTC_SBitCache cache
,
754 FTC_BasicQueryRec query
;
755 FTC_Node node
= 0; /* make compiler happy */
762 /* other argument checks delayed to FTC_Cache_Lookup */
763 if ( !ansbit
|| !scaler
)
764 return FTC_Err_Invalid_Argument
;
768 /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */
769 if ( load_flags
> FT_UINT_MAX
)
771 FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" ));
772 FT_TRACE1(( "0x%x are dropped\n", (load_flags
& ~((FT_ULong
)FT_UINT_MAX
)) ));
775 query
.attrs
.scaler
= scaler
[0];
776 query
.attrs
.load_flags
= (FT_UInt
)load_flags
;
778 /* beware, the hash must be the same for all glyph ranges! */
779 hash
= FTC_BASIC_ATTR_HASH( &query
.attrs
) +
780 gindex
/ FTC_SBIT_ITEMS_PER_NODE
;
782 FTC_GCACHE_LOOKUP_CMP( cache
,
783 ftc_basic_family_compare
,
792 *ansbit
= FTC_SNODE( node
)->sbits
+
793 ( gindex
- FTC_GNODE( node
)->gindex
);
806 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
808 FT_EXPORT( FT_Error
)
809 FTC_SBit_Cache_New( FTC_Manager manager
,
810 FTC_SBitCache
*acache
);
812 FT_EXPORT( FT_Error
)
813 FTC_SBit_Cache_Lookup( FTC_SBitCache cache
,
814 FTC_OldImage_Desc
* desc
,
819 FT_EXPORT_DEF( FT_Error
)
820 FTC_SBit_Cache_New( FTC_Manager manager
,
821 FTC_SBitCache
*acache
)
823 return FTC_SBitCache_New( manager
, (FTC_SBitCache
*)acache
);
827 FT_EXPORT_DEF( FT_Error
)
828 FTC_SBit_Cache_Lookup( FTC_SBitCache cache
,
829 FTC_OldImage_Desc
* desc
,
833 FTC_ImageTypeRec type0
;
837 return FT_Err_Invalid_Argument
;
839 ftc_image_type_from_old_desc( &type0
, desc
);
841 return FTC_SBitCache_Lookup( (FTC_SBitCache
)cache
,
848 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */