1 /***************************************************************************/
5 /* The FreeType basic cache interface (body). */
7 /* Copyright 2003, 2004, 2005, 2006, 2007 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 /***************************************************************************/
24 #include FT_INTERNAL_MEMORY_H
30 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
33 * These structures correspond to the FTC_Font and FTC_ImageDesc types
34 * that were defined in version 2.1.7.
36 typedef struct FTC_OldFontRec_
42 } FTC_OldFontRec
, *FTC_OldFont
;
45 typedef struct FTC_OldImageDescRec_
50 } FTC_OldImageDescRec
, *FTC_OldImageDesc
;
54 * Notice that FTC_OldImageDescRec and FTC_ImageTypeRec are nearly
55 * identical, bit-wise. The only difference is that the `width' and
56 * `height' fields are expressed as 16-bit integers in the old structure,
57 * and as normal `int' in the new one.
59 * We are going to perform a weird hack to detect which structure is
60 * being passed to the image and sbit caches. If the new structure's
61 * `width' is larger than 0x10000, we assume that we are really receiving
62 * an FTC_OldImageDesc.
65 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
72 typedef struct FTC_BasicAttrRec_
77 } FTC_BasicAttrRec
, *FTC_BasicAttrs
;
79 #define FTC_BASIC_ATTR_COMPARE( a, b ) \
80 FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \
81 (a)->load_flags == (b)->load_flags )
83 #define FTC_BASIC_ATTR_HASH( a ) \
84 ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags )
87 typedef struct FTC_BasicQueryRec_
90 FTC_BasicAttrRec attrs
;
92 } FTC_BasicQueryRec
, *FTC_BasicQuery
;
95 typedef struct FTC_BasicFamilyRec_
98 FTC_BasicAttrRec attrs
;
100 } FTC_BasicFamilyRec
, *FTC_BasicFamily
;
103 FT_CALLBACK_DEF( FT_Bool
)
104 ftc_basic_family_compare( FTC_MruNode ftcfamily
,
105 FT_Pointer ftcquery
)
107 FTC_BasicFamily family
= (FTC_BasicFamily
)ftcfamily
;
108 FTC_BasicQuery query
= (FTC_BasicQuery
)ftcquery
;
111 return FTC_BASIC_ATTR_COMPARE( &family
->attrs
, &query
->attrs
);
115 FT_CALLBACK_DEF( FT_Error
)
116 ftc_basic_family_init( FTC_MruNode ftcfamily
,
118 FT_Pointer ftccache
)
120 FTC_BasicFamily family
= (FTC_BasicFamily
)ftcfamily
;
121 FTC_BasicQuery query
= (FTC_BasicQuery
)ftcquery
;
122 FTC_Cache cache
= (FTC_Cache
)ftccache
;
125 FTC_Family_Init( FTC_FAMILY( family
), cache
);
126 family
->attrs
= query
->attrs
;
131 FT_CALLBACK_DEF( FT_UInt
)
132 ftc_basic_family_get_count( FTC_Family ftcfamily
,
133 FTC_Manager manager
)
135 FTC_BasicFamily family
= (FTC_BasicFamily
)ftcfamily
;
141 error
= FTC_Manager_LookupFace( manager
, family
->attrs
.scaler
.face_id
,
144 result
= face
->num_glyphs
;
150 FT_CALLBACK_DEF( FT_Error
)
151 ftc_basic_family_load_bitmap( FTC_Family ftcfamily
,
156 FTC_BasicFamily family
= (FTC_BasicFamily
)ftcfamily
;
161 error
= FTC_Manager_LookupSize( manager
, &family
->attrs
.scaler
, &size
);
164 FT_Face face
= size
->face
;
167 error
= FT_Load_Glyph( face
, gindex
,
168 family
->attrs
.load_flags
| FT_LOAD_RENDER
);
177 FT_CALLBACK_DEF( FT_Error
)
178 ftc_basic_family_load_glyph( FTC_Family ftcfamily
,
183 FTC_BasicFamily family
= (FTC_BasicFamily
)ftcfamily
;
185 FTC_Scaler scaler
= &family
->attrs
.scaler
;
190 /* we will now load the glyph image */
191 error
= FTC_Manager_LookupSize( cache
->manager
,
198 error
= FT_Load_Glyph( face
, gindex
, family
->attrs
.load_flags
);
201 if ( face
->glyph
->format
== FT_GLYPH_FORMAT_BITMAP
||
202 face
->glyph
->format
== FT_GLYPH_FORMAT_OUTLINE
)
208 error
= FT_Get_Glyph( face
->glyph
, &glyph
);
216 error
= FTC_Err_Invalid_Argument
;
225 FT_CALLBACK_DEF( FT_Bool
)
226 ftc_basic_gnode_compare_faceid( FTC_Node ftcgnode
,
227 FT_Pointer ftcface_id
,
230 FTC_GNode gnode
= (FTC_GNode
)ftcgnode
;
231 FTC_FaceID face_id
= (FTC_FaceID
)ftcface_id
;
232 FTC_BasicFamily family
= (FTC_BasicFamily
)gnode
->family
;
236 result
= FT_BOOL( family
->attrs
.scaler
.face_id
== face_id
);
239 /* we must call this function to avoid this node from appearing
240 * in later lookups with the same face_id!
242 FTC_GNode_UnselectFamily( gnode
, cache
);
254 FT_CALLBACK_TABLE_DEF
255 const FTC_IFamilyClassRec ftc_basic_image_family_class
=
258 sizeof ( FTC_BasicFamilyRec
),
259 ftc_basic_family_compare
,
260 ftc_basic_family_init
,
261 0, /* FTC_MruNode_ResetFunc */
262 0 /* FTC_MruNode_DoneFunc */
264 ftc_basic_family_load_glyph
268 FT_CALLBACK_TABLE_DEF
269 const FTC_GCacheClassRec ftc_basic_image_cache_class
=
275 ftc_basic_gnode_compare_faceid
,
278 sizeof ( FTC_GCacheRec
),
282 (FTC_MruListClass
)&ftc_basic_image_family_class
286 /* documentation is in ftcache.h */
288 FT_EXPORT_DEF( FT_Error
)
289 FTC_ImageCache_New( FTC_Manager manager
,
290 FTC_ImageCache
*acache
)
292 return FTC_GCache_New( manager
, &ftc_basic_image_cache_class
,
293 (FTC_GCache
*)acache
);
297 /* documentation is in ftcache.h */
299 FT_EXPORT_DEF( FT_Error
)
300 FTC_ImageCache_Lookup( FTC_ImageCache cache
,
306 FTC_BasicQueryRec query
;
307 FTC_INode node
= 0; /* make compiler happy */
312 /* some argument checks are delayed to FTC_Cache_Lookup */
315 error
= FTC_Err_Invalid_Argument
;
323 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
326 * This one is a major hack used to detect whether we are passed a
327 * regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one.
329 if ( type
->width
>= 0x10000 )
331 FTC_OldImageDesc desc
= (FTC_OldImageDesc
)type
;
334 query
.attrs
.scaler
.face_id
= desc
->font
.face_id
;
335 query
.attrs
.scaler
.width
= desc
->font
.pix_width
;
336 query
.attrs
.scaler
.height
= desc
->font
.pix_height
;
337 query
.attrs
.load_flags
= desc
->flags
;
341 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
344 query
.attrs
.scaler
.face_id
= type
->face_id
;
345 query
.attrs
.scaler
.width
= type
->width
;
346 query
.attrs
.scaler
.height
= type
->height
;
347 query
.attrs
.load_flags
= type
->flags
;
350 query
.attrs
.scaler
.pixel
= 1;
351 query
.attrs
.scaler
.x_res
= 0; /* make compilers happy */
352 query
.attrs
.scaler
.y_res
= 0;
354 hash
= FTC_BASIC_ATTR_HASH( &query
.attrs
) + gindex
;
356 #if 1 /* inlining is about 50% faster! */
357 FTC_GCACHE_LOOKUP_CMP( cache
,
358 ftc_basic_family_compare
,
365 error
= FTC_GCache_Lookup( FTC_GCACHE( cache
),
367 FTC_GQUERY( &query
),
372 *aglyph
= FTC_INODE( node
)->glyph
;
376 *anode
= FTC_NODE( node
);
377 FTC_NODE( node
)->ref_count
++;
386 /* documentation is in ftcache.h */
388 FT_EXPORT_DEF( FT_Error
)
389 FTC_ImageCache_LookupScaler( FTC_ImageCache cache
,
396 FTC_BasicQueryRec query
;
397 FTC_INode node
= 0; /* make compiler happy */
402 /* some argument checks are delayed to FTC_Cache_Lookup */
403 if ( !aglyph
|| !scaler
)
405 error
= FTC_Err_Invalid_Argument
;
413 query
.attrs
.scaler
= scaler
[0];
414 query
.attrs
.load_flags
= load_flags
;
416 hash
= FTC_BASIC_ATTR_HASH( &query
.attrs
) + gindex
;
418 FTC_GCACHE_LOOKUP_CMP( cache
,
419 ftc_basic_family_compare
,
427 *aglyph
= FTC_INODE( node
)->glyph
;
431 *anode
= FTC_NODE( node
);
432 FTC_NODE( node
)->ref_count
++;
442 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
444 /* yet another backwards-legacy structure */
445 typedef struct FTC_OldImage_Desc_
453 #define FTC_OLD_IMAGE_FORMAT( x ) ( (x) & 7 )
456 #define ftc_old_image_format_bitmap 0x0000
457 #define ftc_old_image_format_outline 0x0001
459 #define ftc_old_image_format_mask 0x000F
461 #define ftc_old_image_flag_monochrome 0x0010
462 #define ftc_old_image_flag_unhinted 0x0020
463 #define ftc_old_image_flag_autohinted 0x0040
464 #define ftc_old_image_flag_unscaled 0x0080
465 #define ftc_old_image_flag_no_sbits 0x0100
467 /* monochrome bitmap */
468 #define ftc_old_image_mono ftc_old_image_format_bitmap | \
469 ftc_old_image_flag_monochrome
471 /* anti-aliased bitmap */
472 #define ftc_old_image_grays ftc_old_image_format_bitmap
475 #define ftc_old_image_outline ftc_old_image_format_outline
479 ftc_image_type_from_old_desc( FTC_ImageType typ
,
480 FTC_OldImage_Desc
* desc
)
482 typ
->face_id
= desc
->font
.face_id
;
483 typ
->width
= desc
->font
.pix_width
;
484 typ
->height
= desc
->font
.pix_height
;
486 /* convert image type flags to load flags */
488 FT_UInt load_flags
= FT_LOAD_DEFAULT
;
489 FT_UInt type
= desc
->image_type
;
492 /* determine load flags, depending on the font description's */
495 if ( FTC_OLD_IMAGE_FORMAT( type
) == ftc_old_image_format_bitmap
)
497 if ( type
& ftc_old_image_flag_monochrome
)
498 load_flags
|= FT_LOAD_MONOCHROME
;
500 /* disable embedded bitmaps loading if necessary */
501 if ( type
& ftc_old_image_flag_no_sbits
)
502 load_flags
|= FT_LOAD_NO_BITMAP
;
506 /* we want an outline, don't load embedded bitmaps */
507 load_flags
|= FT_LOAD_NO_BITMAP
;
509 if ( type
& ftc_old_image_flag_unscaled
)
510 load_flags
|= FT_LOAD_NO_SCALE
;
513 /* always render glyphs to bitmaps */
514 load_flags
|= FT_LOAD_RENDER
;
516 if ( type
& ftc_old_image_flag_unhinted
)
517 load_flags
|= FT_LOAD_NO_HINTING
;
519 if ( type
& ftc_old_image_flag_autohinted
)
520 load_flags
|= FT_LOAD_FORCE_AUTOHINT
;
522 typ
->flags
= load_flags
;
527 FT_EXPORT( FT_Error
)
528 FTC_Image_Cache_New( FTC_Manager manager
,
529 FTC_ImageCache
*acache
);
531 FT_EXPORT( FT_Error
)
532 FTC_Image_Cache_Lookup( FTC_ImageCache icache
,
533 FTC_OldImage_Desc
* desc
,
538 FT_EXPORT_DEF( FT_Error
)
539 FTC_Image_Cache_New( FTC_Manager manager
,
540 FTC_ImageCache
*acache
)
542 return FTC_ImageCache_New( manager
, (FTC_ImageCache
*)acache
);
547 FT_EXPORT_DEF( FT_Error
)
548 FTC_Image_Cache_Lookup( FTC_ImageCache icache
,
549 FTC_OldImage_Desc
* desc
,
553 FTC_ImageTypeRec type0
;
557 return FTC_Err_Invalid_Argument
;
559 ftc_image_type_from_old_desc( &type0
, desc
);
561 return FTC_ImageCache_Lookup( (FTC_ImageCache
)icache
,
568 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
573 * basic small bitmap cache
578 FT_CALLBACK_TABLE_DEF
579 const FTC_SFamilyClassRec ftc_basic_sbit_family_class
=
582 sizeof( FTC_BasicFamilyRec
),
583 ftc_basic_family_compare
,
584 ftc_basic_family_init
,
585 0, /* FTC_MruNode_ResetFunc */
586 0 /* FTC_MruNode_DoneFunc */
588 ftc_basic_family_get_count
,
589 ftc_basic_family_load_bitmap
593 FT_CALLBACK_TABLE_DEF
594 const FTC_GCacheClassRec ftc_basic_sbit_cache_class
=
600 ftc_basic_gnode_compare_faceid
,
603 sizeof ( FTC_GCacheRec
),
607 (FTC_MruListClass
)&ftc_basic_sbit_family_class
611 /* documentation is in ftcache.h */
613 FT_EXPORT_DEF( FT_Error
)
614 FTC_SBitCache_New( FTC_Manager manager
,
615 FTC_SBitCache
*acache
)
617 return FTC_GCache_New( manager
, &ftc_basic_sbit_cache_class
,
618 (FTC_GCache
*)acache
);
622 /* documentation is in ftcache.h */
624 FT_EXPORT_DEF( FT_Error
)
625 FTC_SBitCache_Lookup( FTC_SBitCache cache
,
632 FTC_BasicQueryRec query
;
633 FTC_SNode node
= 0; /* make compiler happy */
640 /* other argument checks delayed to FTC_Cache_Lookup */
642 return FTC_Err_Invalid_Argument
;
646 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
648 /* This one is a major hack used to detect whether we are passed a
649 * regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one.
651 if ( type
->width
>= 0x10000 )
653 FTC_OldImageDesc desc
= (FTC_OldImageDesc
)type
;
656 query
.attrs
.scaler
.face_id
= desc
->font
.face_id
;
657 query
.attrs
.scaler
.width
= desc
->font
.pix_width
;
658 query
.attrs
.scaler
.height
= desc
->font
.pix_height
;
659 query
.attrs
.load_flags
= desc
->flags
;
663 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
666 query
.attrs
.scaler
.face_id
= type
->face_id
;
667 query
.attrs
.scaler
.width
= type
->width
;
668 query
.attrs
.scaler
.height
= type
->height
;
669 query
.attrs
.load_flags
= type
->flags
;
672 query
.attrs
.scaler
.pixel
= 1;
673 query
.attrs
.scaler
.x_res
= 0; /* make compilers happy */
674 query
.attrs
.scaler
.y_res
= 0;
676 /* beware, the hash must be the same for all glyph ranges! */
677 hash
= FTC_BASIC_ATTR_HASH( &query
.attrs
) +
678 gindex
/ FTC_SBIT_ITEMS_PER_NODE
;
680 #if 1 /* inlining is about 50% faster! */
681 FTC_GCACHE_LOOKUP_CMP( cache
,
682 ftc_basic_family_compare
,
689 error
= FTC_GCache_Lookup( FTC_GCACHE( cache
),
692 FTC_GQUERY( &query
),
698 *ansbit
= node
->sbits
+ ( gindex
- FTC_GNODE( node
)->gindex
);
702 *anode
= FTC_NODE( node
);
703 FTC_NODE( node
)->ref_count
++;
711 /* documentation is in ftcache.h */
713 FT_EXPORT_DEF( FT_Error
)
714 FTC_SBitCache_LookupScaler( FTC_SBitCache cache
,
722 FTC_BasicQueryRec query
;
723 FTC_SNode node
= 0; /* make compiler happy */
730 /* other argument checks delayed to FTC_Cache_Lookup */
731 if ( !ansbit
|| !scaler
)
732 return FTC_Err_Invalid_Argument
;
736 query
.attrs
.scaler
= scaler
[0];
737 query
.attrs
.load_flags
= load_flags
;
739 /* beware, the hash must be the same for all glyph ranges! */
740 hash
= FTC_BASIC_ATTR_HASH( &query
.attrs
) +
741 gindex
/ FTC_SBIT_ITEMS_PER_NODE
;
743 FTC_GCACHE_LOOKUP_CMP( cache
,
744 ftc_basic_family_compare
,
753 *ansbit
= node
->sbits
+ ( gindex
- FTC_GNODE( node
)->gindex
);
757 *anode
= FTC_NODE( node
);
758 FTC_NODE( node
)->ref_count
++;
766 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
768 FT_EXPORT( FT_Error
)
769 FTC_SBit_Cache_New( FTC_Manager manager
,
770 FTC_SBitCache
*acache
);
772 FT_EXPORT( FT_Error
)
773 FTC_SBit_Cache_Lookup( FTC_SBitCache cache
,
774 FTC_OldImage_Desc
* desc
,
779 FT_EXPORT_DEF( FT_Error
)
780 FTC_SBit_Cache_New( FTC_Manager manager
,
781 FTC_SBitCache
*acache
)
783 return FTC_SBitCache_New( manager
, (FTC_SBitCache
*)acache
);
787 FT_EXPORT_DEF( FT_Error
)
788 FTC_SBit_Cache_Lookup( FTC_SBitCache cache
,
789 FTC_OldImage_Desc
* desc
,
793 FTC_ImageTypeRec type0
;
797 return FT_Err_Invalid_Argument
;
799 ftc_image_type_from_old_desc( &type0
, desc
);
801 return FTC_SBitCache_Lookup( (FTC_SBitCache
)cache
,
808 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */