29#define FT_COMPONENT cache
42 ftc_sbit_copy_bitmap( FTC_SBit sbit,
47 FT_Int pitch = bitmap->pitch;
54 size = (FT_ULong)pitch * bitmap->rows;
56 FT_MEM_DUP( sbit->buffer, bitmap->buffer, size );
63 ftc_snode_free( FTC_Node ftcsnode,
66 FTC_SNode snode = (FTC_SNode)ftcsnode;
67 FTC_SBit sbit = snode->sbits;
68 FT_UInt count = snode->count;
69 FT_Memory memory = cache->memory;
72 for ( ; count > 0; sbit++, count-- )
73 FT_FREE( sbit->buffer );
75 FTC_GNode_Done( FTC_GNODE( snode ), cache );
82 FTC_SNode_Free( FTC_SNode snode,
85 ftc_snode_free( FTC_NODE( snode ), cache );
100 ftc_snode_load( FTC_SNode snode,
106 FTC_GNode gnode = FTC_GNODE( snode );
107 FTC_Family family = gnode->family;
110 FTC_SFamilyClass clazz;
113 if ( gindex - gnode->gindex >= snode->count )
115 FT_ERROR((
"ftc_snode_load: invalid glyph index" ));
116 return FT_THROW( Invalid_Argument );
119 sbit = snode->sbits + ( gindex - gnode->gindex );
120 clazz = (FTC_SFamilyClass)family->clazz;
122 error = clazz->family_load_glyph( family, gindex, manager, &face );
128 FT_GlyphSlot slot = face->glyph;
129 FT_Bitmap* bitmap = &slot->bitmap;
130 FT_Pos xadvance, yadvance;
133 if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
135 FT_TRACE0((
"ftc_snode_load:"
136 " glyph loaded didn't return a bitmap\n" ));
144#define CHECK_CHAR( d ) ( temp = (FT_Char)d, (FT_Int) temp == (FT_Int) d )
145#define CHECK_BYTE( d ) ( temp = (FT_Byte)d, (FT_UInt)temp == (FT_UInt)d )
146#define CHECK_SHRT( d ) ( temp = (FT_Short)d, (FT_Int)temp == (FT_Int) d )
149 xadvance = ( slot->advance.x + 32 ) >> 6;
150 yadvance = ( slot->advance.y + 32 ) >> 6;
152 if ( !CHECK_BYTE( bitmap->rows ) ||
153 !CHECK_BYTE( bitmap->width ) ||
154 !CHECK_SHRT( bitmap->pitch ) ||
155 !CHECK_CHAR( slot->bitmap_left ) ||
156 !CHECK_CHAR( slot->bitmap_top ) ||
157 !CHECK_CHAR( xadvance ) ||
158 !CHECK_CHAR( yadvance ) )
160 FT_TRACE2((
"ftc_snode_load:"
161 " glyph too large for small bitmap cache\n"));
165 sbit->width = (FT_Byte)bitmap->width;
166 sbit->height = (FT_Byte)bitmap->rows;
167 sbit->pitch = (FT_Short)bitmap->pitch;
168 sbit->left = (FT_Char)slot->bitmap_left;
169 sbit->top = (FT_Char)slot->bitmap_top;
170 sbit->xadvance = (FT_Char)xadvance;
171 sbit->yadvance = (FT_Char)yadvance;
172 sbit->format = (FT_Byte)bitmap->pixel_mode;
173 sbit->max_grays = (FT_Byte)( bitmap->num_grays - 1 );
175 if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
178 sbit->buffer = bitmap->buffer;
179 slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
184 error = ftc_sbit_copy_bitmap( sbit, bitmap, manager->memory );
189 *asize = (FT_ULong)FT_ABS( sbit->pitch ) * sbit->height;
197 if ( error && FT_ERR_NEQ( error, Out_Of_Memory ) )
212 FT_LOCAL_DEF( FT_Error )
213 FTC_SNode_New( FTC_SNode *psnode,
217 FT_Memory memory = cache->memory;
219 FTC_SNode snode = NULL;
220 FT_UInt gindex = gquery->gindex;
221 FTC_Family family = gquery->family;
223 FTC_SFamilyClass clazz = FTC_CACHE_SFAMILY_CLASS( cache );
228 total = clazz->family_get_count( family, cache->manager );
229 if ( total == 0 || gindex >= total )
231 error = FT_THROW( Invalid_Argument );
235 if ( !FT_QNEW( snode ) )
237 FT_UInt count, start;
240 start = gindex - ( gindex % FTC_SBIT_ITEMS_PER_NODE );
241 count = total - start;
242 if ( count > FTC_SBIT_ITEMS_PER_NODE )
243 count = FTC_SBIT_ITEMS_PER_NODE;
245 FTC_GNode_Init( FTC_GNODE( snode ), start, family );
247 snode->count = count;
248 for ( node_count = 0; node_count < count; node_count++ )
250 snode->sbits[node_count].width = 255;
251 snode->sbits[node_count].height = 0;
252 snode->sbits[node_count].buffer = NULL;
255 error = ftc_snode_load( snode,
261 FTC_SNode_Free( snode, cache );
272 FT_LOCAL_DEF( FT_Error )
273 ftc_snode_new( FTC_Node *ftcpsnode,
274 FT_Pointer ftcgquery,
277 FTC_SNode *psnode = (FTC_SNode*)ftcpsnode;
278 FTC_GQuery gquery = (FTC_GQuery)ftcgquery;
281 return FTC_SNode_New( psnode, gquery, cache );
285 FT_LOCAL_DEF( FT_Offset )
286 ftc_snode_weight( FTC_Node ftcsnode,
289 FTC_SNode snode = (FTC_SNode)ftcsnode;
290 FT_UInt count = snode->count;
291 FTC_SBit sbit = snode->sbits;
298 FT_ASSERT( snode->count <= FTC_SBIT_ITEMS_PER_NODE );
301 size =
sizeof ( *snode );
303 for ( ; count > 0; count--, sbit++ )
312 size += (FT_Offset)pitch * sbit->height;
322 FT_LOCAL_DEF( FT_Offset )
323 FTC_SNode_Weight( FTC_SNode snode )
325 return ftc_snode_weight( FTC_NODE( snode ), NULL );
331 FT_LOCAL_DEF( FT_Bool )
332 ftc_snode_compare( FTC_Node ftcsnode,
333 FT_Pointer ftcgquery,
335 FT_Bool* list_changed )
337 FTC_SNode snode = (FTC_SNode)ftcsnode;
338 FTC_GQuery gquery = (FTC_GQuery)ftcgquery;
339 FTC_GNode gnode = FTC_GNODE( snode );
340 FT_UInt gindex = gquery->gindex;
345 *list_changed = FALSE;
346 result = FT_BOOL( gnode->family == gquery->family &&
347 gindex - gnode->gindex < snode->count );
351 FTC_SBit sbit = snode->sbits + ( gindex - gnode->gindex );
386 if ( !sbit->buffer && sbit->width == 255 )
392 ftcsnode->ref_count++;
395 FTC_CACHE_TRYLOOP( cache )
397 error = ftc_snode_load( snode, cache->manager, gindex, &size );
399 FTC_CACHE_TRYLOOP_END( list_changed )
401 ftcsnode->ref_count--;
406 cache->manager->cur_weight += size;