|
|
|
@ -85,6 +85,15 @@ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 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 |
|
|
|
|
*/ |
|
|
|
|
static FT_Error |
|
|
|
|
ftc_snode_load( FTC_SNode snode, |
|
|
|
|
FTC_Manager manager, |
|
|
|
@ -315,16 +324,54 @@ |
|
|
|
|
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. |
|
|
|
|
*/ |
|
|
|
|
if ( sbit->buffer == NULL && sbit->width != 255 ) |
|
|
|
|
{ |
|
|
|
|
FT_ULong size; |
|
|
|
|
FT_Error error; |
|
|
|
|
|
|
|
|
|
ftcsnode->ref_count++; /* lock node, prevent flushing in retry loop */ |
|
|
|
|
|
|
|
|
|
if ( !ftc_snode_load( snode, cache->manager, |
|
|
|
|
gindex, &size ) ) |
|
|
|
|
FTC_CACHE_TRYLOOP(cache) |
|
|
|
|
{ |
|
|
|
|
cache->manager->cur_weight += size; |
|
|
|
|
error = ftc_snode_load( snode, cache->manager, gindex, &size ); |
|
|
|
|
} |
|
|
|
|
FTC_CACHE_TRYLOOP_END(); |
|
|
|
|
|
|
|
|
|
ftcsnode->ref_count--; /* unlock the node */ |
|
|
|
|
|
|
|
|
|
if ( error ) |
|
|
|
|
result = 0; |
|
|
|
|
else |
|
|
|
|
cache->manager->cur_weight += size; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|