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