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