|
|
|
@ -19,6 +19,7 @@ |
|
|
|
|
#include <ft2build.h> |
|
|
|
|
#include FT_CACHE_H |
|
|
|
|
#include FT_CACHE_SMALL_BITMAPS_H |
|
|
|
|
#include FT_CACHE_INTERNAL_CHUNK_H |
|
|
|
|
#include FT_INTERNAL_OBJECTS_H |
|
|
|
|
#include FT_INTERNAL_DEBUG_H |
|
|
|
|
#include FT_ERRORS_H |
|
|
|
@ -28,23 +29,31 @@ |
|
|
|
|
#include <string.h> /* memcmp() */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define FTC_SBITSET_ELEMENT_COUNT 16 |
|
|
|
|
#define FTC_SBIT_ITEMS_PER_NODE 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* handle to sbit set */ |
|
|
|
|
typedef struct FTC_SBitSetRec_* FTC_SBitSet; |
|
|
|
|
|
|
|
|
|
/* sbit set structure */ |
|
|
|
|
typedef struct FTC_SBitSetRec_ |
|
|
|
|
{ |
|
|
|
|
FTC_ChunkSetRec root; |
|
|
|
|
FTC_ChunkSetRec cset; |
|
|
|
|
FTC_Image_Desc desc; |
|
|
|
|
|
|
|
|
|
} FTC_SBitSetRec, *FTC_SBitSet; |
|
|
|
|
} FTC_SBitSetRec; |
|
|
|
|
|
|
|
|
|
#define FTC_SBIT_SET(x) ((FTC_SBitSet)(x)) |
|
|
|
|
|
|
|
|
|
typedef struct FTC_SBit_CacheRec_ |
|
|
|
|
{ |
|
|
|
|
FTC_Chunk_CacheRec root; |
|
|
|
|
#define FTC_SBIT_SET_MEMORY(x) FTC_CHUNK_SET_MEMORY(&(x)->cset) |
|
|
|
|
|
|
|
|
|
} FTC_SBit_CacheRec; |
|
|
|
|
|
|
|
|
|
typedef struct FTC_SBitQueryRec_ |
|
|
|
|
{ |
|
|
|
|
FTC_ChunkQueryRec chunk; |
|
|
|
|
FTC_Image_Desc desc; |
|
|
|
|
|
|
|
|
|
} FTC_SBitQueryRec, *FTC_SBitQuery; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/ |
|
|
|
@ -57,77 +66,78 @@ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_CALLBACK_DEF( void ) |
|
|
|
|
ftc_sbit_chunk_node_destroy( FTC_ChunkNode node ) |
|
|
|
|
ftc_sbit_node_done( FTC_ChunkNode cnode ) |
|
|
|
|
{ |
|
|
|
|
FTC_ChunkSet cset = node->cset; |
|
|
|
|
FT_Memory memory = cset->memory; |
|
|
|
|
FT_UInt count = node->num_elements; |
|
|
|
|
FTC_SBit sbit = (FTC_SBit)node->elements; |
|
|
|
|
FTC_ChunkSet cset = cnode->cset; |
|
|
|
|
FT_Memory memory = cset->ccache->cache.memory; |
|
|
|
|
FT_UInt count = cnode->item_count; |
|
|
|
|
FTC_SBit sbit = (FTC_SBit) cnode->items; |
|
|
|
|
|
|
|
|
|
if ( sbit ) |
|
|
|
|
{ |
|
|
|
|
for ( ; count > 0; sbit++, count-- ) |
|
|
|
|
FREE( sbit->buffer ); |
|
|
|
|
|
|
|
|
|
for ( ; count > 0; sbit++, count-- ) |
|
|
|
|
FREE( sbit->buffer ); |
|
|
|
|
FREE( cnode->items ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
FREE( node->elements ); |
|
|
|
|
FREE( node ); |
|
|
|
|
ftc_chunk_node_done( cnode ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_CALLBACK_DEF( FT_Error ) |
|
|
|
|
ftc_bitmap_copy( FT_Memory memory, |
|
|
|
|
FT_Bitmap* source, |
|
|
|
|
FTC_SBit target ) |
|
|
|
|
static FT_Error |
|
|
|
|
ftc_sbit_set_bitmap( FTC_SBit sbit, |
|
|
|
|
FT_Bitmap* bitmap, |
|
|
|
|
FT_Memory memory ) |
|
|
|
|
{ |
|
|
|
|
FT_Error error; |
|
|
|
|
FT_Int pitch = source->pitch; |
|
|
|
|
FT_Int pitch = bitmap->pitch; |
|
|
|
|
FT_ULong size; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( pitch < 0 ) |
|
|
|
|
pitch = -pitch; |
|
|
|
|
|
|
|
|
|
size = (FT_ULong)( pitch * source->rows ); |
|
|
|
|
size = (FT_ULong)( pitch * bitmap->rows ); |
|
|
|
|
|
|
|
|
|
if ( !ALLOC( target->buffer, size ) ) |
|
|
|
|
MEM_Copy( target->buffer, source->buffer, size ); |
|
|
|
|
if ( !ALLOC( sbit->buffer, size ) ) |
|
|
|
|
MEM_Copy( sbit->buffer, bitmap->buffer, size ); |
|
|
|
|
|
|
|
|
|
return error; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_CALLBACK_DEF( FT_Error ) |
|
|
|
|
ftc_sbit_chunk_node_new( FTC_ChunkSet cset, |
|
|
|
|
FT_UInt index, |
|
|
|
|
FTC_ChunkNode *anode ) |
|
|
|
|
|
|
|
|
|
static FT_Error |
|
|
|
|
ftc_sbit_node_load( FTC_ChunkNode cnode, |
|
|
|
|
FT_UInt gindex, |
|
|
|
|
FT_ULong *asize ) |
|
|
|
|
{ |
|
|
|
|
FT_Error error; |
|
|
|
|
FT_Memory memory = cset->memory; |
|
|
|
|
FTC_SBitSet sbitset = (FTC_SBitSet)cset; |
|
|
|
|
FTC_ChunkNode node = 0; |
|
|
|
|
FTC_ChunkSet cset = cnode->cset; |
|
|
|
|
FTC_SBitSet sbitset = FTC_SBIT_SET(cset); |
|
|
|
|
FT_Memory memory = FTC_SBIT_SET_MEMORY(sbitset); |
|
|
|
|
FT_Face face; |
|
|
|
|
FT_Size size; |
|
|
|
|
|
|
|
|
|
FTC_SBit sbit; |
|
|
|
|
|
|
|
|
|
/* allocate node */ |
|
|
|
|
if ( ALLOC( node, sizeof ( *node ) ) ) |
|
|
|
|
goto Exit; |
|
|
|
|
if ( gindex < (FT_UInt)cnode->item_start || |
|
|
|
|
gindex >= (FT_UInt)cnode->item_start + cnode->item_count ) |
|
|
|
|
{ |
|
|
|
|
FT_ERROR(( "FreeType.cache.sbit_load: invalid glyph index" )); |
|
|
|
|
return FTC_Err_Invalid_Argument; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* initialize its inner fields */ |
|
|
|
|
error = FTC_ChunkNode_Init( node, cset, index, 1 ); |
|
|
|
|
if ( error ) |
|
|
|
|
goto Exit; |
|
|
|
|
sbit = (FTC_SBit)cnode->items + (gindex - cnode->item_start); |
|
|
|
|
|
|
|
|
|
/* we will now load all glyph images for this chunk */ |
|
|
|
|
error = FTC_Manager_Lookup_Size( cset->manager, |
|
|
|
|
error = FTC_Manager_Lookup_Size( cset->ccache->cache.manager, |
|
|
|
|
&sbitset->desc.font, |
|
|
|
|
&face, &size ); |
|
|
|
|
if ( !error ) |
|
|
|
|
{ |
|
|
|
|
FT_UInt glyph_index = index * cset->element_count; |
|
|
|
|
FT_UInt load_flags = FT_LOAD_DEFAULT; |
|
|
|
|
FT_UInt image_type = sbitset->desc.image_type; |
|
|
|
|
FT_UInt count = node->num_elements; |
|
|
|
|
FTC_SBit sbit = (FTC_SBit)node->elements; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* determine load flags, depending on the font description's */ |
|
|
|
@ -144,7 +154,7 @@ |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
FT_ERROR(( "FTC_SBit_Cache: cannot load scalable glyphs in an" |
|
|
|
|
FT_ERROR(( "FreeType.cache.sbit_load: cannot load scalable glyphs in an" |
|
|
|
|
" sbit cache, please check your arguments!\n" )); |
|
|
|
|
error = FTC_Err_Invalid_Argument; |
|
|
|
|
goto Exit; |
|
|
|
@ -159,102 +169,126 @@ |
|
|
|
|
if ( image_type & ftc_image_flag_autohinted ) |
|
|
|
|
load_flags |= FT_LOAD_FORCE_AUTOHINT; |
|
|
|
|
|
|
|
|
|
/* load a chunk of small bitmaps in a row */ |
|
|
|
|
for ( ; count > 0; count--, glyph_index++, sbit++ ) |
|
|
|
|
{ |
|
|
|
|
/* by default, indicates a `missing' glyph */ |
|
|
|
|
sbit->buffer = 0; |
|
|
|
|
/* by default, indicates a `missing' glyph */ |
|
|
|
|
sbit->buffer = 0; |
|
|
|
|
|
|
|
|
|
error = FT_Load_Glyph( face, glyph_index, load_flags ); |
|
|
|
|
if ( !error ) |
|
|
|
|
{ |
|
|
|
|
FT_Int temp; |
|
|
|
|
FT_GlyphSlot slot = face->glyph; |
|
|
|
|
FT_Bitmap* bitmap = &slot->bitmap; |
|
|
|
|
FT_Int xadvance, yadvance; |
|
|
|
|
error = FT_Load_Glyph( face, gindex, load_flags ); |
|
|
|
|
if ( !error ) |
|
|
|
|
{ |
|
|
|
|
FT_Int temp; |
|
|
|
|
FT_GlyphSlot slot = face->glyph; |
|
|
|
|
FT_Bitmap* bitmap = &slot->bitmap; |
|
|
|
|
FT_Int xadvance, yadvance; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* check that our values fit into 8-bit containers! */ |
|
|
|
|
/* If this is not the case, our bitmap is too large */ |
|
|
|
|
/* and we will leave it as `missing' with sbit.buffer = 0 */ |
|
|
|
|
/* check that our values fit into 8-bit containers! */ |
|
|
|
|
/* If this is not the case, our bitmap is too large */ |
|
|
|
|
/* and we will leave it as `missing' with sbit.buffer = 0 */ |
|
|
|
|
|
|
|
|
|
#define CHECK_CHAR( d ) ( temp = (FT_Char)d, temp == d ) |
|
|
|
|
#define CHECK_BYTE( d ) ( temp = (FT_Byte)d, temp == d ) |
|
|
|
|
|
|
|
|
|
/* XXX: FIXME: add support for vertical layouts maybe */ |
|
|
|
|
/* XXX: FIXME: add support for vertical layouts maybe */ |
|
|
|
|
|
|
|
|
|
/* horizontal advance in pixels */ |
|
|
|
|
xadvance = ( slot->metrics.horiAdvance + 32 ) >> 6; |
|
|
|
|
yadvance = ( slot->metrics.vertAdvance + 32 ) >> 6; |
|
|
|
|
/* horizontal advance in pixels */ |
|
|
|
|
xadvance = ( slot->metrics.horiAdvance + 32 ) >> 6; |
|
|
|
|
yadvance = ( slot->metrics.vertAdvance + 32 ) >> 6; |
|
|
|
|
|
|
|
|
|
if ( CHECK_BYTE( bitmap->rows ) && |
|
|
|
|
CHECK_BYTE( bitmap->width ) && |
|
|
|
|
CHECK_CHAR( bitmap->pitch ) && |
|
|
|
|
CHECK_CHAR( slot->bitmap_left ) && |
|
|
|
|
CHECK_CHAR( slot->bitmap_top ) && |
|
|
|
|
CHECK_CHAR( xadvance ) && |
|
|
|
|
CHECK_CHAR( yadvance ) ) |
|
|
|
|
if ( CHECK_BYTE( bitmap->rows ) && |
|
|
|
|
CHECK_BYTE( bitmap->width ) && |
|
|
|
|
CHECK_CHAR( bitmap->pitch ) && |
|
|
|
|
CHECK_CHAR( slot->bitmap_left ) && |
|
|
|
|
CHECK_CHAR( slot->bitmap_top ) && |
|
|
|
|
CHECK_CHAR( xadvance ) && |
|
|
|
|
CHECK_CHAR( yadvance ) ) |
|
|
|
|
{ |
|
|
|
|
sbit->width = (FT_Byte) bitmap->width; |
|
|
|
|
sbit->height = (FT_Byte) bitmap->rows; |
|
|
|
|
sbit->pitch = (FT_Char) bitmap->pitch; |
|
|
|
|
sbit->left = (FT_Char) slot->bitmap_left; |
|
|
|
|
sbit->top = (FT_Char) slot->bitmap_top; |
|
|
|
|
sbit->xadvance = (FT_Char) xadvance; |
|
|
|
|
sbit->yadvance = (FT_Char) yadvance; |
|
|
|
|
sbit->format = (FT_Byte) bitmap->pixel_mode; |
|
|
|
|
|
|
|
|
|
/* grab the bitmap when possible - this is a hack !! */ |
|
|
|
|
if ( slot->flags & ft_glyph_own_bitmap ) |
|
|
|
|
{ |
|
|
|
|
sbit->width = (FT_Byte)bitmap->width; |
|
|
|
|
sbit->height = (FT_Byte)bitmap->rows; |
|
|
|
|
sbit->pitch = (FT_Char)bitmap->pitch; |
|
|
|
|
sbit->left = (FT_Char)slot->bitmap_left; |
|
|
|
|
sbit->top = (FT_Char)slot->bitmap_top; |
|
|
|
|
sbit->xadvance = (FT_Char)xadvance; |
|
|
|
|
sbit->yadvance = (FT_Char)yadvance; |
|
|
|
|
sbit->format = (FT_Byte)bitmap->pixel_mode; |
|
|
|
|
|
|
|
|
|
/* grab the bitmap when possible */ |
|
|
|
|
if ( slot->flags & ft_glyph_own_bitmap ) |
|
|
|
|
{ |
|
|
|
|
slot->flags &= ~ft_glyph_own_bitmap; |
|
|
|
|
sbit->buffer = bitmap->buffer; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
/* copy the bitmap into a new buffer -- ignore error */ |
|
|
|
|
ftc_bitmap_copy( memory, bitmap, sbit ); |
|
|
|
|
} |
|
|
|
|
slot->flags &= ~ft_glyph_own_bitmap; |
|
|
|
|
sbit->buffer = bitmap->buffer; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
/* copy the bitmap into a new buffer -- ignore error */ |
|
|
|
|
error = ftc_sbit_set_bitmap( sbit, bitmap, memory ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* now, compute size */ |
|
|
|
|
if ( asize ) |
|
|
|
|
*asize = sizeof( FTC_SBitRec ) + ABS(sbit->pitch) * sbit->height; |
|
|
|
|
|
|
|
|
|
} /* glyph dimensions ok */ |
|
|
|
|
|
|
|
|
|
} /* glyph loading successful */ |
|
|
|
|
|
|
|
|
|
/* ignore the errors that might have occurred -- */ |
|
|
|
|
/* we recognize unloaded glyphs with `sbit.buffer == 0' */ |
|
|
|
|
error = 0; |
|
|
|
|
/* and 'width == 255', 'height == 0' */ |
|
|
|
|
/* */ |
|
|
|
|
if ( error ) |
|
|
|
|
{ |
|
|
|
|
sbit->width = 255; |
|
|
|
|
error = 0; |
|
|
|
|
/* sbit->buffer == NULL too !! */ |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Exit: |
|
|
|
|
if ( error && node ) |
|
|
|
|
return error; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_CALLBACK_DEF( FT_Error ) |
|
|
|
|
ftc_sbit_node_init( FTC_ChunkNode cnode, |
|
|
|
|
FTC_ChunkQuery query ) |
|
|
|
|
{ |
|
|
|
|
FT_Error error; |
|
|
|
|
|
|
|
|
|
error = ftc_chunk_node_init( cnode, |
|
|
|
|
query->cset, |
|
|
|
|
query->gindex, |
|
|
|
|
TRUE ); |
|
|
|
|
if ( !error ) |
|
|
|
|
{ |
|
|
|
|
FREE( node->elements ); |
|
|
|
|
FREE( node ); |
|
|
|
|
} |
|
|
|
|
error = ftc_sbit_node_load( cnode, query->gindex, NULL ); |
|
|
|
|
|
|
|
|
|
*anode = node; |
|
|
|
|
if ( error ) |
|
|
|
|
ftc_chunk_node_done( cnode ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return error; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* this function is important because it is both part of */ |
|
|
|
|
/* an FTC_ChunkSet_Class and an FTC_CacheNode_Class */ |
|
|
|
|
/* */ |
|
|
|
|
FT_CALLBACK_DEF( FT_ULong ) |
|
|
|
|
ftc_sbit_chunk_node_size( FTC_ChunkNode node ) |
|
|
|
|
ftc_sbit_node_weight( FTC_ChunkNode cnode ) |
|
|
|
|
{ |
|
|
|
|
FT_ULong size; |
|
|
|
|
FTC_ChunkSet cset = node->cset; |
|
|
|
|
FT_UInt count = node->num_elements; |
|
|
|
|
FTC_ChunkSet cset = cnode->cset; |
|
|
|
|
FT_UInt count = cnode->item_count; |
|
|
|
|
FT_Int pitch; |
|
|
|
|
FTC_SBit sbit = (FTC_SBit)node->elements; |
|
|
|
|
FTC_SBit sbit = (FTC_SBit) cnode->items; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* the node itself */ |
|
|
|
|
size = sizeof ( *node ); |
|
|
|
|
size = sizeof ( *cnode ); |
|
|
|
|
|
|
|
|
|
/* the sbit records */ |
|
|
|
|
size += cset->element_count * sizeof ( FTC_SBitRec ); |
|
|
|
|
size += cnode->item_count * sizeof ( FTC_SBitRec ); |
|
|
|
|
|
|
|
|
|
for ( ; count > 0; count--, sbit++ ) |
|
|
|
|
{ |
|
|
|
@ -273,6 +307,34 @@ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_CALLBACK_DEF( FT_Bool ) |
|
|
|
|
ftc_sbit_node_compare( FTC_ChunkNode cnode, |
|
|
|
|
FTC_SBitQuery query, |
|
|
|
|
FTC_Cache cache ) |
|
|
|
|
{ |
|
|
|
|
FTC_ChunkQuery creq = &query->chunk; |
|
|
|
|
FT_UInt gindex = query->chunk.gindex; |
|
|
|
|
FT_UInt offset = (FT_UInt)(gindex - cnode->item_start); |
|
|
|
|
FT_Bool result; |
|
|
|
|
|
|
|
|
|
result = FT_BOOL( offset < (FT_UInt)cnode->item_count && |
|
|
|
|
creq->cset == cnode->cset ); |
|
|
|
|
if ( result ) |
|
|
|
|
{ |
|
|
|
|
/* check if we need to load the glyph bitmap now */ |
|
|
|
|
FTC_SBit sbit = (FTC_SBit)cnode->items + offset; |
|
|
|
|
|
|
|
|
|
if ( sbit->buffer == NULL && sbit->width != 255 ) |
|
|
|
|
{ |
|
|
|
|
FT_ULong size; |
|
|
|
|
ftc_sbit_node_load( cnode, gindex, &size ); |
|
|
|
|
cache->manager->cur_weight += size; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/***** *****/ |
|
|
|
@ -283,60 +345,74 @@ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_CALLBACK_DEF( FT_Error ) |
|
|
|
|
ftc_sbit_chunk_set_sizes( FTC_ChunkSet cset, |
|
|
|
|
FTC_Image_Desc* desc ) |
|
|
|
|
ftc_sbit_set_init( FTC_SBitSet sset, |
|
|
|
|
FTC_SBitQuery query, |
|
|
|
|
FT_LruList lru ) |
|
|
|
|
{ |
|
|
|
|
FT_Error error; |
|
|
|
|
FT_Face face; |
|
|
|
|
|
|
|
|
|
FTC_ChunkCache ccache = lru->user_data; |
|
|
|
|
FTC_Manager manager = ccache->cache.manager; |
|
|
|
|
FT_Error error; |
|
|
|
|
FT_Face face; |
|
|
|
|
|
|
|
|
|
cset->element_count = FTC_SBITSET_ELEMENT_COUNT; |
|
|
|
|
cset->element_size = sizeof ( FTC_SBitRec ); |
|
|
|
|
sset->desc = query->desc; |
|
|
|
|
|
|
|
|
|
/* lookup the FT_Face to obtain the number of glyphs */ |
|
|
|
|
error = FTC_Manager_Lookup_Face( cset->manager, |
|
|
|
|
desc->font.face_id, &face ); |
|
|
|
|
/* we need to compute "cquery.item_total" now */ |
|
|
|
|
error = FTC_Manager_Lookup_Face( manager, |
|
|
|
|
query->desc.font.face_id, |
|
|
|
|
&face ); |
|
|
|
|
if ( !error ) |
|
|
|
|
cset->element_max = face->num_glyphs; |
|
|
|
|
{ |
|
|
|
|
ftc_chunk_set_init( FTC_CHUNK_SET(sset), |
|
|
|
|
sizeof( FTC_SBitRec ), |
|
|
|
|
FTC_SBIT_ITEMS_PER_NODE, |
|
|
|
|
face->num_glyphs, |
|
|
|
|
FTC_CHUNK_CACHE(lru->user_data) ); |
|
|
|
|
|
|
|
|
|
/* now compute hash from description - this is _very_ important */ |
|
|
|
|
/* for good performance.. */ |
|
|
|
|
sset->cset.hash = FTC_IMAGE_DESC_HASH( &sset->desc ); |
|
|
|
|
query->chunk.cset = &sset->cset; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return error; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_CALLBACK_DEF( FT_Error ) |
|
|
|
|
ftc_sbit_chunk_set_init( FTC_SBitSet sset, |
|
|
|
|
FTC_Image_Desc* type ) |
|
|
|
|
{ |
|
|
|
|
sset->desc = *type; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_CALLBACK_DEF( FT_Bool ) |
|
|
|
|
ftc_sbit_chunk_set_compare( FTC_SBitSet sset, |
|
|
|
|
FTC_Image_Desc* type ) |
|
|
|
|
ftc_sbit_set_compare( FTC_SBitSet sset, |
|
|
|
|
FTC_SBitQuery query ) |
|
|
|
|
{ |
|
|
|
|
return FT_BOOL( !memcmp( &sset->desc, type, sizeof ( *type ) ) ); |
|
|
|
|
FT_Bool result; |
|
|
|
|
|
|
|
|
|
/* we need to set the "cquery.cset" field or our query for */ |
|
|
|
|
/* faster glyph comparisons in ftc_sbit_node_compare.. */ |
|
|
|
|
/* */ |
|
|
|
|
result = FT_BOOL( FTC_IMAGE_DESC_COMPARE( &sset->desc, &query->desc ) ); |
|
|
|
|
if ( result ) |
|
|
|
|
query->chunk.cset = &sset->cset; |
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_CALLBACK_TABLE_DEF |
|
|
|
|
const FTC_ChunkSet_Class ftc_sbit_chunk_set_class = |
|
|
|
|
const FT_LruList_ClassRec ftc_sbit_set_class = |
|
|
|
|
{ |
|
|
|
|
sizeof( FTC_SBitSetRec ), |
|
|
|
|
|
|
|
|
|
(FTC_ChunkSet_InitFunc) ftc_sbit_chunk_set_init, |
|
|
|
|
(FTC_ChunkSet_DoneFunc) 0, |
|
|
|
|
(FTC_ChunkSet_CompareFunc) ftc_sbit_chunk_set_compare, |
|
|
|
|
(FTC_ChunkSet_SizesFunc) ftc_sbit_chunk_set_sizes, |
|
|
|
|
sizeof( FT_LruListRec ), |
|
|
|
|
(FT_LruList_InitFunc) NULL, |
|
|
|
|
(FT_LruList_DoneFunc) NULL, |
|
|
|
|
|
|
|
|
|
(FTC_ChunkSet_NewNodeFunc) ftc_sbit_chunk_node_new, |
|
|
|
|
(FTC_ChunkSet_SizeNodeFunc) ftc_sbit_chunk_node_size, |
|
|
|
|
(FTC_ChunkSet_DestroyNodeFunc)ftc_sbit_chunk_node_destroy |
|
|
|
|
sizeof( FTC_SBitSetRec ), |
|
|
|
|
(FT_LruNode_InitFunc) ftc_sbit_set_init, |
|
|
|
|
(FT_LruNode_DoneFunc) ftc_chunk_set_done, |
|
|
|
|
(FT_LruNode_FlushFunc) NULL, |
|
|
|
|
(FT_LruNode_CompareFunc) ftc_sbit_set_compare, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/***** *****/ |
|
|
|
@ -346,15 +422,25 @@ |
|
|
|
|
/*************************************************************************/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_CALLBACK_DEF( FT_Error ) |
|
|
|
|
ftc_sbit_cache_init( FTC_SBit_Cache scache ) |
|
|
|
|
{ |
|
|
|
|
return ftc_chunk_cache_init( FTC_CHUNK_CACHE(scache), |
|
|
|
|
&ftc_sbit_set_class ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
FT_CALLBACK_TABLE_DEF |
|
|
|
|
const FTC_Chunk_Cache_Class ftc_sbit_cache_class = |
|
|
|
|
const FTC_Cache_ClassRec ftc_sbit_cache_class = |
|
|
|
|
{ |
|
|
|
|
{ |
|
|
|
|
sizeof( FTC_SBit_CacheRec ), |
|
|
|
|
(FTC_Cache_InitFunc)FTC_Chunk_Cache_Init, |
|
|
|
|
(FTC_Cache_DoneFunc)FTC_Chunk_Cache_Done |
|
|
|
|
}, |
|
|
|
|
(FTC_ChunkSet_Class*)&ftc_sbit_chunk_set_class |
|
|
|
|
sizeof( FTC_ChunkCacheRec ), |
|
|
|
|
(FTC_Cache_InitFunc) ftc_sbit_cache_init, |
|
|
|
|
(FTC_Cache_DoneFunc) ftc_chunk_cache_done, |
|
|
|
|
|
|
|
|
|
sizeof( FTC_ChunkNodeRec ), |
|
|
|
|
(FTC_Node_InitFunc) ftc_sbit_node_init, |
|
|
|
|
(FTC_Node_WeightFunc) ftc_sbit_node_weight, |
|
|
|
|
(FTC_Node_CompareFunc) ftc_sbit_node_compare, |
|
|
|
|
(FTC_Node_DoneFunc) ftc_sbit_node_done |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -366,8 +452,8 @@ |
|
|
|
|
{ |
|
|
|
|
return FTC_Manager_Register_Cache( |
|
|
|
|
manager, |
|
|
|
|
(FTC_Cache_Class*)&ftc_sbit_cache_class, |
|
|
|
|
(FTC_Cache*)acache ); |
|
|
|
|
&ftc_sbit_cache_class, |
|
|
|
|
(FTC_Cache*) acache ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -379,21 +465,27 @@ |
|
|
|
|
FT_UInt gindex, |
|
|
|
|
FTC_SBit *ansbit ) |
|
|
|
|
{ |
|
|
|
|
FT_Error error; |
|
|
|
|
FTC_ChunkNode node; |
|
|
|
|
FT_UInt cindex; |
|
|
|
|
FT_Error error; |
|
|
|
|
FTC_ChunkCache ccache = (FTC_ChunkCache) cache; |
|
|
|
|
FTC_ChunkNode node; |
|
|
|
|
FTC_SBitQueryRec query; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* argument checks delayed to FTC_Chunk_Cache_Lookup */ |
|
|
|
|
if ( !ansbit ) |
|
|
|
|
return FTC_Err_Invalid_Argument; |
|
|
|
|
|
|
|
|
|
*ansbit = 0; |
|
|
|
|
error = FTC_Chunk_Cache_Lookup( &cache->root, desc, gindex, |
|
|
|
|
&node, &cindex ); |
|
|
|
|
if ( !error ) |
|
|
|
|
*ansbit = (FTC_SBit)node->elements + cindex; |
|
|
|
|
*ansbit = NULL; |
|
|
|
|
|
|
|
|
|
query.chunk.gindex = gindex; |
|
|
|
|
query.chunk.cset = NULL; |
|
|
|
|
query.desc = *desc; |
|
|
|
|
|
|
|
|
|
error = ftc_chunk_cache_lookup( ccache, &query.chunk, &node ); |
|
|
|
|
if ( !error ) |
|
|
|
|
{ |
|
|
|
|
*ansbit = (FTC_SBit) node->items + (gindex - node->item_start); |
|
|
|
|
} |
|
|
|
|
return error; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|