123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399 |
- /***************************************************************************/
- /* */
- /* ftcimage.c */
- /* */
- /* FreeType Image cache (body). */
- /* */
- /* Copyright 2000-2001 by */
- /* David Turner, Robert Wilhelm, and Werner Lemberg. */
- /* */
- /* This file is part of the FreeType project, and may only be used, */
- /* modified, and distributed under the terms of the FreeType project */
- /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
- /* this file you indicate that you have read the license and */
- /* understand and accept it fully. */
- /* */
- /***************************************************************************/
- #include <ft2build.h>
- #include FT_CACHE_H
- #include FT_CACHE_IMAGE_H
- #include FT_CACHE_INTERNAL_GLYPH_H
- #include FT_INTERNAL_MEMORY_H
- #include "ftcerror.h"
- /* the FT_Glyph image node type */
- typedef struct FTC_ImageNodeRec_
- {
- FTC_GlyphNodeRec gnode;
- FT_Glyph glyph;
- } FTC_ImageNodeRec, *FTC_ImageNode;
- #define FTC_IMAGE_NODE( x ) ( (FTC_ImageNode)( x ) )
- #define FTC_IMAGE_NODE_GINDEX( x ) FTC_GLYPH_NODE_GINDEX( x )
- /* the glyph image query */
- typedef struct FTC_ImageQueryRec_
- {
- FTC_GlyphQueryRec gquery;
- FTC_ImageTypeRec type;
- } FTC_ImageQueryRec, *FTC_ImageQuery;
- #define FTC_IMAGE_QUERY( x ) ( (FTC_ImageQuery)( x ) )
- /* the glyph image set type */
- typedef struct FTC_ImageFamilyRec_
- {
- FTC_GlyphFamilyRec gfam;
- FTC_ImageTypeRec type;
- } FTC_ImageFamilyRec, *FTC_ImageFamily;
- #define FTC_IMAGE_FAMILY( x ) ( (FTC_ImageFamily)( x ) )
- #define FTC_IMAGE_FAMILY_MEMORY( x ) FTC_GLYPH_FAMILY_MEMORY( &(x)->gfam )
- /*************************************************************************/
- /*************************************************************************/
- /***** *****/
- /***** GLYPH IMAGE NODES *****/
- /***** *****/
- /*************************************************************************/
- /*************************************************************************/
- /* finalize a given glyph image node */
- FT_CALLBACK_DEF( void )
- ftc_image_node_done( FTC_ImageNode inode,
- FTC_Cache cache )
- {
- if ( inode->glyph )
- {
- FT_Done_Glyph( inode->glyph );
- inode->glyph = NULL;
- }
- ftc_glyph_node_done( FTC_GLYPH_NODE( inode ), cache );
- }
- /* initialize a new glyph image node */
- FT_CALLBACK_DEF( FT_Error )
- ftc_image_node_init( FTC_ImageNode inode,
- FTC_GlyphQuery gquery,
- FTC_Cache cache )
- {
- FTC_ImageFamily ifam = FTC_IMAGE_FAMILY( gquery->query.family );
- FT_Error error;
- FT_Face face;
- FT_Size size;
- /* initialize its inner fields */
- ftc_glyph_node_init( FTC_GLYPH_NODE( inode ),
- gquery->gindex,
- FTC_GLYPH_FAMILY( ifam ) );
- /* we will now load the glyph image */
- error = FTC_Manager_Lookup_Size( FTC_FAMILY( ifam )->cache->manager,
- &ifam->type.font,
- &face, &size );
- if ( !error )
- {
- FT_UInt gindex = FTC_GLYPH_NODE_GINDEX( inode );
- error = FT_Load_Glyph( face, gindex, ifam->type.flags );
- if ( !error )
- {
- if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP ||
- face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
- {
- /* ok, copy it */
- FT_Glyph glyph;
- error = FT_Get_Glyph( face->glyph, &glyph );
- if ( !error )
- {
- inode->glyph = glyph;
- goto Exit;
- }
- }
- else
- error = FTC_Err_Invalid_Argument;
- }
- }
- /* in case of error */
- ftc_glyph_node_done( FTC_GLYPH_NODE(inode), cache );
- Exit:
- return error;
- }
- FT_CALLBACK_DEF( FT_ULong )
- ftc_image_node_weight( FTC_ImageNode inode )
- {
- FT_ULong size = 0;
- FT_Glyph glyph = inode->glyph;
- switch ( glyph->format )
- {
- case FT_GLYPH_FORMAT_BITMAP:
- {
- FT_BitmapGlyph bitg;
- bitg = (FT_BitmapGlyph)glyph;
- size = bitg->bitmap.rows * labs( bitg->bitmap.pitch ) +
- sizeof ( *bitg );
- }
- break;
- case FT_GLYPH_FORMAT_OUTLINE:
- {
- FT_OutlineGlyph outg;
- outg = (FT_OutlineGlyph)glyph;
- size = outg->outline.n_points *
- ( sizeof ( FT_Vector ) + sizeof ( FT_Byte ) ) +
- outg->outline.n_contours * sizeof ( FT_Short ) +
- sizeof ( *outg );
- }
- break;
- default:
- ;
- }
- size += sizeof ( *inode );
- return size;
- }
- /*************************************************************************/
- /*************************************************************************/
- /***** *****/
- /***** GLYPH IMAGE SETS *****/
- /***** *****/
- /*************************************************************************/
- /*************************************************************************/
- FT_CALLBACK_DEF( FT_Error )
- ftc_image_family_init( FTC_ImageFamily ifam,
- FTC_ImageQuery iquery,
- FTC_Cache cache )
- {
- FTC_Manager manager = cache->manager;
- FT_Error error;
- FT_Face face;
- ifam->type = iquery->type;
- /* we need to compute "iquery.item_total" now */
- error = FTC_Manager_Lookup_Face( manager,
- iquery->type.font.face_id,
- &face );
- if ( !error )
- {
- error = ftc_glyph_family_init( FTC_GLYPH_FAMILY( ifam ),
- FTC_IMAGE_TYPE_HASH( &ifam->type ),
- 1,
- face->num_glyphs,
- FTC_GLYPH_QUERY( iquery ),
- cache );
- }
- return error;
- }
- FT_CALLBACK_DEF( FT_Bool )
- ftc_image_family_compare( FTC_ImageFamily ifam,
- FTC_ImageQuery iquery )
- {
- FT_Bool result;
- result = FT_BOOL( FTC_IMAGE_TYPE_COMPARE( &ifam->type, &iquery->type ) );
- if ( result )
- FTC_GLYPH_FAMILY_FOUND( ifam, iquery );
- return result;
- }
- /*************************************************************************/
- /*************************************************************************/
- /***** *****/
- /***** GLYPH IMAGE CACHE *****/
- /***** *****/
- /*************************************************************************/
- /*************************************************************************/
- FT_CALLBACK_TABLE_DEF
- const FTC_Cache_ClassRec ftc_image_cache_class =
- {
- sizeof ( FTC_CacheRec ),
- (FTC_Cache_InitFunc) ftc_cache_init,
- (FTC_Cache_ClearFunc)ftc_cache_clear,
- (FTC_Cache_DoneFunc) ftc_cache_done,
- sizeof ( FTC_ImageFamilyRec ),
- (FTC_Family_InitFunc) ftc_image_family_init,
- (FTC_Family_CompareFunc)ftc_image_family_compare,
- (FTC_Family_DoneFunc) ftc_glyph_family_done,
- sizeof ( FTC_ImageNodeRec ),
- (FTC_Node_InitFunc) ftc_image_node_init,
- (FTC_Node_WeightFunc) ftc_image_node_weight,
- (FTC_Node_CompareFunc)ftc_glyph_node_compare,
- (FTC_Node_DoneFunc) ftc_image_node_done
- };
- /* documentation is in ftcimage.h */
- FT_EXPORT_DEF( FT_Error )
- FTC_ImageCache_New( FTC_Manager manager,
- FTC_ImageCache *acache )
- {
- return FTC_Manager_Register_Cache(
- manager,
- (FTC_Cache_Class)&ftc_image_cache_class,
- FTC_CACHE_P( acache ) );
- }
- /* documentation is in ftcimage.h */
- FT_EXPORT_DEF( FT_Error )
- FTC_ImageCache_Lookup( FTC_ImageCache cache,
- FTC_ImageType type,
- FT_UInt gindex,
- FT_Glyph *aglyph,
- FTC_Node *anode )
- {
- FTC_ImageQueryRec iquery;
- FTC_ImageNode node;
- FT_Error error;
- /* some argument checks are delayed to ftc_cache_lookup */
- if ( !aglyph )
- return FTC_Err_Invalid_Argument;
- if ( anode )
- *anode = NULL;
- iquery.gquery.gindex = gindex;
- iquery.type = *type;
- error = ftc_cache_lookup( FTC_CACHE( cache ),
- FTC_QUERY( &iquery ),
- (FTC_Node*)&node );
- if ( !error )
- {
- *aglyph = node->glyph;
- if ( anode )
- {
- *anode = (FTC_Node)node;
- FTC_NODE( node )->ref_count++;
- }
- }
- return error;
- }
- /* backwards-compatibility functions */
- FT_EXPORT_DEF( FT_Error )
- FTC_Image_Cache_New( FTC_Manager manager,
- FTC_Image_Cache *acache )
- {
- return FTC_ImageCache_New( manager, (FTC_ImageCache*)acache );
- }
- FT_EXPORT_DEF( FT_Error )
- FTC_Image_Cache_Lookup( FTC_Image_Cache icache,
- FTC_Image_Desc* desc,
- FT_UInt gindex,
- FT_Glyph *aglyph )
- {
- FTC_ImageTypeRec type0;
- if ( !desc )
- return FTC_Err_Invalid_Argument;
- type0.font = desc->font;
- /* convert image type flags to load flags */
- {
- FT_UInt load_flags = FT_LOAD_DEFAULT;
- FT_UInt type = desc->image_type;
- /* determine load flags, depending on the font description's */
- /* image type */
- if ( ftc_image_format( type ) == ftc_image_format_bitmap )
- {
- if ( type & ftc_image_flag_monochrome )
- load_flags |= FT_LOAD_MONOCHROME;
- /* disable embedded bitmaps loading if necessary */
- if ( type & ftc_image_flag_no_sbits )
- load_flags |= FT_LOAD_NO_BITMAP;
- }
- else
- {
- /* we want an outline, don't load embedded bitmaps */
- load_flags |= FT_LOAD_NO_BITMAP;
- if ( type & ftc_image_flag_unscaled )
- load_flags |= FT_LOAD_NO_SCALE;
- }
- /* always render glyphs to bitmaps */
- load_flags |= FT_LOAD_RENDER;
- if ( type & ftc_image_flag_unhinted )
- load_flags |= FT_LOAD_NO_HINTING;
- if ( type & ftc_image_flag_autohinted )
- load_flags |= FT_LOAD_FORCE_AUTOHINT;
- type0.flags = load_flags;
- }
- return FTC_ImageCache_Lookup( (FTC_ImageCache)icache,
- &type0,
- gindex,
- aglyph,
- NULL );
- }
- /* END */
|