Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(624)

Side by Side Diff: src/cache/ftcsbits.c

Issue 89753003: Update freetype to latest version of ASOP. (Closed) Base URL: https://chromium.googlesource.com/chromium/src/third_party/freetype.git@master
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/cache/ftcsbits.h ('k') | src/cff/cf2arrst.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /***************************************************************************/
2 /* */
3 /* ftcsbits.c */
4 /* */
5 /* FreeType sbits manager (body). */
6 /* */
7 /* Copyright 2000-2006, 2009-2011, 2013 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
43 ftc_sbit_copy_bitmap( FTC_SBit sbit,
44 FT_Bitmap* bitmap,
45 FT_Memory memory )
46 {
47 FT_Error error;
48 FT_Int pitch = bitmap->pitch;
49 FT_ULong size;
50
51
52 if ( pitch < 0 )
53 pitch = -pitch;
54
55 size = (FT_ULong)( pitch * bitmap->rows );
56
57 if ( !FT_ALLOC( sbit->buffer, size ) )
58 FT_MEM_COPY( sbit->buffer, bitmap->buffer, size );
59
60 return error;
61 }
62
63
64 FT_LOCAL_DEF( void )
65 ftc_snode_free( FTC_Node ftcsnode,
66 FTC_Cache cache )
67 {
68 FTC_SNode snode = (FTC_SNode)ftcsnode;
69 FTC_SBit sbit = snode->sbits;
70 FT_UInt count = snode->count;
71 FT_Memory memory = cache->memory;
72
73
74 for ( ; count > 0; sbit++, count-- )
75 FT_FREE( sbit->buffer );
76
77 FTC_GNode_Done( FTC_GNODE( snode ), cache );
78
79 FT_FREE( snode );
80 }
81
82
83 FT_LOCAL_DEF( void )
84 FTC_SNode_Free( FTC_SNode snode,
85 FTC_Cache cache )
86 {
87 ftc_snode_free( FTC_NODE( snode ), cache );
88 }
89
90
91 /*
92 * This function tries to load a small bitmap within a given FTC_SNode.
93 * Note that it returns a non-zero error code _only_ in the case of
94 * out-of-memory condition. For all other errors (e.g., corresponding
95 * to a bad font file), this function will mark the sbit as `unavailable'
96 * and return a value of 0.
97 *
98 * You should also read the comment within the @ftc_snode_compare
99 * function below to see how out-of-memory is handled during a lookup.
100 */
101 static FT_Error
102 ftc_snode_load( FTC_SNode snode,
103 FTC_Manager manager,
104 FT_UInt gindex,
105 FT_ULong *asize )
106 {
107 FT_Error error;
108 FTC_GNode gnode = FTC_GNODE( snode );
109 FTC_Family family = gnode->family;
110 FT_Memory memory = manager->memory;
111 FT_Face face;
112 FTC_SBit sbit;
113 FTC_SFamilyClass clazz;
114
115
116 if ( (FT_UInt)(gindex - gnode->gindex) >= snode->count )
117 {
118 FT_ERROR(( "ftc_snode_load: invalid glyph index" ));
119 return FT_THROW( Invalid_Argument );
120 }
121
122 sbit = snode->sbits + ( gindex - gnode->gindex );
123 clazz = (FTC_SFamilyClass)family->clazz;
124
125 sbit->buffer = 0;
126
127 error = clazz->family_load_glyph( family, gindex, manager, &face );
128 if ( error )
129 goto BadGlyph;
130
131 {
132 FT_Int temp;
133 FT_GlyphSlot slot = face->glyph;
134 FT_Bitmap* bitmap = &slot->bitmap;
135 FT_Pos xadvance, yadvance; /* FT_GlyphSlot->advance.{x|y} */
136
137
138 if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
139 {
140 FT_TRACE0(( "ftc_snode_load:"
141 " glyph loaded didn't return a bitmap\n" ));
142 goto BadGlyph;
143 }
144
145 /* Check that our values fit into 8-bit containers! */
146 /* If this is not the case, our bitmap is too large */
147 /* and we will leave it as `missing' with sbit.buffer = 0 */
148
149 #define CHECK_CHAR( d ) ( temp = (FT_Char)d, temp == d )
150 #define CHECK_BYTE( d ) ( temp = (FT_Byte)d, temp == d )
151
152 /* horizontal advance in pixels */
153 xadvance = ( slot->advance.x + 32 ) >> 6;
154 yadvance = ( slot->advance.y + 32 ) >> 6;
155
156 if ( !CHECK_BYTE( bitmap->rows ) ||
157 !CHECK_BYTE( bitmap->width ) ||
158 !CHECK_CHAR( bitmap->pitch ) ||
159 !CHECK_CHAR( slot->bitmap_left ) ||
160 !CHECK_CHAR( slot->bitmap_top ) ||
161 !CHECK_CHAR( xadvance ) ||
162 !CHECK_CHAR( yadvance ) )
163 {
164 FT_TRACE2(( "ftc_snode_load:"
165 " glyph too large for small bitmap cache\n"));
166 goto BadGlyph;
167 }
168
169 sbit->width = (FT_Byte)bitmap->width;
170 sbit->height = (FT_Byte)bitmap->rows;
171 sbit->pitch = (FT_Char)bitmap->pitch;
172 sbit->left = (FT_Char)slot->bitmap_left;
173 sbit->top = (FT_Char)slot->bitmap_top;
174 sbit->xadvance = (FT_Char)xadvance;
175 sbit->yadvance = (FT_Char)yadvance;
176 sbit->format = (FT_Byte)bitmap->pixel_mode;
177 sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1);
178
179 /* copy the bitmap into a new buffer -- ignore error */
180 error = ftc_sbit_copy_bitmap( sbit, bitmap, memory );
181
182 /* now, compute size */
183 if ( asize )
184 *asize = FT_ABS( sbit->pitch ) * sbit->height;
185
186 } /* glyph loading successful */
187
188 /* ignore the errors that might have occurred -- */
189 /* we mark unloaded glyphs with `sbit.buffer == 0' */
190 /* and `width == 255', `height == 0' */
191 /* */
192 if ( error && FT_ERR_NEQ( error, Out_Of_Memory ) )
193 {
194 BadGlyph:
195 sbit->width = 255;
196 sbit->height = 0;
197 sbit->buffer = NULL;
198 error = FT_Err_Ok;
199 if ( asize )
200 *asize = 0;
201 }
202
203 return error;
204 }
205
206
207 FT_LOCAL_DEF( FT_Error )
208 FTC_SNode_New( FTC_SNode *psnode,
209 FTC_GQuery gquery,
210 FTC_Cache cache )
211 {
212 FT_Memory memory = cache->memory;
213 FT_Error error;
214 FTC_SNode snode = NULL;
215 FT_UInt gindex = gquery->gindex;
216 FTC_Family family = gquery->family;
217
218 FTC_SFamilyClass clazz = FTC_CACHE__SFAMILY_CLASS( cache );
219 FT_UInt total;
220 FT_UInt node_count;
221
222
223 total = clazz->family_get_count( family, cache->manager );
224 if ( total == 0 || gindex >= total )
225 {
226 error = FT_THROW( Invalid_Argument );
227 goto Exit;
228 }
229
230 if ( !FT_NEW( snode ) )
231 {
232 FT_UInt count, start;
233
234
235 start = gindex - ( gindex % FTC_SBIT_ITEMS_PER_NODE );
236 count = total - start;
237 if ( count > FTC_SBIT_ITEMS_PER_NODE )
238 count = FTC_SBIT_ITEMS_PER_NODE;
239
240 FTC_GNode_Init( FTC_GNODE( snode ), start, family );
241
242 snode->count = count;
243 for ( node_count = 0; node_count < count; node_count++ )
244 {
245 snode->sbits[node_count].width = 255;
246 }
247
248 error = ftc_snode_load( snode,
249 cache->manager,
250 gindex,
251 NULL );
252 if ( error )
253 {
254 FTC_SNode_Free( snode, cache );
255 snode = NULL;
256 }
257 }
258
259 Exit:
260 *psnode = snode;
261 return error;
262 }
263
264
265 FT_LOCAL_DEF( FT_Error )
266 ftc_snode_new( FTC_Node *ftcpsnode,
267 FT_Pointer ftcgquery,
268 FTC_Cache cache )
269 {
270 FTC_SNode *psnode = (FTC_SNode*)ftcpsnode;
271 FTC_GQuery gquery = (FTC_GQuery)ftcgquery;
272
273
274 return FTC_SNode_New( psnode, gquery, cache );
275 }
276
277
278 FT_LOCAL_DEF( FT_Offset )
279 ftc_snode_weight( FTC_Node ftcsnode,
280 FTC_Cache cache )
281 {
282 FTC_SNode snode = (FTC_SNode)ftcsnode;
283 FT_UInt count = snode->count;
284 FTC_SBit sbit = snode->sbits;
285 FT_Int pitch;
286 FT_Offset size;
287
288 FT_UNUSED( cache );
289
290
291 FT_ASSERT( snode->count <= FTC_SBIT_ITEMS_PER_NODE );
292
293 /* the node itself */
294 size = sizeof ( *snode );
295
296 for ( ; count > 0; count--, sbit++ )
297 {
298 if ( sbit->buffer )
299 {
300 pitch = sbit->pitch;
301 if ( pitch < 0 )
302 pitch = -pitch;
303
304 /* add the size of a given glyph image */
305 size += pitch * sbit->height;
306 }
307 }
308
309 return size;
310 }
311
312
313 #if 0
314
315 FT_LOCAL_DEF( FT_Offset )
316 FTC_SNode_Weight( FTC_SNode snode )
317 {
318 return ftc_snode_weight( FTC_NODE( snode ), NULL );
319 }
320
321 #endif /* 0 */
322
323
324 FT_LOCAL_DEF( FT_Bool )
325 ftc_snode_compare( FTC_Node ftcsnode,
326 FT_Pointer ftcgquery,
327 FTC_Cache cache,
328 FT_Bool* list_changed )
329 {
330 FTC_SNode snode = (FTC_SNode)ftcsnode;
331 FTC_GQuery gquery = (FTC_GQuery)ftcgquery;
332 FTC_GNode gnode = FTC_GNODE( snode );
333 FT_UInt gindex = gquery->gindex;
334 FT_Bool result;
335
336
337 if (list_changed)
338 *list_changed = FALSE;
339 result = FT_BOOL( gnode->family == gquery->family &&
340 (FT_UInt)( gindex - gnode->gindex ) < snode->count );
341 if ( result )
342 {
343 /* check if we need to load the glyph bitmap now */
344 FTC_SBit sbit = snode->sbits + ( gindex - gnode->gindex );
345
346
347 /*
348 * The following code illustrates what to do when you want to
349 * perform operations that may fail within a lookup function.
350 *
351 * Here, we want to load a small bitmap on-demand; we thus
352 * need to call the `ftc_snode_load' function which may return
353 * a non-zero error code only when we are out of memory (OOM).
354 *
355 * The correct thing to do is to use @FTC_CACHE_TRYLOOP and
356 * @FTC_CACHE_TRYLOOP_END in order to implement a retry loop
357 * that is capable of flushing the cache incrementally when
358 * an OOM errors occur.
359 *
360 * However, we need to `lock' the node before this operation to
361 * prevent it from being flushed within the loop.
362 *
363 * When we exit the loop, we unlock the node, then check the `error'
364 * variable. If it is non-zero, this means that the cache was
365 * completely flushed and that no usable memory was found to load
366 * the bitmap.
367 *
368 * We then prefer to return a value of 0 (i.e., NO MATCH). This
369 * ensures that the caller will try to allocate a new node.
370 * This operation consequently _fail_ and the lookup function
371 * returns the appropriate OOM error code.
372 *
373 * Note that `buffer == NULL && width == 255' is a hack used to
374 * tag `unavailable' bitmaps in the array. We should never try
375 * to load these.
376 *
377 */
378
379 if ( sbit->buffer == NULL && sbit->width == 255 )
380 {
381 FT_ULong size;
382 FT_Error error;
383
384
385 ftcsnode->ref_count++; /* lock node to prevent flushing */
386 /* in retry loop */
387
388 FTC_CACHE_TRYLOOP( cache )
389 {
390 error = ftc_snode_load( snode, cache->manager, gindex, &size );
391 }
392 FTC_CACHE_TRYLOOP_END( list_changed );
393
394 ftcsnode->ref_count--; /* unlock the node */
395
396 if ( error )
397 result = 0;
398 else
399 cache->manager->cur_weight += size;
400 }
401 }
402
403 return result;
404 }
405
406
407 #ifdef FTC_INLINE
408
409 FT_LOCAL_DEF( FT_Bool )
410 FTC_SNode_Compare( FTC_SNode snode,
411 FTC_GQuery gquery,
412 FTC_Cache cache,
413 FT_Bool* list_changed )
414 {
415 return ftc_snode_compare( FTC_NODE( snode ), gquery,
416 cache, list_changed );
417 }
418
419 #endif
420
421 /* END */
OLDNEW
« no previous file with comments | « src/cache/ftcsbits.h ('k') | src/cff/cf2arrst.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698