diff -r f3840de881bd -r 915436ff64ab misc/libfreetype/src/cache/ftcsbits.c --- a/misc/libfreetype/src/cache/ftcsbits.c Thu Jul 25 23:16:06 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,421 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcsbits.c */ -/* */ -/* FreeType sbits manager (body). */ -/* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010, 2011 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include -#include FT_CACHE_H -#include "ftcsbits.h" -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_ERRORS_H - -#include "ftccback.h" -#include "ftcerror.h" - -#undef FT_COMPONENT -#define FT_COMPONENT trace_cache - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** SBIT CACHE NODES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - static FT_Error - ftc_sbit_copy_bitmap( FTC_SBit sbit, - FT_Bitmap* bitmap, - FT_Memory memory ) - { - FT_Error error; - FT_Int pitch = bitmap->pitch; - FT_ULong size; - - - if ( pitch < 0 ) - pitch = -pitch; - - size = (FT_ULong)( pitch * bitmap->rows ); - - if ( !FT_ALLOC( sbit->buffer, size ) ) - FT_MEM_COPY( sbit->buffer, bitmap->buffer, size ); - - return error; - } - - - FT_LOCAL_DEF( void ) - ftc_snode_free( FTC_Node ftcsnode, - FTC_Cache cache ) - { - FTC_SNode snode = (FTC_SNode)ftcsnode; - FTC_SBit sbit = snode->sbits; - FT_UInt count = snode->count; - FT_Memory memory = cache->memory; - - - for ( ; count > 0; sbit++, count-- ) - FT_FREE( sbit->buffer ); - - FTC_GNode_Done( FTC_GNODE( snode ), cache ); - - FT_FREE( snode ); - } - - - FT_LOCAL_DEF( void ) - FTC_SNode_Free( FTC_SNode snode, - FTC_Cache cache ) - { - ftc_snode_free( FTC_NODE( snode ), cache ); - } - - - /* - * This function tries to load a small bitmap within a given FTC_SNode. - * Note that it returns a non-zero error code _only_ in the case of - * out-of-memory condition. For all other errors (e.g., corresponding - * to a bad font file), this function will mark the sbit as `unavailable' - * and return a value of 0. - * - * You should also read the comment within the @ftc_snode_compare - * function below to see how out-of-memory is handled during a lookup. - */ - static FT_Error - ftc_snode_load( FTC_SNode snode, - FTC_Manager manager, - FT_UInt gindex, - FT_ULong *asize ) - { - FT_Error error; - FTC_GNode gnode = FTC_GNODE( snode ); - FTC_Family family = gnode->family; - FT_Memory memory = manager->memory; - FT_Face face; - FTC_SBit sbit; - FTC_SFamilyClass clazz; - - - if ( (FT_UInt)(gindex - gnode->gindex) >= snode->count ) - { - FT_ERROR(( "ftc_snode_load: invalid glyph index" )); - return FTC_Err_Invalid_Argument; - } - - sbit = snode->sbits + ( gindex - gnode->gindex ); - clazz = (FTC_SFamilyClass)family->clazz; - - sbit->buffer = 0; - - error = clazz->family_load_glyph( family, gindex, manager, &face ); - if ( error ) - goto BadGlyph; - - { - FT_Int temp; - FT_GlyphSlot slot = face->glyph; - FT_Bitmap* bitmap = &slot->bitmap; - FT_Pos xadvance, yadvance; /* FT_GlyphSlot->advance.{x|y} */ - - - if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) - { - FT_TRACE0(( "ftc_snode_load:" - " glyph loaded didn't return a bitmap\n" )); - goto BadGlyph; - } - - /* 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 ) - - /* horizontal advance in pixels */ - xadvance = ( slot->advance.x + 32 ) >> 6; - yadvance = ( slot->advance.y + 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 ) ) - { - FT_TRACE2(( "ftc_snode_load:" - " glyph too large for small bitmap cache\n")); - goto BadGlyph; - } - - 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; - sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1); - - /* copy the bitmap into a new buffer -- ignore error */ - error = ftc_sbit_copy_bitmap( sbit, bitmap, memory ); - - /* now, compute size */ - if ( asize ) - *asize = FT_ABS( sbit->pitch ) * sbit->height; - - } /* glyph loading successful */ - - /* ignore the errors that might have occurred -- */ - /* we mark unloaded glyphs with `sbit.buffer == 0' */ - /* and `width == 255', `height == 0' */ - /* */ - if ( error && error != FTC_Err_Out_Of_Memory ) - { - BadGlyph: - sbit->width = 255; - sbit->height = 0; - sbit->buffer = NULL; - error = FTC_Err_Ok; - if ( asize ) - *asize = 0; - } - - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - FTC_SNode_New( FTC_SNode *psnode, - FTC_GQuery gquery, - FTC_Cache cache ) - { - FT_Memory memory = cache->memory; - FT_Error error; - FTC_SNode snode = NULL; - FT_UInt gindex = gquery->gindex; - FTC_Family family = gquery->family; - - FTC_SFamilyClass clazz = FTC_CACHE__SFAMILY_CLASS( cache ); - FT_UInt total; - FT_UInt node_count; - - - total = clazz->family_get_count( family, cache->manager ); - if ( total == 0 || gindex >= total ) - { - error = FTC_Err_Invalid_Argument; - goto Exit; - } - - if ( !FT_NEW( snode ) ) - { - FT_UInt count, start; - - - start = gindex - ( gindex % FTC_SBIT_ITEMS_PER_NODE ); - count = total - start; - if ( count > FTC_SBIT_ITEMS_PER_NODE ) - count = FTC_SBIT_ITEMS_PER_NODE; - - FTC_GNode_Init( FTC_GNODE( snode ), start, family ); - - snode->count = count; - for ( node_count = 0; node_count < count; node_count++ ) - { - snode->sbits[node_count].width = 255; - } - - error = ftc_snode_load( snode, - cache->manager, - gindex, - NULL ); - if ( error ) - { - FTC_SNode_Free( snode, cache ); - snode = NULL; - } - } - - Exit: - *psnode = snode; - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - ftc_snode_new( FTC_Node *ftcpsnode, - FT_Pointer ftcgquery, - FTC_Cache cache ) - { - FTC_SNode *psnode = (FTC_SNode*)ftcpsnode; - FTC_GQuery gquery = (FTC_GQuery)ftcgquery; - - - return FTC_SNode_New( psnode, gquery, cache ); - } - - - FT_LOCAL_DEF( FT_Offset ) - ftc_snode_weight( FTC_Node ftcsnode, - FTC_Cache cache ) - { - FTC_SNode snode = (FTC_SNode)ftcsnode; - FT_UInt count = snode->count; - FTC_SBit sbit = snode->sbits; - FT_Int pitch; - FT_Offset size; - - FT_UNUSED( cache ); - - - FT_ASSERT( snode->count <= FTC_SBIT_ITEMS_PER_NODE ); - - /* the node itself */ - size = sizeof ( *snode ); - - for ( ; count > 0; count--, sbit++ ) - { - if ( sbit->buffer ) - { - pitch = sbit->pitch; - if ( pitch < 0 ) - pitch = -pitch; - - /* add the size of a given glyph image */ - size += pitch * sbit->height; - } - } - - return size; - } - - -#if 0 - - FT_LOCAL_DEF( FT_Offset ) - FTC_SNode_Weight( FTC_SNode snode ) - { - return ftc_snode_weight( FTC_NODE( snode ), NULL ); - } - -#endif /* 0 */ - - - FT_LOCAL_DEF( FT_Bool ) - ftc_snode_compare( FTC_Node ftcsnode, - FT_Pointer ftcgquery, - FTC_Cache cache, - FT_Bool* list_changed ) - { - FTC_SNode snode = (FTC_SNode)ftcsnode; - FTC_GQuery gquery = (FTC_GQuery)ftcgquery; - FTC_GNode gnode = FTC_GNODE( snode ); - FT_UInt gindex = gquery->gindex; - FT_Bool result; - - - if (list_changed) - *list_changed = FALSE; - result = FT_BOOL( gnode->family == gquery->family && - (FT_UInt)( gindex - gnode->gindex ) < snode->count ); - if ( result ) - { - /* check if we need to load the glyph bitmap now */ - FTC_SBit sbit = snode->sbits + ( gindex - gnode->gindex ); - - - /* - * The following code illustrates what to do when you want to - * perform operations that may fail within a lookup function. - * - * Here, we want to load a small bitmap on-demand; we thus - * need to call the `ftc_snode_load' function which may return - * a non-zero error code only when we are out of memory (OOM). - * - * The correct thing to do is to use @FTC_CACHE_TRYLOOP and - * @FTC_CACHE_TRYLOOP_END in order to implement a retry loop - * that is capable of flushing the cache incrementally when - * an OOM errors occur. - * - * However, we need to `lock' the node before this operation to - * prevent it from being flushed within the loop. - * - * When we exit the loop, we unlock the node, then check the `error' - * variable. If it is non-zero, this means that the cache was - * completely flushed and that no usable memory was found to load - * the bitmap. - * - * We then prefer to return a value of 0 (i.e., NO MATCH). This - * ensures that the caller will try to allocate a new node. - * This operation consequently _fail_ and the lookup function - * returns the appropriate OOM error code. - * - * Note that `buffer == NULL && width == 255' is a hack used to - * tag `unavailable' bitmaps in the array. We should never try - * to load these. - * - */ - - if ( sbit->buffer == NULL && sbit->width == 255 ) - { - FT_ULong size; - FT_Error error; - - - ftcsnode->ref_count++; /* lock node to prevent flushing */ - /* in retry loop */ - - FTC_CACHE_TRYLOOP( cache ) - { - error = ftc_snode_load( snode, cache->manager, gindex, &size ); - } - FTC_CACHE_TRYLOOP_END( list_changed ); - - ftcsnode->ref_count--; /* unlock the node */ - - if ( error ) - result = 0; - else - cache->manager->cur_weight += size; - } - } - - return result; - } - - -#ifdef FTC_INLINE - - FT_LOCAL_DEF( FT_Bool ) - FTC_SNode_Compare( FTC_SNode snode, - FTC_GQuery gquery, - FTC_Cache cache, - FT_Bool* list_changed ) - { - return ftc_snode_compare( FTC_NODE( snode ), gquery, - cache, list_changed ); - } - -#endif - -/* END */