ftcimage.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /***************************************************************************/
  2. /* */
  3. /* ftcimage.c */
  4. /* */
  5. /* FreeType Image cache (body). */
  6. /* */
  7. /* Copyright 2000-2001 by */
  8. /* David Turner, Robert Wilhelm, and Werner Lemberg. */
  9. /* */
  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. */
  15. /* */
  16. /***************************************************************************/
  17. #include <ft2build.h>
  18. #include FT_CACHE_H
  19. #include FT_CACHE_IMAGE_H
  20. #include FT_CACHE_INTERNAL_GLYPH_H
  21. #include FT_INTERNAL_MEMORY_H
  22. #include "ftcerror.h"
  23. /* the FT_Glyph image node type */
  24. typedef struct FTC_ImageNodeRec_
  25. {
  26. FTC_GlyphNodeRec gnode;
  27. FT_Glyph glyph;
  28. } FTC_ImageNodeRec, *FTC_ImageNode;
  29. #define FTC_IMAGE_NODE( x ) ( (FTC_ImageNode)( x ) )
  30. #define FTC_IMAGE_NODE_GINDEX( x ) FTC_GLYPH_NODE_GINDEX( x )
  31. /* the glyph image query */
  32. typedef struct FTC_ImageQueryRec_
  33. {
  34. FTC_GlyphQueryRec gquery;
  35. FTC_ImageTypeRec type;
  36. } FTC_ImageQueryRec, *FTC_ImageQuery;
  37. #define FTC_IMAGE_QUERY( x ) ( (FTC_ImageQuery)( x ) )
  38. /* the glyph image set type */
  39. typedef struct FTC_ImageFamilyRec_
  40. {
  41. FTC_GlyphFamilyRec gfam;
  42. FTC_ImageTypeRec type;
  43. } FTC_ImageFamilyRec, *FTC_ImageFamily;
  44. #define FTC_IMAGE_FAMILY( x ) ( (FTC_ImageFamily)( x ) )
  45. #define FTC_IMAGE_FAMILY_MEMORY( x ) FTC_GLYPH_FAMILY_MEMORY( &(x)->gfam )
  46. /*************************************************************************/
  47. /*************************************************************************/
  48. /***** *****/
  49. /***** GLYPH IMAGE NODES *****/
  50. /***** *****/
  51. /*************************************************************************/
  52. /*************************************************************************/
  53. /* finalize a given glyph image node */
  54. FT_CALLBACK_DEF( void )
  55. ftc_image_node_done( FTC_ImageNode inode,
  56. FTC_Cache cache )
  57. {
  58. if ( inode->glyph )
  59. {
  60. FT_Done_Glyph( inode->glyph );
  61. inode->glyph = NULL;
  62. }
  63. ftc_glyph_node_done( FTC_GLYPH_NODE( inode ), cache );
  64. }
  65. /* initialize a new glyph image node */
  66. FT_CALLBACK_DEF( FT_Error )
  67. ftc_image_node_init( FTC_ImageNode inode,
  68. FTC_GlyphQuery gquery,
  69. FTC_Cache cache )
  70. {
  71. FTC_ImageFamily ifam = FTC_IMAGE_FAMILY( gquery->query.family );
  72. FT_Error error;
  73. FT_Face face;
  74. FT_Size size;
  75. /* initialize its inner fields */
  76. ftc_glyph_node_init( FTC_GLYPH_NODE( inode ),
  77. gquery->gindex,
  78. FTC_GLYPH_FAMILY( ifam ) );
  79. /* we will now load the glyph image */
  80. error = FTC_Manager_Lookup_Size( FTC_FAMILY( ifam )->cache->manager,
  81. &ifam->type.font,
  82. &face, &size );
  83. if ( !error )
  84. {
  85. FT_UInt gindex = FTC_GLYPH_NODE_GINDEX( inode );
  86. error = FT_Load_Glyph( face, gindex, ifam->type.flags );
  87. if ( !error )
  88. {
  89. if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP ||
  90. face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
  91. {
  92. /* ok, copy it */
  93. FT_Glyph glyph;
  94. error = FT_Get_Glyph( face->glyph, &glyph );
  95. if ( !error )
  96. {
  97. inode->glyph = glyph;
  98. goto Exit;
  99. }
  100. }
  101. else
  102. error = FTC_Err_Invalid_Argument;
  103. }
  104. }
  105. /* in case of error */
  106. ftc_glyph_node_done( FTC_GLYPH_NODE(inode), cache );
  107. Exit:
  108. return error;
  109. }
  110. FT_CALLBACK_DEF( FT_ULong )
  111. ftc_image_node_weight( FTC_ImageNode inode )
  112. {
  113. FT_ULong size = 0;
  114. FT_Glyph glyph = inode->glyph;
  115. switch ( glyph->format )
  116. {
  117. case FT_GLYPH_FORMAT_BITMAP:
  118. {
  119. FT_BitmapGlyph bitg;
  120. bitg = (FT_BitmapGlyph)glyph;
  121. size = bitg->bitmap.rows * labs( bitg->bitmap.pitch ) +
  122. sizeof ( *bitg );
  123. }
  124. break;
  125. case FT_GLYPH_FORMAT_OUTLINE:
  126. {
  127. FT_OutlineGlyph outg;
  128. outg = (FT_OutlineGlyph)glyph;
  129. size = outg->outline.n_points *
  130. ( sizeof ( FT_Vector ) + sizeof ( FT_Byte ) ) +
  131. outg->outline.n_contours * sizeof ( FT_Short ) +
  132. sizeof ( *outg );
  133. }
  134. break;
  135. default:
  136. ;
  137. }
  138. size += sizeof ( *inode );
  139. return size;
  140. }
  141. /*************************************************************************/
  142. /*************************************************************************/
  143. /***** *****/
  144. /***** GLYPH IMAGE SETS *****/
  145. /***** *****/
  146. /*************************************************************************/
  147. /*************************************************************************/
  148. FT_CALLBACK_DEF( FT_Error )
  149. ftc_image_family_init( FTC_ImageFamily ifam,
  150. FTC_ImageQuery iquery,
  151. FTC_Cache cache )
  152. {
  153. FTC_Manager manager = cache->manager;
  154. FT_Error error;
  155. FT_Face face;
  156. ifam->type = iquery->type;
  157. /* we need to compute "iquery.item_total" now */
  158. error = FTC_Manager_Lookup_Face( manager,
  159. iquery->type.font.face_id,
  160. &face );
  161. if ( !error )
  162. {
  163. error = ftc_glyph_family_init( FTC_GLYPH_FAMILY( ifam ),
  164. FTC_IMAGE_TYPE_HASH( &ifam->type ),
  165. 1,
  166. face->num_glyphs,
  167. FTC_GLYPH_QUERY( iquery ),
  168. cache );
  169. }
  170. return error;
  171. }
  172. FT_CALLBACK_DEF( FT_Bool )
  173. ftc_image_family_compare( FTC_ImageFamily ifam,
  174. FTC_ImageQuery iquery )
  175. {
  176. FT_Bool result;
  177. result = FT_BOOL( FTC_IMAGE_TYPE_COMPARE( &ifam->type, &iquery->type ) );
  178. if ( result )
  179. FTC_GLYPH_FAMILY_FOUND( ifam, iquery );
  180. return result;
  181. }
  182. /*************************************************************************/
  183. /*************************************************************************/
  184. /***** *****/
  185. /***** GLYPH IMAGE CACHE *****/
  186. /***** *****/
  187. /*************************************************************************/
  188. /*************************************************************************/
  189. FT_CALLBACK_TABLE_DEF
  190. const FTC_Cache_ClassRec ftc_image_cache_class =
  191. {
  192. sizeof ( FTC_CacheRec ),
  193. (FTC_Cache_InitFunc) ftc_cache_init,
  194. (FTC_Cache_ClearFunc)ftc_cache_clear,
  195. (FTC_Cache_DoneFunc) ftc_cache_done,
  196. sizeof ( FTC_ImageFamilyRec ),
  197. (FTC_Family_InitFunc) ftc_image_family_init,
  198. (FTC_Family_CompareFunc)ftc_image_family_compare,
  199. (FTC_Family_DoneFunc) ftc_glyph_family_done,
  200. sizeof ( FTC_ImageNodeRec ),
  201. (FTC_Node_InitFunc) ftc_image_node_init,
  202. (FTC_Node_WeightFunc) ftc_image_node_weight,
  203. (FTC_Node_CompareFunc)ftc_glyph_node_compare,
  204. (FTC_Node_DoneFunc) ftc_image_node_done
  205. };
  206. /* documentation is in ftcimage.h */
  207. FT_EXPORT_DEF( FT_Error )
  208. FTC_ImageCache_New( FTC_Manager manager,
  209. FTC_ImageCache *acache )
  210. {
  211. return FTC_Manager_Register_Cache(
  212. manager,
  213. (FTC_Cache_Class)&ftc_image_cache_class,
  214. FTC_CACHE_P( acache ) );
  215. }
  216. /* documentation is in ftcimage.h */
  217. FT_EXPORT_DEF( FT_Error )
  218. FTC_ImageCache_Lookup( FTC_ImageCache cache,
  219. FTC_ImageType type,
  220. FT_UInt gindex,
  221. FT_Glyph *aglyph,
  222. FTC_Node *anode )
  223. {
  224. FTC_ImageQueryRec iquery;
  225. FTC_ImageNode node;
  226. FT_Error error;
  227. /* some argument checks are delayed to ftc_cache_lookup */
  228. if ( !aglyph )
  229. return FTC_Err_Invalid_Argument;
  230. if ( anode )
  231. *anode = NULL;
  232. iquery.gquery.gindex = gindex;
  233. iquery.type = *type;
  234. error = ftc_cache_lookup( FTC_CACHE( cache ),
  235. FTC_QUERY( &iquery ),
  236. (FTC_Node*)&node );
  237. if ( !error )
  238. {
  239. *aglyph = node->glyph;
  240. if ( anode )
  241. {
  242. *anode = (FTC_Node)node;
  243. FTC_NODE( node )->ref_count++;
  244. }
  245. }
  246. return error;
  247. }
  248. /* backwards-compatibility functions */
  249. FT_EXPORT_DEF( FT_Error )
  250. FTC_Image_Cache_New( FTC_Manager manager,
  251. FTC_Image_Cache *acache )
  252. {
  253. return FTC_ImageCache_New( manager, (FTC_ImageCache*)acache );
  254. }
  255. FT_EXPORT_DEF( FT_Error )
  256. FTC_Image_Cache_Lookup( FTC_Image_Cache icache,
  257. FTC_Image_Desc* desc,
  258. FT_UInt gindex,
  259. FT_Glyph *aglyph )
  260. {
  261. FTC_ImageTypeRec type0;
  262. if ( !desc )
  263. return FTC_Err_Invalid_Argument;
  264. type0.font = desc->font;
  265. /* convert image type flags to load flags */
  266. {
  267. FT_UInt load_flags = FT_LOAD_DEFAULT;
  268. FT_UInt type = desc->image_type;
  269. /* determine load flags, depending on the font description's */
  270. /* image type */
  271. if ( ftc_image_format( type ) == ftc_image_format_bitmap )
  272. {
  273. if ( type & ftc_image_flag_monochrome )
  274. load_flags |= FT_LOAD_MONOCHROME;
  275. /* disable embedded bitmaps loading if necessary */
  276. if ( type & ftc_image_flag_no_sbits )
  277. load_flags |= FT_LOAD_NO_BITMAP;
  278. }
  279. else
  280. {
  281. /* we want an outline, don't load embedded bitmaps */
  282. load_flags |= FT_LOAD_NO_BITMAP;
  283. if ( type & ftc_image_flag_unscaled )
  284. load_flags |= FT_LOAD_NO_SCALE;
  285. }
  286. /* always render glyphs to bitmaps */
  287. load_flags |= FT_LOAD_RENDER;
  288. if ( type & ftc_image_flag_unhinted )
  289. load_flags |= FT_LOAD_NO_HINTING;
  290. if ( type & ftc_image_flag_autohinted )
  291. load_flags |= FT_LOAD_FORCE_AUTOHINT;
  292. type0.flags = load_flags;
  293. }
  294. return FTC_ImageCache_Lookup( (FTC_ImageCache)icache,
  295. &type0,
  296. gindex,
  297. aglyph,
  298. NULL );
  299. }
  300. /* END */