ReactOS 0.4.15-dev-7788-g1ad9096
ftcsbits.c
Go to the documentation of this file.
1/***************************************************************************/
2/* */
3/* ftcsbits.c */
4/* */
5/* FreeType sbits manager (body). */
6/* */
7/* Copyright 2000-2018 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 "ftcsbits.h"
22#include FT_INTERNAL_OBJECTS_H
23#include FT_INTERNAL_DEBUG_H
24#include FT_ERRORS_H
25
26#include "ftccback.h"
27#include "ftcerror.h"
28
29#undef FT_COMPONENT
30#define FT_COMPONENT trace_cache
31
32
33 /*************************************************************************/
34 /*************************************************************************/
35 /***** *****/
36 /***** SBIT CACHE NODES *****/
37 /***** *****/
38 /*************************************************************************/
39 /*************************************************************************/
40
41
42 static FT_Error
46 {
48 FT_Int pitch = bitmap->pitch;
50
51
52 if ( pitch < 0 )
53 pitch = -pitch;
54
55 size = (FT_ULong)pitch * bitmap->rows;
56 if ( !size )
57 return FT_Err_Ok;
58
59 if ( !FT_ALLOC( sbit->buffer, size ) )
60 FT_MEM_COPY( sbit->buffer, bitmap->buffer, size );
61
62 return error;
63 }
64
65
66 FT_LOCAL_DEF( void )
69 {
70 FTC_SNode snode = (FTC_SNode)ftcsnode;
71 FTC_SBit sbit = snode->sbits;
72 FT_UInt count = snode->count;
73 FT_Memory memory = cache->memory;
74
75
76 for ( ; count > 0; sbit++, count-- )
77 FT_FREE( sbit->buffer );
78
79 FTC_GNode_Done( FTC_GNODE( snode ), cache );
80
81 FT_FREE( snode );
82 }
83
84
85 FT_LOCAL_DEF( void )
88 {
89 ftc_snode_free( FTC_NODE( snode ), cache );
90 }
91
92
93 /*
94 * This function tries to load a small bitmap within a given FTC_SNode.
95 * Note that it returns a non-zero error code _only_ in the case of
96 * out-of-memory condition. For all other errors (e.g., corresponding
97 * to a bad font file), this function will mark the sbit as `unavailable'
98 * and return a value of 0.
99 *
100 * You should also read the comment within the @ftc_snode_compare
101 * function below to see how out-of-memory is handled during a lookup.
102 */
103 static FT_Error
105 FTC_Manager manager,
106 FT_UInt gindex,
107 FT_ULong *asize )
108 {
110 FTC_GNode gnode = FTC_GNODE( snode );
111 FTC_Family family = gnode->family;
112 FT_Memory memory = manager->memory;
114 FTC_SBit sbit;
115 FTC_SFamilyClass clazz;
116
117
118 if ( (FT_UInt)(gindex - gnode->gindex) >= snode->count )
119 {
120 FT_ERROR(( "ftc_snode_load: invalid glyph index" ));
121 return FT_THROW( Invalid_Argument );
122 }
123
124 sbit = snode->sbits + ( gindex - gnode->gindex );
125 clazz = (FTC_SFamilyClass)family->clazz;
126
127 sbit->buffer = 0;
128
129 error = clazz->family_load_glyph( family, gindex, manager, &face );
130 if ( error )
131 goto BadGlyph;
132
133 {
134 FT_Int temp;
135 FT_GlyphSlot slot = face->glyph;
136 FT_Bitmap* bitmap = &slot->bitmap;
137 FT_Pos xadvance, yadvance; /* FT_GlyphSlot->advance.{x|y} */
138
139
140 if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
141 {
142 FT_TRACE0(( "ftc_snode_load:"
143 " glyph loaded didn't return a bitmap\n" ));
144 goto BadGlyph;
145 }
146
147 /* Check whether our values fit into 8-bit containers! */
148 /* If this is not the case, our bitmap is too large */
149 /* and we will leave it as `missing' with sbit.buffer = 0 */
150
151#define CHECK_CHAR( d ) ( temp = (FT_Char)d, (FT_Int) temp == (FT_Int) d )
152#define CHECK_BYTE( d ) ( temp = (FT_Byte)d, (FT_UInt)temp == (FT_UInt)d )
153
154 /* horizontal advance in pixels */
155 xadvance = ( slot->advance.x + 32 ) >> 6;
156 yadvance = ( slot->advance.y + 32 ) >> 6;
157
158 if ( !CHECK_BYTE( bitmap->rows ) ||
159 !CHECK_BYTE( bitmap->width ) ||
160 !CHECK_CHAR( bitmap->pitch ) ||
161 !CHECK_CHAR( slot->bitmap_left ) ||
162 !CHECK_CHAR( slot->bitmap_top ) ||
163 !CHECK_CHAR( xadvance ) ||
164 !CHECK_CHAR( yadvance ) )
165 {
166 FT_TRACE2(( "ftc_snode_load:"
167 " glyph too large for small bitmap cache\n"));
168 goto BadGlyph;
169 }
170
171 sbit->width = (FT_Byte)bitmap->width;
172 sbit->height = (FT_Byte)bitmap->rows;
173 sbit->pitch = (FT_Char)bitmap->pitch;
174 sbit->left = (FT_Char)slot->bitmap_left;
175 sbit->top = (FT_Char)slot->bitmap_top;
176 sbit->xadvance = (FT_Char)xadvance;
177 sbit->yadvance = (FT_Char)yadvance;
178 sbit->format = (FT_Byte)bitmap->pixel_mode;
179 sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1);
180
181 /* copy the bitmap into a new buffer -- ignore error */
183
184 /* now, compute size */
185 if ( asize )
186 *asize = (FT_ULong)FT_ABS( sbit->pitch ) * sbit->height;
187
188 } /* glyph loading successful */
189
190 /* ignore the errors that might have occurred -- */
191 /* we mark unloaded glyphs with `sbit.buffer == 0' */
192 /* and `width == 255', `height == 0' */
193 /* */
194 if ( error && FT_ERR_NEQ( error, Out_Of_Memory ) )
195 {
196 BadGlyph:
197 sbit->width = 255;
198 sbit->height = 0;
199 sbit->buffer = NULL;
201 if ( asize )
202 *asize = 0;
203 }
204
205 return error;
206 }
207
208
211 FTC_GQuery gquery,
213 {
214 FT_Memory memory = cache->memory;
216 FTC_SNode snode = NULL;
217 FT_UInt gindex = gquery->gindex;
218 FTC_Family family = gquery->family;
219
222 FT_UInt node_count;
223
224
225 total = clazz->family_get_count( family, cache->manager );
226 if ( total == 0 || gindex >= total )
227 {
228 error = FT_THROW( Invalid_Argument );
229 goto Exit;
230 }
231
232 if ( !FT_NEW( snode ) )
233 {
235
236
237 start = gindex - ( gindex % FTC_SBIT_ITEMS_PER_NODE );
238 count = total - start;
241
242 FTC_GNode_Init( FTC_GNODE( snode ), start, family );
243
244 snode->count = count;
245 for ( node_count = 0; node_count < count; node_count++ )
246 {
247 snode->sbits[node_count].width = 255;
248 }
249
250 error = ftc_snode_load( snode,
251 cache->manager,
252 gindex,
253 NULL );
254 if ( error )
255 {
256 FTC_SNode_Free( snode, cache );
257 snode = NULL;
258 }
259 }
260
261 Exit:
262 *psnode = snode;
263 return error;
264 }
265
266
269 FT_Pointer ftcgquery,
271 {
272 FTC_SNode *psnode = (FTC_SNode*)ftcpsnode;
273 FTC_GQuery gquery = (FTC_GQuery)ftcgquery;
274
275
276 return FTC_SNode_New( psnode, gquery, cache );
277 }
278
279
283 {
284 FTC_SNode snode = (FTC_SNode)ftcsnode;
285 FT_UInt count = snode->count;
286 FTC_SBit sbit = snode->sbits;
287 FT_Int pitch;
289
290 FT_UNUSED( cache );
291
292
294
295 /* the node itself */
296 size = sizeof ( *snode );
297
298 for ( ; count > 0; count--, sbit++ )
299 {
300 if ( sbit->buffer )
301 {
302 pitch = sbit->pitch;
303 if ( pitch < 0 )
304 pitch = -pitch;
305
306 /* add the size of a given glyph image */
307 size += (FT_Offset)pitch * sbit->height;
308 }
309 }
310
311 return size;
312 }
313
314
315#if 0
316
318 FTC_SNode_Weight( FTC_SNode snode )
319 {
320 return ftc_snode_weight( FTC_NODE( snode ), NULL );
321 }
322
323#endif /* 0 */
324
325
328 FT_Pointer ftcgquery,
330 FT_Bool* list_changed )
331 {
332 FTC_SNode snode = (FTC_SNode)ftcsnode;
333 FTC_GQuery gquery = (FTC_GQuery)ftcgquery;
334 FTC_GNode gnode = FTC_GNODE( snode );
335 FT_UInt gindex = gquery->gindex;
337
338
339 if (list_changed)
340 *list_changed = FALSE;
341 result = FT_BOOL( gnode->family == gquery->family &&
342 (FT_UInt)( gindex - gnode->gindex ) < snode->count );
343 if ( result )
344 {
345 /* check if we need to load the glyph bitmap now */
346 FTC_SBit sbit = snode->sbits + ( gindex - gnode->gindex );
347
348
349 /*
350 * The following code illustrates what to do when you want to
351 * perform operations that may fail within a lookup function.
352 *
353 * Here, we want to load a small bitmap on-demand; we thus
354 * need to call the `ftc_snode_load' function which may return
355 * a non-zero error code only when we are out of memory (OOM).
356 *
357 * The correct thing to do is to use @FTC_CACHE_TRYLOOP and
358 * @FTC_CACHE_TRYLOOP_END in order to implement a retry loop
359 * that is capable of flushing the cache incrementally when
360 * an OOM errors occur.
361 *
362 * However, we need to `lock' the node before this operation to
363 * prevent it from being flushed within the loop.
364 *
365 * When we exit the loop, we unlock the node, then check the `error'
366 * variable. If it is non-zero, this means that the cache was
367 * completely flushed and that no usable memory was found to load
368 * the bitmap.
369 *
370 * We then prefer to return a value of 0 (i.e., NO MATCH). This
371 * ensures that the caller will try to allocate a new node.
372 * This operation consequently _fail_ and the lookup function
373 * returns the appropriate OOM error code.
374 *
375 * Note that `buffer == NULL && width == 255' is a hack used to
376 * tag `unavailable' bitmaps in the array. We should never try
377 * to load these.
378 *
379 */
380
381 if ( !sbit->buffer && sbit->width == 255 )
382 {
385
386
387 ftcsnode->ref_count++; /* lock node to prevent flushing */
388 /* in retry loop */
389
391 {
392 error = ftc_snode_load( snode, cache->manager, gindex, &size );
393 }
394 FTC_CACHE_TRYLOOP_END( list_changed );
395
396 ftcsnode->ref_count--; /* unlock the node */
397
398 if ( error )
399 result = 0;
400 else
401 cache->manager->cur_weight += size;
402 }
403 }
404
405 return result;
406 }
407
408
409#ifdef FTC_INLINE
410
413 FTC_GQuery gquery,
415 FT_Bool* list_changed )
416 {
417 return ftc_snode_compare( FTC_NODE( snode ), gquery,
418 cache, list_changed );
419 }
420
421#endif
422
423/* END */
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
WORD face[3]
Definition: mesh.c:4747
return FT_Err_Ok
Definition: ftbbox.c:511
#define FTC_CACHE_TRYLOOP_END(list_changed)
Definition: ftccache.h:323
#define FTC_CACHE_TRYLOOP(cache)
Definition: ftccache.h:312
#define FTC_NODE(x)
Definition: ftccache.h:69
FTC_GNode_Done(FTC_GNode gnode, FTC_Cache cache)
Definition: ftcglyph.c:55
FTC_GNode_Init(FTC_GNode gnode, FT_UInt gindex, FTC_Family family)
Definition: ftcglyph.c:31
FT_BEGIN_HEADER struct FTC_FamilyRec_ * FTC_Family
struct FTC_GQueryRec_ * FTC_GQuery
#define FTC_GNODE(x)
Definition: ftcglyph.h:156
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
ftc_snode_new(FTC_Node *ftcpsnode, FT_Pointer ftcgquery, FTC_Cache cache)
Definition: ftcsbits.c:268
ftc_snode_weight(FTC_Node ftcsnode, FTC_Cache cache)
Definition: ftcsbits.c:281
FTC_SNode_Compare(FTC_SNode snode, FTC_GQuery gquery, FTC_Cache cache, FT_Bool *list_changed)
Definition: ftcsbits.c:412
ftc_snode_free(FTC_Node ftcsnode, FTC_Cache cache)
Definition: ftcsbits.c:67
#define CHECK_BYTE(d)
static FT_Error ftc_snode_load(FTC_SNode snode, FTC_Manager manager, FT_UInt gindex, FT_ULong *asize)
Definition: ftcsbits.c:104
static FT_Error ftc_sbit_copy_bitmap(FTC_SBit sbit, FT_Bitmap *bitmap, FT_Memory memory)
Definition: ftcsbits.c:43
FTC_SNode_New(FTC_SNode *psnode, FTC_GQuery gquery, FTC_Cache cache)
Definition: ftcsbits.c:210
FTC_SNode_Free(FTC_SNode snode, FTC_Cache cache)
Definition: ftcsbits.c:86
ftc_snode_compare(FTC_Node ftcsnode, FT_Pointer ftcgquery, FTC_Cache cache, FT_Bool *list_changed)
Definition: ftcsbits.c:327
#define CHECK_CHAR(d)
#define FTC_CACHE_SFAMILY_CLASS(x)
Definition: ftcsbits.h:67
const FTC_SFamilyClassRec * FTC_SFamilyClass
Definition: ftcsbits.h:63
struct FTC_SNodeRec_ * FTC_SNode
#define FTC_SBIT_ITEMS_PER_NODE
Definition: ftcsbits.h:30
#define FT_ASSERT(condition)
Definition: ftdebug.h:211
#define FT_TRACE0(varformat)
Definition: ftdebug.h:157
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
#define FT_THROW(e)
Definition: ftdebug.h:213
#define FT_TRACE2(varformat)
Definition: ftdebug.h:159
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
#define FT_NEW(ptr)
Definition: ftmemory.h:331
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:303
#define FT_FREE(ptr)
Definition: ftmemory.h:329
#define FT_MEM_COPY(dest, source, count)
Definition: ftmemory.h:228
#define FT_ABS(a)
Definition: ftobjs.h:74
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
signed char FT_Char
Definition: fttypes.h:143
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
unsigned long FT_ULong
Definition: fttypes.h:253
unsigned char FT_Byte
Definition: fttypes.h:154
int FT_Error
Definition: fttypes.h:300
#define FT_ERR_NEQ(x, e)
Definition: fttypes.h:593
unsigned int FT_UInt
Definition: fttypes.h:231
#define FT_BOOL(x)
Definition: fttypes.h:578
size_t FT_Offset
Definition: fttypes.h:324
signed int FT_Int
Definition: fttypes.h:220
size_t total
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
GLuint64EXT * result
Definition: glext.h:11304
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
static char memory[1024 *256]
Definition: process.c:116
static calc_node_t temp
Definition: rpn_ieee.c:38
static void Exit(void)
Definition: sock.c:1330
FT_UInt gindex
Definition: ftcglyph.h:152
FTC_Family family
Definition: ftcglyph.h:151
FTC_Family family
Definition: ftcglyph.h:163
FT_UInt gindex
Definition: ftcglyph.h:162
FT_Memory memory
Definition: ftcmanag.h:94
FT_Short pitch
Definition: ftcache.h:881
FT_Byte format
Definition: ftcache.h:879
FT_Char top
Definition: ftcache.h:877
FT_Char xadvance
Definition: ftcache.h:882
FT_Byte height
Definition: ftcache.h:875
FT_Byte width
Definition: ftcache.h:874
FT_Byte max_grays
Definition: ftcache.h:880
FT_Char yadvance
Definition: ftcache.h:883
FT_Byte * buffer
Definition: ftcache.h:885
FT_Char left
Definition: ftcache.h:876
FTC_SFamily_GetCountFunc family_get_count
Definition: ftcsbits.h:58
FTC_SFamily_LoadGlyphFunc family_load_glyph
Definition: ftcsbits.h:59
FTC_MruListClassRec clazz
Definition: ftcsbits.h:57
FTC_SBitRec sbits[FTC_SBIT_ITEMS_PER_NODE]
Definition: ftcsbits.h:36
FT_UInt count
Definition: ftcsbits.h:35
Definition: vfat.h:185
Definition: uimain.c:89
uint32 width
Definition: uimain.c:91
Definition: cache.c:49