1 /***************************************************************************/
5 /* FreeType Image cache (body). */
7 /* Copyright 2000-2001 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 /***************************************************************************/
21 #include FT_CACHE_IMAGE_H
22 #include FT_CACHE_INTERNAL_GLYPH_H
23 #include FT_INTERNAL_MEMORY_H
28 /* the FT_Glyph image node type */
29 typedef struct FTC_ImageNodeRec_
31 FTC_GlyphNodeRec gnode;
34 } FTC_ImageNodeRec, *FTC_ImageNode;
37 #define FTC_IMAGE_NODE( x ) ( (FTC_ImageNode)( x ) )
38 #define FTC_IMAGE_NODE_GINDEX( x ) FTC_GLYPH_NODE_GINDEX( x )
41 /* the glyph image query */
42 typedef struct FTC_ImageQueryRec_
44 FTC_GlyphQueryRec gquery;
45 FTC_ImageTypeRec type;
47 } FTC_ImageQueryRec, *FTC_ImageQuery;
50 #define FTC_IMAGE_QUERY( x ) ( (FTC_ImageQuery)( x ) )
53 /* the glyph image set type */
54 typedef struct FTC_ImageFamilyRec_
56 FTC_GlyphFamilyRec gfam;
57 FTC_ImageTypeRec type;
59 } FTC_ImageFamilyRec, *FTC_ImageFamily;
62 #define FTC_IMAGE_FAMILY( x ) ( (FTC_ImageFamily)( x ) )
63 #define FTC_IMAGE_FAMILY_MEMORY( x ) FTC_GLYPH_FAMILY_MEMORY( &(x)->gfam )
66 /*************************************************************************/
67 /*************************************************************************/
69 /***** GLYPH IMAGE NODES *****/
71 /*************************************************************************/
72 /*************************************************************************/
75 /* finalize a given glyph image node */
76 FT_CALLBACK_DEF( void )
77 ftc_image_node_done( FTC_ImageNode inode,
82 FT_Done_Glyph( inode->glyph );
86 ftc_glyph_node_done( FTC_GLYPH_NODE( inode ), cache );
90 /* initialize a new glyph image node */
91 FT_CALLBACK_DEF( FT_Error )
92 ftc_image_node_init( FTC_ImageNode inode,
93 FTC_GlyphQuery gquery,
96 FTC_ImageFamily ifam = FTC_IMAGE_FAMILY( gquery->query.family );
102 /* initialize its inner fields */
103 ftc_glyph_node_init( FTC_GLYPH_NODE( inode ),
105 FTC_GLYPH_FAMILY( ifam ) );
107 /* we will now load the glyph image */
108 error = FTC_Manager_Lookup_Size( FTC_FAMILY( ifam )->cache->manager,
113 FT_UInt gindex = FTC_GLYPH_NODE_GINDEX( inode );
116 error = FT_Load_Glyph( face, gindex, ifam->type.flags );
119 if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP ||
120 face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
126 error = FT_Get_Glyph( face->glyph, &glyph );
129 inode->glyph = glyph;
134 error = FTC_Err_Invalid_Argument;
138 /* in case of error */
139 ftc_glyph_node_done( FTC_GLYPH_NODE(inode), cache );
146 FT_CALLBACK_DEF( FT_ULong )
147 ftc_image_node_weight( FTC_ImageNode inode )
150 FT_Glyph glyph = inode->glyph;
153 switch ( glyph->format )
155 case FT_GLYPH_FORMAT_BITMAP:
160 bitg = (FT_BitmapGlyph)glyph;
161 size = bitg->bitmap.rows * labs( bitg->bitmap.pitch ) +
166 case FT_GLYPH_FORMAT_OUTLINE:
168 FT_OutlineGlyph outg;
171 outg = (FT_OutlineGlyph)glyph;
172 size = outg->outline.n_points *
173 ( sizeof ( FT_Vector ) + sizeof ( FT_Byte ) ) +
174 outg->outline.n_contours * sizeof ( FT_Short ) +
183 size += sizeof ( *inode );
188 /*************************************************************************/
189 /*************************************************************************/
191 /***** GLYPH IMAGE SETS *****/
193 /*************************************************************************/
194 /*************************************************************************/
197 FT_CALLBACK_DEF( FT_Error )
198 ftc_image_family_init( FTC_ImageFamily ifam,
199 FTC_ImageQuery iquery,
202 FTC_Manager manager = cache->manager;
207 ifam->type = iquery->type;
209 /* we need to compute "iquery.item_total" now */
210 error = FTC_Manager_Lookup_Face( manager,
211 iquery->type.font.face_id,
215 error = ftc_glyph_family_init( FTC_GLYPH_FAMILY( ifam ),
216 FTC_IMAGE_TYPE_HASH( &ifam->type ),
219 FTC_GLYPH_QUERY( iquery ),
227 FT_CALLBACK_DEF( FT_Bool )
228 ftc_image_family_compare( FTC_ImageFamily ifam,
229 FTC_ImageQuery iquery )
234 result = FT_BOOL( FTC_IMAGE_TYPE_COMPARE( &ifam->type, &iquery->type ) );
236 FTC_GLYPH_FAMILY_FOUND( ifam, iquery );
242 /*************************************************************************/
243 /*************************************************************************/
245 /***** GLYPH IMAGE CACHE *****/
247 /*************************************************************************/
248 /*************************************************************************/
252 FT_CALLBACK_TABLE_DEF
253 const FTC_Cache_ClassRec ftc_image_cache_class =
255 sizeof ( FTC_CacheRec ),
256 (FTC_Cache_InitFunc) ftc_cache_init,
257 (FTC_Cache_ClearFunc)ftc_cache_clear,
258 (FTC_Cache_DoneFunc) ftc_cache_done,
260 sizeof ( FTC_ImageFamilyRec ),
261 (FTC_Family_InitFunc) ftc_image_family_init,
262 (FTC_Family_CompareFunc)ftc_image_family_compare,
263 (FTC_Family_DoneFunc) ftc_glyph_family_done,
265 sizeof ( FTC_ImageNodeRec ),
266 (FTC_Node_InitFunc) ftc_image_node_init,
267 (FTC_Node_WeightFunc) ftc_image_node_weight,
268 (FTC_Node_CompareFunc)ftc_glyph_node_compare,
269 (FTC_Node_DoneFunc) ftc_image_node_done
273 /* documentation is in ftcimage.h */
275 FT_EXPORT_DEF( FT_Error )
276 FTC_ImageCache_New( FTC_Manager manager,
277 FTC_ImageCache *acache )
279 return FTC_Manager_Register_Cache(
281 (FTC_Cache_Class)&ftc_image_cache_class,
282 FTC_CACHE_P( acache ) );
286 /* documentation is in ftcimage.h */
288 FT_EXPORT_DEF( FT_Error )
289 FTC_ImageCache_Lookup( FTC_ImageCache cache,
295 FTC_ImageQueryRec iquery;
300 /* some argument checks are delayed to ftc_cache_lookup */
302 return FTC_Err_Invalid_Argument;
307 iquery.gquery.gindex = gindex;
310 error = ftc_cache_lookup( FTC_CACHE( cache ),
311 FTC_QUERY( &iquery ),
315 *aglyph = node->glyph;
319 *anode = (FTC_Node)node;
320 FTC_NODE( node )->ref_count++;
328 /* backwards-compatibility functions */
330 FT_EXPORT_DEF( FT_Error )
331 FTC_Image_Cache_New( FTC_Manager manager,
332 FTC_Image_Cache *acache )
334 return FTC_ImageCache_New( manager, (FTC_ImageCache*)acache );
338 FT_EXPORT_DEF( FT_Error )
339 FTC_Image_Cache_Lookup( FTC_Image_Cache icache,
340 FTC_Image_Desc* desc,
344 FTC_ImageTypeRec type0;
348 return FTC_Err_Invalid_Argument;
350 type0.font = desc->font;
352 /* convert image type flags to load flags */
354 FT_UInt load_flags = FT_LOAD_DEFAULT;
355 FT_UInt type = desc->image_type;
358 /* determine load flags, depending on the font description's */
361 if ( ftc_image_format( type ) == ftc_image_format_bitmap )
363 if ( type & ftc_image_flag_monochrome )
364 load_flags |= FT_LOAD_MONOCHROME;
366 /* disable embedded bitmaps loading if necessary */
367 if ( type & ftc_image_flag_no_sbits )
368 load_flags |= FT_LOAD_NO_BITMAP;
372 /* we want an outline, don't load embedded bitmaps */
373 load_flags |= FT_LOAD_NO_BITMAP;
375 if ( type & ftc_image_flag_unscaled )
376 load_flags |= FT_LOAD_NO_SCALE;
379 /* always render glyphs to bitmaps */
380 load_flags |= FT_LOAD_RENDER;
382 if ( type & ftc_image_flag_unhinted )
383 load_flags |= FT_LOAD_NO_HINTING;
385 if ( type & ftc_image_flag_autohinted )
386 load_flags |= FT_LOAD_FORCE_AUTOHINT;
388 type0.flags = load_flags;
391 return FTC_ImageCache_Lookup( (FTC_ImageCache)icache,