/modules/freetype2/src/cache/ftcbasic.c

http://github.com/zpao/v8monkey · C · 851 lines · 572 code · 197 blank · 82 comment · 52 complexity · 791911381d6e479e1186f1851d45dc14 MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* ftcbasic.c */
  4. /* */
  5. /* The FreeType basic cache interface (body). */
  6. /* */
  7. /* Copyright 2003, 2004, 2005, 2006, 2007, 2009, 2010 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_INTERNAL_DEBUG_H
  19. #include FT_CACHE_H
  20. #include "ftcglyph.h"
  21. #include "ftcimage.h"
  22. #include "ftcsbits.h"
  23. #include "ftccback.h"
  24. #include "ftcerror.h"
  25. #define FT_COMPONENT trace_cache
  26. #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
  27. /*
  28. * These structures correspond to the FTC_Font and FTC_ImageDesc types
  29. * that were defined in version 2.1.7.
  30. */
  31. typedef struct FTC_OldFontRec_
  32. {
  33. FTC_FaceID face_id;
  34. FT_UShort pix_width;
  35. FT_UShort pix_height;
  36. } FTC_OldFontRec, *FTC_OldFont;
  37. typedef struct FTC_OldImageDescRec_
  38. {
  39. FTC_OldFontRec font;
  40. FT_UInt32 flags;
  41. } FTC_OldImageDescRec, *FTC_OldImageDesc;
  42. /*
  43. * Notice that FTC_OldImageDescRec and FTC_ImageTypeRec are nearly
  44. * identical, bit-wise. The only difference is that the `width' and
  45. * `height' fields are expressed as 16-bit integers in the old structure,
  46. * and as normal `int' in the new one.
  47. *
  48. * We are going to perform a weird hack to detect which structure is
  49. * being passed to the image and sbit caches. If the new structure's
  50. * `width' is larger than 0x10000, we assume that we are really receiving
  51. * an FTC_OldImageDesc.
  52. */
  53. #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
  54. /*
  55. * Basic Families
  56. *
  57. */
  58. typedef struct FTC_BasicAttrRec_
  59. {
  60. FTC_ScalerRec scaler;
  61. FT_UInt load_flags;
  62. } FTC_BasicAttrRec, *FTC_BasicAttrs;
  63. #define FTC_BASIC_ATTR_COMPARE( a, b ) \
  64. FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \
  65. (a)->load_flags == (b)->load_flags )
  66. #define FTC_BASIC_ATTR_HASH( a ) \
  67. ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags )
  68. typedef struct FTC_BasicQueryRec_
  69. {
  70. FTC_GQueryRec gquery;
  71. FTC_BasicAttrRec attrs;
  72. } FTC_BasicQueryRec, *FTC_BasicQuery;
  73. typedef struct FTC_BasicFamilyRec_
  74. {
  75. FTC_FamilyRec family;
  76. FTC_BasicAttrRec attrs;
  77. } FTC_BasicFamilyRec, *FTC_BasicFamily;
  78. FT_CALLBACK_DEF( FT_Bool )
  79. ftc_basic_family_compare( FTC_MruNode ftcfamily,
  80. FT_Pointer ftcquery )
  81. {
  82. FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily;
  83. FTC_BasicQuery query = (FTC_BasicQuery)ftcquery;
  84. return FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs );
  85. }
  86. FT_CALLBACK_DEF( FT_Error )
  87. ftc_basic_family_init( FTC_MruNode ftcfamily,
  88. FT_Pointer ftcquery,
  89. FT_Pointer ftccache )
  90. {
  91. FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily;
  92. FTC_BasicQuery query = (FTC_BasicQuery)ftcquery;
  93. FTC_Cache cache = (FTC_Cache)ftccache;
  94. FTC_Family_Init( FTC_FAMILY( family ), cache );
  95. family->attrs = query->attrs;
  96. return 0;
  97. }
  98. FT_CALLBACK_DEF( FT_UInt )
  99. ftc_basic_family_get_count( FTC_Family ftcfamily,
  100. FTC_Manager manager )
  101. {
  102. FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily;
  103. FT_Error error;
  104. FT_Face face;
  105. FT_UInt result = 0;
  106. error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id,
  107. &face );
  108. if ( error || !face )
  109. return result;
  110. if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs )
  111. {
  112. FT_TRACE1(( "ftc_basic_family_get_count: too large number of glyphs " ));
  113. FT_TRACE1(( "in this face, truncated\n", face->num_glyphs ));
  114. }
  115. if ( !error )
  116. result = (FT_UInt)face->num_glyphs;
  117. return result;
  118. }
  119. FT_CALLBACK_DEF( FT_Error )
  120. ftc_basic_family_load_bitmap( FTC_Family ftcfamily,
  121. FT_UInt gindex,
  122. FTC_Manager manager,
  123. FT_Face *aface )
  124. {
  125. FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily;
  126. FT_Error error;
  127. FT_Size size;
  128. error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size );
  129. if ( !error )
  130. {
  131. FT_Face face = size->face;
  132. error = FT_Load_Glyph( face, gindex,
  133. family->attrs.load_flags | FT_LOAD_RENDER );
  134. if ( !error )
  135. *aface = face;
  136. }
  137. return error;
  138. }
  139. FT_CALLBACK_DEF( FT_Error )
  140. ftc_basic_family_load_glyph( FTC_Family ftcfamily,
  141. FT_UInt gindex,
  142. FTC_Cache cache,
  143. FT_Glyph *aglyph )
  144. {
  145. FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily;
  146. FT_Error error;
  147. FTC_Scaler scaler = &family->attrs.scaler;
  148. FT_Face face;
  149. FT_Size size;
  150. /* we will now load the glyph image */
  151. error = FTC_Manager_LookupSize( cache->manager,
  152. scaler,
  153. &size );
  154. if ( !error )
  155. {
  156. face = size->face;
  157. error = FT_Load_Glyph( face, gindex, family->attrs.load_flags );
  158. if ( !error )
  159. {
  160. if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP ||
  161. face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
  162. {
  163. /* ok, copy it */
  164. FT_Glyph glyph;
  165. error = FT_Get_Glyph( face->glyph, &glyph );
  166. if ( !error )
  167. {
  168. *aglyph = glyph;
  169. goto Exit;
  170. }
  171. }
  172. else
  173. error = FTC_Err_Invalid_Argument;
  174. }
  175. }
  176. Exit:
  177. return error;
  178. }
  179. FT_CALLBACK_DEF( FT_Bool )
  180. ftc_basic_gnode_compare_faceid( FTC_Node ftcgnode,
  181. FT_Pointer ftcface_id,
  182. FTC_Cache cache )
  183. {
  184. FTC_GNode gnode = (FTC_GNode)ftcgnode;
  185. FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
  186. FTC_BasicFamily family = (FTC_BasicFamily)gnode->family;
  187. FT_Bool result;
  188. result = FT_BOOL( family->attrs.scaler.face_id == face_id );
  189. if ( result )
  190. {
  191. /* we must call this function to avoid this node from appearing
  192. * in later lookups with the same face_id!
  193. */
  194. FTC_GNode_UnselectFamily( gnode, cache );
  195. }
  196. return result;
  197. }
  198. /*
  199. *
  200. * basic image cache
  201. *
  202. */
  203. FT_CALLBACK_TABLE_DEF
  204. const FTC_IFamilyClassRec ftc_basic_image_family_class =
  205. {
  206. {
  207. sizeof ( FTC_BasicFamilyRec ),
  208. ftc_basic_family_compare,
  209. ftc_basic_family_init,
  210. 0, /* FTC_MruNode_ResetFunc */
  211. 0 /* FTC_MruNode_DoneFunc */
  212. },
  213. ftc_basic_family_load_glyph
  214. };
  215. FT_CALLBACK_TABLE_DEF
  216. const FTC_GCacheClassRec ftc_basic_image_cache_class =
  217. {
  218. {
  219. ftc_inode_new,
  220. ftc_inode_weight,
  221. ftc_gnode_compare,
  222. ftc_basic_gnode_compare_faceid,
  223. ftc_inode_free,
  224. sizeof ( FTC_GCacheRec ),
  225. ftc_gcache_init,
  226. ftc_gcache_done
  227. },
  228. (FTC_MruListClass)&ftc_basic_image_family_class
  229. };
  230. /* documentation is in ftcache.h */
  231. FT_EXPORT_DEF( FT_Error )
  232. FTC_ImageCache_New( FTC_Manager manager,
  233. FTC_ImageCache *acache )
  234. {
  235. return FTC_GCache_New( manager, &ftc_basic_image_cache_class,
  236. (FTC_GCache*)acache );
  237. }
  238. /* documentation is in ftcache.h */
  239. FT_EXPORT_DEF( FT_Error )
  240. FTC_ImageCache_Lookup( FTC_ImageCache cache,
  241. FTC_ImageType type,
  242. FT_UInt gindex,
  243. FT_Glyph *aglyph,
  244. FTC_Node *anode )
  245. {
  246. FTC_BasicQueryRec query;
  247. FTC_Node node = 0; /* make compiler happy */
  248. FT_Error error;
  249. FT_UInt32 hash;
  250. /* some argument checks are delayed to FTC_Cache_Lookup */
  251. if ( !aglyph )
  252. {
  253. error = FTC_Err_Invalid_Argument;
  254. goto Exit;
  255. }
  256. *aglyph = NULL;
  257. if ( anode )
  258. *anode = NULL;
  259. #if defined( FT_CONFIG_OPTION_OLD_INTERNALS ) && ( FT_INT_MAX > 0xFFFFU )
  260. /*
  261. * This one is a major hack used to detect whether we are passed a
  262. * regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one.
  263. */
  264. if ( (FT_ULong)type->width >= 0x10000L )
  265. {
  266. FTC_OldImageDesc desc = (FTC_OldImageDesc)type;
  267. query.attrs.scaler.face_id = desc->font.face_id;
  268. query.attrs.scaler.width = desc->font.pix_width;
  269. query.attrs.scaler.height = desc->font.pix_height;
  270. query.attrs.load_flags = desc->flags;
  271. }
  272. else
  273. #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
  274. {
  275. if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX )
  276. {
  277. FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" ));
  278. FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) ));
  279. }
  280. query.attrs.scaler.face_id = type->face_id;
  281. query.attrs.scaler.width = type->width;
  282. query.attrs.scaler.height = type->height;
  283. query.attrs.load_flags = (FT_UInt)type->flags;
  284. }
  285. query.attrs.scaler.pixel = 1;
  286. query.attrs.scaler.x_res = 0; /* make compilers happy */
  287. query.attrs.scaler.y_res = 0;
  288. hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;
  289. #if 1 /* inlining is about 50% faster! */
  290. FTC_GCACHE_LOOKUP_CMP( cache,
  291. ftc_basic_family_compare,
  292. FTC_GNode_Compare,
  293. hash, gindex,
  294. &query,
  295. node,
  296. error );
  297. #else
  298. error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
  299. hash, gindex,
  300. FTC_GQUERY( &query ),
  301. &node );
  302. #endif
  303. if ( !error )
  304. {
  305. *aglyph = FTC_INODE( node )->glyph;
  306. if ( anode )
  307. {
  308. *anode = node;
  309. node->ref_count++;
  310. }
  311. }
  312. Exit:
  313. return error;
  314. }
  315. /* documentation is in ftcache.h */
  316. FT_EXPORT_DEF( FT_Error )
  317. FTC_ImageCache_LookupScaler( FTC_ImageCache cache,
  318. FTC_Scaler scaler,
  319. FT_ULong load_flags,
  320. FT_UInt gindex,
  321. FT_Glyph *aglyph,
  322. FTC_Node *anode )
  323. {
  324. FTC_BasicQueryRec query;
  325. FTC_Node node = 0; /* make compiler happy */
  326. FT_Error error;
  327. FT_UInt32 hash;
  328. /* some argument checks are delayed to FTC_Cache_Lookup */
  329. if ( !aglyph || !scaler )
  330. {
  331. error = FTC_Err_Invalid_Argument;
  332. goto Exit;
  333. }
  334. *aglyph = NULL;
  335. if ( anode )
  336. *anode = NULL;
  337. /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */
  338. if ( load_flags > FT_UINT_MAX )
  339. {
  340. FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" ));
  341. FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) ));
  342. }
  343. query.attrs.scaler = scaler[0];
  344. query.attrs.load_flags = (FT_UInt)load_flags;
  345. hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;
  346. FTC_GCACHE_LOOKUP_CMP( cache,
  347. ftc_basic_family_compare,
  348. FTC_GNode_Compare,
  349. hash, gindex,
  350. &query,
  351. node,
  352. error );
  353. if ( !error )
  354. {
  355. *aglyph = FTC_INODE( node )->glyph;
  356. if ( anode )
  357. {
  358. *anode = node;
  359. node->ref_count++;
  360. }
  361. }
  362. Exit:
  363. return error;
  364. }
  365. #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
  366. /* yet another backwards-legacy structure */
  367. typedef struct FTC_OldImage_Desc_
  368. {
  369. FTC_FontRec font;
  370. FT_UInt image_type;
  371. } FTC_OldImage_Desc;
  372. #define FTC_OLD_IMAGE_FORMAT( x ) ( (x) & 7 )
  373. #define ftc_old_image_format_bitmap 0x0000
  374. #define ftc_old_image_format_outline 0x0001
  375. #define ftc_old_image_format_mask 0x000F
  376. #define ftc_old_image_flag_monochrome 0x0010
  377. #define ftc_old_image_flag_unhinted 0x0020
  378. #define ftc_old_image_flag_autohinted 0x0040
  379. #define ftc_old_image_flag_unscaled 0x0080
  380. #define ftc_old_image_flag_no_sbits 0x0100
  381. /* monochrome bitmap */
  382. #define ftc_old_image_mono ftc_old_image_format_bitmap | \
  383. ftc_old_image_flag_monochrome
  384. /* anti-aliased bitmap */
  385. #define ftc_old_image_grays ftc_old_image_format_bitmap
  386. /* scaled outline */
  387. #define ftc_old_image_outline ftc_old_image_format_outline
  388. static void
  389. ftc_image_type_from_old_desc( FTC_ImageType typ,
  390. FTC_OldImage_Desc* desc )
  391. {
  392. typ->face_id = desc->font.face_id;
  393. typ->width = desc->font.pix_width;
  394. typ->height = desc->font.pix_height;
  395. /* convert image type flags to load flags */
  396. {
  397. FT_UInt load_flags = FT_LOAD_DEFAULT;
  398. FT_UInt type = desc->image_type;
  399. /* determine load flags, depending on the font description's */
  400. /* image type */
  401. if ( FTC_OLD_IMAGE_FORMAT( type ) == ftc_old_image_format_bitmap )
  402. {
  403. if ( type & ftc_old_image_flag_monochrome )
  404. load_flags |= FT_LOAD_MONOCHROME;
  405. /* disable embedded bitmaps loading if necessary */
  406. if ( type & ftc_old_image_flag_no_sbits )
  407. load_flags |= FT_LOAD_NO_BITMAP;
  408. }
  409. else
  410. {
  411. /* we want an outline, don't load embedded bitmaps */
  412. load_flags |= FT_LOAD_NO_BITMAP;
  413. if ( type & ftc_old_image_flag_unscaled )
  414. load_flags |= FT_LOAD_NO_SCALE;
  415. }
  416. /* always render glyphs to bitmaps */
  417. load_flags |= FT_LOAD_RENDER;
  418. if ( type & ftc_old_image_flag_unhinted )
  419. load_flags |= FT_LOAD_NO_HINTING;
  420. if ( type & ftc_old_image_flag_autohinted )
  421. load_flags |= FT_LOAD_FORCE_AUTOHINT;
  422. typ->flags = load_flags;
  423. }
  424. }
  425. FT_EXPORT( FT_Error )
  426. FTC_Image_Cache_New( FTC_Manager manager,
  427. FTC_ImageCache *acache );
  428. FT_EXPORT( FT_Error )
  429. FTC_Image_Cache_Lookup( FTC_ImageCache icache,
  430. FTC_OldImage_Desc* desc,
  431. FT_UInt gindex,
  432. FT_Glyph *aglyph );
  433. FT_EXPORT_DEF( FT_Error )
  434. FTC_Image_Cache_New( FTC_Manager manager,
  435. FTC_ImageCache *acache )
  436. {
  437. return FTC_ImageCache_New( manager, (FTC_ImageCache*)acache );
  438. }
  439. FT_EXPORT_DEF( FT_Error )
  440. FTC_Image_Cache_Lookup( FTC_ImageCache icache,
  441. FTC_OldImage_Desc* desc,
  442. FT_UInt gindex,
  443. FT_Glyph *aglyph )
  444. {
  445. FTC_ImageTypeRec type0;
  446. if ( !desc )
  447. return FTC_Err_Invalid_Argument;
  448. ftc_image_type_from_old_desc( &type0, desc );
  449. return FTC_ImageCache_Lookup( (FTC_ImageCache)icache,
  450. &type0,
  451. gindex,
  452. aglyph,
  453. NULL );
  454. }
  455. #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
  456. /*
  457. *
  458. * basic small bitmap cache
  459. *
  460. */
  461. FT_CALLBACK_TABLE_DEF
  462. const FTC_SFamilyClassRec ftc_basic_sbit_family_class =
  463. {
  464. {
  465. sizeof( FTC_BasicFamilyRec ),
  466. ftc_basic_family_compare,
  467. ftc_basic_family_init,
  468. 0, /* FTC_MruNode_ResetFunc */
  469. 0 /* FTC_MruNode_DoneFunc */
  470. },
  471. ftc_basic_family_get_count,
  472. ftc_basic_family_load_bitmap
  473. };
  474. FT_CALLBACK_TABLE_DEF
  475. const FTC_GCacheClassRec ftc_basic_sbit_cache_class =
  476. {
  477. {
  478. ftc_snode_new,
  479. ftc_snode_weight,
  480. ftc_snode_compare,
  481. ftc_basic_gnode_compare_faceid,
  482. ftc_snode_free,
  483. sizeof ( FTC_GCacheRec ),
  484. ftc_gcache_init,
  485. ftc_gcache_done
  486. },
  487. (FTC_MruListClass)&ftc_basic_sbit_family_class
  488. };
  489. /* documentation is in ftcache.h */
  490. FT_EXPORT_DEF( FT_Error )
  491. FTC_SBitCache_New( FTC_Manager manager,
  492. FTC_SBitCache *acache )
  493. {
  494. return FTC_GCache_New( manager, &ftc_basic_sbit_cache_class,
  495. (FTC_GCache*)acache );
  496. }
  497. /* documentation is in ftcache.h */
  498. FT_EXPORT_DEF( FT_Error )
  499. FTC_SBitCache_Lookup( FTC_SBitCache cache,
  500. FTC_ImageType type,
  501. FT_UInt gindex,
  502. FTC_SBit *ansbit,
  503. FTC_Node *anode )
  504. {
  505. FT_Error error;
  506. FTC_BasicQueryRec query;
  507. FTC_Node node = 0; /* make compiler happy */
  508. FT_UInt32 hash;
  509. if ( anode )
  510. *anode = NULL;
  511. /* other argument checks delayed to FTC_Cache_Lookup */
  512. if ( !ansbit )
  513. return FTC_Err_Invalid_Argument;
  514. *ansbit = NULL;
  515. #if defined( FT_CONFIG_OPTION_OLD_INTERNALS ) && ( FT_INT_MAX > 0xFFFFU )
  516. /* This one is a major hack used to detect whether we are passed a
  517. * regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one.
  518. */
  519. if ( (FT_ULong)type->width >= 0x10000L )
  520. {
  521. FTC_OldImageDesc desc = (FTC_OldImageDesc)type;
  522. query.attrs.scaler.face_id = desc->font.face_id;
  523. query.attrs.scaler.width = desc->font.pix_width;
  524. query.attrs.scaler.height = desc->font.pix_height;
  525. query.attrs.load_flags = desc->flags;
  526. }
  527. else
  528. #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
  529. {
  530. if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX )
  531. {
  532. FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" ));
  533. FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) ));
  534. }
  535. query.attrs.scaler.face_id = type->face_id;
  536. query.attrs.scaler.width = type->width;
  537. query.attrs.scaler.height = type->height;
  538. query.attrs.load_flags = (FT_UInt)type->flags;
  539. }
  540. query.attrs.scaler.pixel = 1;
  541. query.attrs.scaler.x_res = 0; /* make compilers happy */
  542. query.attrs.scaler.y_res = 0;
  543. /* beware, the hash must be the same for all glyph ranges! */
  544. hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
  545. gindex / FTC_SBIT_ITEMS_PER_NODE;
  546. #if 1 /* inlining is about 50% faster! */
  547. FTC_GCACHE_LOOKUP_CMP( cache,
  548. ftc_basic_family_compare,
  549. FTC_SNode_Compare,
  550. hash, gindex,
  551. &query,
  552. node,
  553. error );
  554. #else
  555. error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
  556. hash,
  557. gindex,
  558. FTC_GQUERY( &query ),
  559. &node );
  560. #endif
  561. if ( error )
  562. goto Exit;
  563. *ansbit = FTC_SNODE( node )->sbits +
  564. ( gindex - FTC_GNODE( node )->gindex );
  565. if ( anode )
  566. {
  567. *anode = node;
  568. node->ref_count++;
  569. }
  570. Exit:
  571. return error;
  572. }
  573. /* documentation is in ftcache.h */
  574. FT_EXPORT_DEF( FT_Error )
  575. FTC_SBitCache_LookupScaler( FTC_SBitCache cache,
  576. FTC_Scaler scaler,
  577. FT_ULong load_flags,
  578. FT_UInt gindex,
  579. FTC_SBit *ansbit,
  580. FTC_Node *anode )
  581. {
  582. FT_Error error;
  583. FTC_BasicQueryRec query;
  584. FTC_Node node = 0; /* make compiler happy */
  585. FT_UInt32 hash;
  586. if ( anode )
  587. *anode = NULL;
  588. /* other argument checks delayed to FTC_Cache_Lookup */
  589. if ( !ansbit || !scaler )
  590. return FTC_Err_Invalid_Argument;
  591. *ansbit = NULL;
  592. /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */
  593. if ( load_flags > FT_UINT_MAX )
  594. {
  595. FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" ));
  596. FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) ));
  597. }
  598. query.attrs.scaler = scaler[0];
  599. query.attrs.load_flags = (FT_UInt)load_flags;
  600. /* beware, the hash must be the same for all glyph ranges! */
  601. hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
  602. gindex / FTC_SBIT_ITEMS_PER_NODE;
  603. FTC_GCACHE_LOOKUP_CMP( cache,
  604. ftc_basic_family_compare,
  605. FTC_SNode_Compare,
  606. hash, gindex,
  607. &query,
  608. node,
  609. error );
  610. if ( error )
  611. goto Exit;
  612. *ansbit = FTC_SNODE( node )->sbits +
  613. ( gindex - FTC_GNODE( node )->gindex );
  614. if ( anode )
  615. {
  616. *anode = node;
  617. node->ref_count++;
  618. }
  619. Exit:
  620. return error;
  621. }
  622. #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
  623. FT_EXPORT( FT_Error )
  624. FTC_SBit_Cache_New( FTC_Manager manager,
  625. FTC_SBitCache *acache );
  626. FT_EXPORT( FT_Error )
  627. FTC_SBit_Cache_Lookup( FTC_SBitCache cache,
  628. FTC_OldImage_Desc* desc,
  629. FT_UInt gindex,
  630. FTC_SBit *ansbit );
  631. FT_EXPORT_DEF( FT_Error )
  632. FTC_SBit_Cache_New( FTC_Manager manager,
  633. FTC_SBitCache *acache )
  634. {
  635. return FTC_SBitCache_New( manager, (FTC_SBitCache*)acache );
  636. }
  637. FT_EXPORT_DEF( FT_Error )
  638. FTC_SBit_Cache_Lookup( FTC_SBitCache cache,
  639. FTC_OldImage_Desc* desc,
  640. FT_UInt gindex,
  641. FTC_SBit *ansbit )
  642. {
  643. FTC_ImageTypeRec type0;
  644. if ( !desc )
  645. return FTC_Err_Invalid_Argument;
  646. ftc_image_type_from_old_desc( &type0, desc );
  647. return FTC_SBitCache_Lookup( (FTC_SBitCache)cache,
  648. &type0,
  649. gindex,
  650. ansbit,
  651. NULL );
  652. }
  653. #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
  654. /* END */