diff options
author | Werner Lemberg <wl@gnu.org> | 2005-05-23 21:33:02 +0000 |
---|---|---|
committer | Werner Lemberg <wl@gnu.org> | 2005-05-23 21:33:02 +0000 |
commit | 92aa527a1ce0f427c5e2446fbe12011b4a307806 (patch) | |
tree | cfb6d5cb7975ce8e74d5c8d82d820338db0ffbe6 | |
parent | f9e05597780eae8db99a238319bbbee06f7cf738 (diff) | |
download | freetype2-92aa527a1ce0f427c5e2446fbe12011b4a307806.tar.gz |
* builds/amiga/makefile.os4 (WARNINGS), builds/compiler/gcc-dev.mk
(CFLAGS), builds/compiler/gcc.mk (CFLAGS): Remove
-fno-strict-aliasing.
Say you have `(Foo*)x' and want to assign, pass, or return it as
`(Bar*)'. If you simply say `x' or `(Bar*)x', then the C compiler
would warn you that type casting incompatible pointer types breaks
strict-aliasing. The solution is to cast to `(void*)' instead which
is the generic pointer type, so the compiler knows that it should
make no strict-aliasing assumption on `x'. But the problem with
`(void*)x' is that seems like in C++, unlike C, `void*' is not a
generic pointer type and assigning `void*' to `Bar*' without a cast
causes an error. The solution is to cast to `Bar*' too, with
`(Bar*)(void*)x' as the result -- this is what the patch does.
* include/freetype/cache/ftccache.h (FTC_CACHE_LOOKUP_CMP),
include/freetype/cache/ftcmru.h (FTC_MRULIST_LOOKUP_CMP): Remove
cast on lvalue, use a temporary pointer instead.
Cast temporarily to (void*) to not break strict aliasing.
* include/freetype/internal/ftmemory.h (FT_MEM_ALLOC,
FT_MEM_REALLOC, FT_MEM_QALLOC, FT_MEM_QREALLOC, FT_MEM_FREE),
src/base/ftglyph.c (FT_Glyph_To_Bitmap): Cast temporarily to (void*)
to not break strict aliasing.
* src/base/ftinit.c (FT_USE_MODULE): Fix wrong type information.
* builds/unix/configure.ac (XX_CFLAGS): Remove -fno-strict-aliasing.
* src/sfnt/rules.mk (SFNT_DRV_SRC): Don't include ttsbit0.c --
it is currently loaded from ttsbit.c.
Other formatting.
-rw-r--r-- | ChangeLog | 47 | ||||
-rw-r--r-- | builds/amiga/makefile.os4 | 2 | ||||
-rw-r--r-- | builds/compiler/gcc-dev.mk | 3 | ||||
-rw-r--r-- | builds/compiler/gcc.mk | 4 | ||||
-rw-r--r-- | builds/unix/configure.ac | 2 | ||||
-rw-r--r-- | include/freetype/cache/ftccache.h | 83 | ||||
-rw-r--r-- | include/freetype/cache/ftcmru.h | 59 | ||||
-rw-r--r-- | include/freetype/internal/ftmemory.h | 62 | ||||
-rw-r--r-- | src/base/ftglyph.c | 2 | ||||
-rw-r--r-- | src/base/ftinit.c | 8 | ||||
-rw-r--r-- | src/cache/ftccache.c | 16 | ||||
-rw-r--r-- | src/cache/ftcsbits.c | 88 | ||||
-rw-r--r-- | src/sfnt/rules.mk | 1 |
13 files changed, 219 insertions, 158 deletions
@@ -1,8 +1,49 @@ +2005-05-23 Werner Lemberg <wl@gnu.org> + + * builds/amiga/makefile.os4 (WARNINGS), builds/compiler/gcc-dev.mk + (CFLAGS), builds/compiler/gcc.mk (CFLAGS): Remove + -fno-strict-aliasing. + +2005-05-23 Behdad Esfahbod <behdad@cs.toronto.edu> + + Say you have `(Foo*)x' and want to assign, pass, or return it as + `(Bar*)'. If you simply say `x' or `(Bar*)x', then the C compiler + would warn you that type casting incompatible pointer types breaks + strict-aliasing. The solution is to cast to `(void*)' instead which + is the generic pointer type, so the compiler knows that it should + make no strict-aliasing assumption on `x'. But the problem with + `(void*)x' is that seems like in C++, unlike C, `void*' is not a + generic pointer type and assigning `void*' to `Bar*' without a cast + causes an error. The solution is to cast to `Bar*' too, with + `(Bar*)(void*)x' as the result -- this is what the patch does. + + * include/freetype/cache/ftccache.h (FTC_CACHE_LOOKUP_CMP), + include/freetype/cache/ftcmru.h (FTC_MRULIST_LOOKUP_CMP): Remove + cast on lvalue, use a temporary pointer instead. + Cast temporarily to (void*) to not break strict aliasing. + + * include/freetype/internal/ftmemory.h (FT_MEM_ALLOC, + FT_MEM_REALLOC, FT_MEM_QALLOC, FT_MEM_QREALLOC, FT_MEM_FREE), + src/base/ftglyph.c (FT_Glyph_To_Bitmap): Cast temporarily to (void*) + to not break strict aliasing. + + * src/base/ftinit.c (FT_USE_MODULE): Fix wrong type information. + + * builds/unix/configure.ac (XX_CFLAGS): Remove -fno-strict-aliasing. + + * src/sfnt/rules.mk (SFNT_DRV_SRC): Don't include ttsbit0.c -- + it is currently loaded from ttsbit.c. + 2005-05-23 David Turner <dturner@freetype.org> - * include/freetype/cache/ftcache.h, src/cache/ftccache.c, - src/cache/ftcsbits.c: fixing bug #12213 (incorrect behaviour - of the cache sub-system in low-memory conditions). + Fix Savannah bug #12213 (incorrect behaviour of the cache sub-system + in low-memory conditions). + + * include/freetype/cache/ftccache.h (FTC_CACHE_TRYLOOP, + FTC_CACHE_TRYLOOP_END): New macros. + + * src/cache/ftccache.c (FTC_Cache_NewNode), src/cache/ftcsbits.c + (ftc_snode_compare): Use FT_CACHE_TRYLOOP and FTC_CACE_TRYLOOP_END. 2005-05-23 Werner Lemberg <wl@gnu.org> diff --git a/builds/amiga/makefile.os4 b/builds/amiga/makefile.os4 index 508e96136..a3e6f823f 100644 --- a/builds/amiga/makefile.os4 +++ b/builds/amiga/makefile.os4 @@ -41,7 +41,7 @@ RANLIB = ppc-amigaos-ranlib DIRFLAGS = -Iinclude -I/FT/src -I/FT/include -I/SDK/include WARNINGS = -Wall -W -Wundef -Wpointer-arith -Wbad-function-cast \ - -Waggregate-return -Wshadow -fno-strict-aliasing + -Waggregate-return -Wshadow CPU = -mcpu=604e diff --git a/builds/compiler/gcc-dev.mk b/builds/compiler/gcc-dev.mk index 9cad7e99a..c70f11734 100644 --- a/builds/compiler/gcc-dev.mk +++ b/builds/compiler/gcc-dev.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2003, 2004 by +# Copyright 1996-2000, 2003, 2004, 2005 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -68,7 +68,6 @@ ifndef CFLAGS endif CFLAGS := -c -g -O0 \ - -fno-strict-aliasing \ -Wall \ -W \ -Wundef \ diff --git a/builds/compiler/gcc.mk b/builds/compiler/gcc.mk index d51f642d0..f4c5f96f4 100644 --- a/builds/compiler/gcc.mk +++ b/builds/compiler/gcc.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2003 by +# Copyright 1996-2000, 2003, 2005 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -62,7 +62,7 @@ T := -o$(space) # ANSI compliance. # ifndef CFLAGS - CFLAGS := -c -g -O6 -Wall -fno-strict-aliasing + CFLAGS := -c -g -O6 -Wall endif # ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. diff --git a/builds/unix/configure.ac b/builds/unix/configure.ac index 0f5bef130..feb4e50e2 100644 --- a/builds/unix/configure.ac +++ b/builds/unix/configure.ac @@ -28,7 +28,7 @@ AC_PROG_CPP # get compiler flags right if test "x$CC" = xgcc; then - XX_CFLAGS="-Wall -fno-strict-aliasing" + XX_CFLAGS="-Wall" XX_ANSIFLAGS="-pedantic -ansi" else case "$host" in diff --git a/include/freetype/cache/ftccache.h b/include/freetype/cache/ftccache.h index f44191581..f2e10281b 100644 --- a/include/freetype/cache/ftccache.h +++ b/include/freetype/cache/ftccache.h @@ -4,7 +4,7 @@ /* */ /* FreeType internal cache interface (specification). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -248,7 +248,8 @@ FT_BEGIN_HEADER error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \ \ _Ok: \ - *(FTC_Node*)&(node) = _node; \ + _pnode = (FTC_Node*)(void*)&(node); \ + *_pnode = _node; \ FT_END_STMNT #else /* !FTC_INLINE */ @@ -262,47 +263,49 @@ FT_BEGIN_HEADER #endif /* !FTC_INLINE */ -/* use this macro with FTC_CACHE_TRYLOOP_END() in order to define - * a retry loop that will flush the cache repeatidely in case of - * memory overflows. - * - * this is used when creating a new cache node, or within a lookup - * that needs to allocate things (e.g. the sbit cache lookup) - * - * here's an example: - * - * { - * FTC_CACHE_TRYLOOP(cache) - * error = load_data( ... ); - * FTC_CACHE_TRYLOOP_END() - * } - * - */ -#define FTC_CACHE_TRYLOOP(cache) \ - { \ - FTC_Manager _try_manager = FTC_CACHE(cache)->manager; \ - FT_UInt _try_count = 4; \ - \ - for (;;) \ - { \ + /* + * This macro, together with FTC_CACHE_TRYLOOP_END, defines a retry + * loop to flush the cache repeatedly in case of memory overflows. + * + * It is used when creating a new cache node, or within a lookup + * that needs to allocate data (e.g., the sbit cache lookup). + * + * Example: + * + * { + * FTC_CACHE_TRYLOOP( cache ) + * error = load_data( ... ); + * FTC_CACHE_TRYLOOP_END() + * } + * + */ +#define FTC_CACHE_TRYLOOP( cache ) \ + { \ + FTC_Manager _try_manager = FTC_CACHE( cache )->manager; \ + FT_UInt _try_count = 4; \ + \ + \ + for (;;) \ + { \ FT_UInt _try_done; -#define FTC_CACHE_TRYLOOP_END() \ - if ( !error || error != FT_Err_Out_Of_Memory ) \ - break; \ - \ - _try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \ - if ( _try_done == 0 ) \ - break; \ - \ - if ( _try_done == _try_count ) \ - { \ - _try_count *= 2; \ - if ( _try_count < _try_done || _try_count > _try_manager->num_nodes ) \ - _try_count = _try_manager->num_nodes; \ - } \ - } \ +#define FTC_CACHE_TRYLOOP_END() \ + if ( !error || error != FT_Err_Out_Of_Memory ) \ + break; \ + \ + _try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \ + if ( _try_done == 0 ) \ + break; \ + \ + if ( _try_done == _try_count ) \ + { \ + _try_count *= 2; \ + if ( _try_count < _try_done || \ + _try_count > _try_manager->num_nodes ) \ + _try_count = _try_manager->num_nodes; \ + } \ + } \ } /* */ diff --git a/include/freetype/cache/ftcmru.h b/include/freetype/cache/ftcmru.h index d70c5cce7..ac1a1a92e 100644 --- a/include/freetype/cache/ftcmru.h +++ b/include/freetype/cache/ftcmru.h @@ -4,7 +4,7 @@ /* */ /* Simple MRU list-cache (specification). */ /* */ -/* Copyright 2000-2001, 2003, 2004 by */ +/* Copyright 2000-2001, 2003, 2004, 2005 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -172,34 +172,35 @@ FT_BEGIN_HEADER FT_BEGIN_STMNT \ FTC_MruNode* _pfirst = &(list)->nodes; \ FTC_MruNode_CompareFunc _compare = (FTC_MruNode_CompareFunc)(compare); \ - FTC_MruNode _first, _node; \ - \ - \ - error = 0; \ - _first = *(_pfirst); \ - _node = NULL; \ - \ - if ( _first ) \ - { \ - _node = _first; \ - do \ - { \ - if ( _compare( _node, (key) ) ) \ - { \ - if ( _node != _first ) \ - FTC_MruNode_Up( _pfirst, _node ); \ - \ - *(FTC_MruNode*)&(node) = _node; \ - goto _MruOk; \ - } \ - _node = _node->next; \ - \ - } while ( _node != _first) ; \ - } \ - \ - error = FTC_MruList_New( (list), (key), (FTC_MruNode*)&(node) ); \ - _MruOk: \ - ; \ + FTC_MruNode _first, _node, *_pnode; \ + \ + \ + error = 0; \ + _first = *(_pfirst); \ + _node = NULL; \ + \ + if ( _first ) \ + { \ + _node = _first; \ + do \ + { \ + if ( _compare( _node, (key) ) ) \ + { \ + if ( _node != _first ) \ + FTC_MruNode_Up( _pfirst, _node ); \ + \ + _pnode = (FTC_MruNode*)(void*)&(node); \ + *_pnode = _node; \ + goto _MruOk; \ + } \ + _node = _node->next; \ + \ + } while ( _node != _first) ; \ + } \ + \ + error = FTC_MruList_New( (list), (key), (FTC_MruNode*)(void*)&(node) ); \ + _MruOk: \ + ; \ FT_END_STMNT #define FTC_MRULIST_LOOKUP( list, key, node, error ) \ diff --git a/include/freetype/internal/ftmemory.h b/include/freetype/internal/ftmemory.h index e2553798e..cead50d72 100644 --- a/include/freetype/internal/ftmemory.h +++ b/include/freetype/internal/ftmemory.h @@ -290,43 +290,53 @@ FT_BEGIN_HEADER #ifdef FT_DEBUG_MEMORY -#define FT_MEM_ALLOC( _pointer_, _size_ ) \ - FT_Alloc_Debug( memory, _size_, \ - (void**)&(_pointer_), __FILE__, __LINE__ ) +#define FT_MEM_ALLOC( _pointer_, _size_ ) \ + FT_Alloc_Debug( memory, _size_, \ + (void**)(void*)&(_pointer_), \ + __FILE__, __LINE__ ) -#define FT_MEM_REALLOC( _pointer_, _current_, _size_ ) \ - FT_Realloc_Debug( memory, _current_, _size_, \ - (void**)&(_pointer_), __FILE__, __LINE__ ) +#define FT_MEM_REALLOC( _pointer_, _current_, _size_ ) \ + FT_Realloc_Debug( memory, _current_, _size_, \ + (void**)(void*)&(_pointer_), \ + __FILE__, __LINE__ ) -#define FT_MEM_QALLOC( _pointer_, _size_ ) \ - FT_QAlloc_Debug( memory, _size_, \ - (void**)&(_pointer_), __FILE__, __LINE__ ) +#define FT_MEM_QALLOC( _pointer_, _size_ ) \ + FT_QAlloc_Debug( memory, _size_, \ + (void**)(void*)&(_pointer_), \ + __FILE__, __LINE__ ) -#define FT_MEM_QREALLOC( _pointer_, _current_, _size_ ) \ - FT_QRealloc_Debug( memory, _current_, _size_, \ - (void**)&(_pointer_), __FILE__, __LINE__ ) +#define FT_MEM_QREALLOC( _pointer_, _current_, _size_ ) \ + FT_QRealloc_Debug( memory, _current_, _size_, \ + (void**)(void*)&(_pointer_), \ + __FILE__, __LINE__ ) -#define FT_MEM_FREE( _pointer_ ) \ - FT_Free_Debug( memory, (void**)&(_pointer_), __FILE__, __LINE__ ) +#define FT_MEM_FREE( _pointer_ ) \ + FT_Free_Debug( memory, (void**)(void*)&(_pointer_), \ + __FILE__, __LINE__ ) #else /* !FT_DEBUG_MEMORY */ -#define FT_MEM_ALLOC( _pointer_, _size_ ) \ - FT_Alloc( memory, _size_, (void**)&(_pointer_) ) +#define FT_MEM_ALLOC( _pointer_, _size_ ) \ + FT_Alloc( memory, _size_, \ + (void**)(void*)&(_pointer_) ) -#define FT_MEM_FREE( _pointer_ ) \ - FT_Free( memory, (void**)&(_pointer_) ) +#define FT_MEM_FREE( _pointer_ ) \ + FT_Free( memory, \ + (void**)(void*)&(_pointer_) ) -#define FT_MEM_REALLOC( _pointer_, _current_, _size_ ) \ - FT_Realloc( memory, _current_, _size_, (void**)&(_pointer_) ) +#define FT_MEM_REALLOC( _pointer_, _current_, _size_ ) \ + FT_Realloc( memory, _current_, _size_, \ + (void**)(void*)&(_pointer_) ) -#define FT_MEM_QALLOC( _pointer_, _size_ ) \ - FT_QAlloc( memory, _size_, (void**)&(_pointer_) ) +#define FT_MEM_QALLOC( _pointer_, _size_ ) \ + FT_QAlloc( memory, _size_, \ + (void**)(void*)&(_pointer_) ) -#define FT_MEM_QREALLOC( _pointer_, _current_, _size_ ) \ - FT_QRealloc( memory, _current_, _size_, (void**)&(_pointer_) ) +#define FT_MEM_QREALLOC( _pointer_, _current_, _size_ ) \ + FT_QRealloc( memory, _current_, _size_, \ + (void**)(void*)&(_pointer_) ) #endif /* !FT_DEBUG_MEMORY */ @@ -337,7 +347,7 @@ FT_BEGIN_HEADER /* _typed_ in order to automatically compute array element sizes. */ /* */ -#define FT_MEM_NEW( _pointer_ ) \ +#define FT_MEM_NEW( _pointer_ ) \ FT_MEM_ALLOC( _pointer_, sizeof ( *(_pointer_) ) ) #define FT_MEM_NEW_ARRAY( _pointer_, _count_ ) \ @@ -347,7 +357,7 @@ FT_BEGIN_HEADER FT_MEM_REALLOC( _pointer_, (_old_) * sizeof ( *(_pointer_) ), \ (_new_) * sizeof ( *(_pointer_) ) ) -#define FT_MEM_QNEW( _pointer_ ) \ +#define FT_MEM_QNEW( _pointer_ ) \ FT_MEM_QALLOC( _pointer_, sizeof ( *(_pointer_) ) ) #define FT_MEM_QNEW_ARRAY( _pointer_, _count_ ) \ diff --git a/src/base/ftglyph.c b/src/base/ftglyph.c index 8f85510d5..af0eadf72 100644 --- a/src/base/ftglyph.c +++ b/src/base/ftglyph.c @@ -603,7 +603,7 @@ /* create result bitmap glyph */ error = ft_new_glyph( glyph->library, &ft_bitmap_glyph_class, - (FT_Glyph*)&bitmap ); + (FT_Glyph*)(void*)&bitmap ); if ( error ) goto Exit; diff --git a/src/base/ftinit.c b/src/base/ftinit.c index 79ba9f0bd..ac009b76d 100644 --- a/src/base/ftinit.c +++ b/src/base/ftinit.c @@ -4,7 +4,7 @@ /* */ /* FreeType initialization layer (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2005 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -55,9 +55,9 @@ #undef FT_USE_MODULE #ifdef __cplusplus -#define FT_USE_MODULE( x ) extern "C" const FT_Module_Class* x; +#define FT_USE_MODULE( x ) extern "C" const FT_Module_Class x; #else -#define FT_USE_MODULE( x ) extern const FT_Module_Class* x; +#define FT_USE_MODULE( x ) extern const FT_Module_Class x; #endif @@ -65,7 +65,7 @@ #undef FT_USE_MODULE -#define FT_USE_MODULE( x ) (const FT_Module_Class*)&x, +#define FT_USE_MODULE( x ) (const FT_Module_Class*)&(x), static const FT_Module_Class* const ft_default_modules[] = diff --git a/src/cache/ftccache.c b/src/cache/ftccache.c index 8c7758a47..ad036805f 100644 --- a/src/cache/ftccache.c +++ b/src/cache/ftccache.c @@ -4,7 +4,7 @@ /* */ /* The FreeType internal cache interface (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -424,12 +424,14 @@ FT_Error error; FTC_Node node; - /* we use the FTC_CACHE_TRYLOOP macros in order to - * support out-of-memory error (OOM) correctly, i.e. - * by flushing the cache progressively in order to - * make more room - */ - FTC_CACHE_TRYLOOP(cache) + + /* + * We use the FTC_CACHE_TRYLOOP macros to support out-of-memory + * errors (OOM) correctly, i.e., by flushing the cache progressively + * in order to make more room. + */ + + FTC_CACHE_TRYLOOP( cache ) { error = cache->clazz.node_new( &node, query, cache ); } diff --git a/src/cache/ftcsbits.c b/src/cache/ftcsbits.c index 51ec34c31..891c7ab8e 100644 --- a/src/cache/ftcsbits.c +++ b/src/cache/ftcsbits.c @@ -4,7 +4,7 @@ /* */ /* FreeType sbits manager (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -85,15 +85,16 @@ } - /* this function tries to load a small bitmap within a given FTC_SNode - * note that it will return 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 - */ + /* + * 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, @@ -324,43 +325,48 @@ 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're out of memory - * - * 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 - * OOM errors occur. - * - * however, we previously need to 'lock' the node to prevent it - * from being flushed in 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 - * will ensure that the caller will try to allocate a new node. - * this operation _will_ fail and the lookup function will return - * the OOM error code appropriately. - * - * note that 'buffer == NULL && width == 255' is a hack used to - * tag "unavailable" bitmaps in the array. We should never try - * to load these. - */ + /* + * 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, prevent flushing in retry loop */ - FTC_CACHE_TRYLOOP(cache) + ftcsnode->ref_count++; /* lock node to prevent flushing */ + /* in retry loop */ + + FTC_CACHE_TRYLOOP( cache ) { error = ftc_snode_load( snode, cache->manager, gindex, &size ); } diff --git a/src/sfnt/rules.mk b/src/sfnt/rules.mk index f2f1c4a1f..e15681b21 100644 --- a/src/sfnt/rules.mk +++ b/src/sfnt/rules.mk @@ -28,7 +28,6 @@ SFNT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SFNT_DIR)) SFNT_DRV_SRC := $(SFNT_DIR)/ttload.c \ $(SFNT_DIR)/ttcmap.c \ $(SFNT_DIR)/ttsbit.c \ - $(SFNT_DIR)/ttsbit0.c \ $(SFNT_DIR)/ttpost.c \ $(SFNT_DIR)/ttkern.c \ $(SFNT_DIR)/sfobjs.c \ |