/src/freetype/src/cache/ftcbasic.c

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