cf2_stack_popInt( CF2_Stack stack ) { if ( stack->top == &stack->buffer[0] ) { CF2_SET_ERROR( stack->error, Stack_Underflow ); return 0; /* underflow */ } if ( stack->top[-1].type != CF2_NumberInt ) { CF2_SET_ERROR( stack->error, Syntax_Error ); return 0; /* type mismatch */ } --stack->top; return stack->top->u.i; }
cf2_stack_pop( CF2_Stack stack, CF2_UInt num ) { if ( num > cf2_stack_count( stack ) ) { CF2_SET_ERROR( stack->error, Stack_Underflow ); return; } stack->top -= num; }
/* return false on memory error */ static FT_Bool cf2_arrstack_setNumElements( CF2_ArrStack arrstack, size_t numElements ) { FT_ASSERT( arrstack != NULL ); { FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ FT_Memory memory = arrstack->memory; /* for FT_REALLOC */ FT_Long newSize = numElements * arrstack->sizeItem; if ( numElements > LONG_MAX / arrstack->sizeItem ) goto exit; FT_ASSERT( newSize > 0 ); /* avoid realloc with zero size */ if ( !FT_REALLOC( arrstack->ptr, arrstack->totalSize, newSize ) ) { arrstack->allocated = numElements; arrstack->totalSize = newSize; if ( arrstack->count > numElements ) { /* we truncated the list! */ CF2_SET_ERROR( arrstack->error, Stack_Overflow ); arrstack->count = numElements; return FALSE; } return TRUE; /* success */ } } exit: /* if there's not already an error, store this one */ CF2_SET_ERROR( arrstack->error, Out_Of_Memory ); return FALSE; }
cf2_stack_pushInt( CF2_Stack stack, CF2_Int val ) { if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] ) { CF2_SET_ERROR( stack->error, Stack_Overflow ); return; /* stack overflow */ } stack->top->u.i = val; stack->top->type = CF2_NumberInt; ++stack->top; }
cf2_buf_readByte( CF2_Buffer buf ) { if ( buf->ptr < buf->end ) { #if CF2_IO_FAIL if ( randomError2() ) { CF2_SET_ERROR( buf->error, Invalid_Stream_Operation ); return 0; } return *(buf->ptr)++ + randomValue(); #else return *(buf->ptr)++; #endif } else { CF2_SET_ERROR( buf->error, Invalid_Stream_Operation ); return 0; } }
cf2_stack_setReal( CF2_Stack stack, CF2_UInt idx, CF2_Fixed val ) { if ( idx > cf2_stack_count( stack ) ) { CF2_SET_ERROR( stack->error, Stack_Overflow ); return; } stack->buffer[idx].u.r = val; stack->buffer[idx].type = CF2_NumberFixed; }
cf2_stack_pushFixed( CF2_Stack stack, CF2_Fixed val ) { if ( stack->top == stack->buffer + stack->stackSize ) { CF2_SET_ERROR( stack->error, Stack_Overflow ); return; /* stack overflow */ } stack->top->u.r = val; stack->top->type = CF2_NumberFixed; stack->top++; }
cf2_stack_pushInt( CF2_Stack stack, CF2_Int val ) { if ( stack->top == stack->buffer + stack->stackSize ) { CF2_SET_ERROR( stack->error, Stack_Overflow ); return; /* stack overflow */ } stack->top->u.i = val; stack->top->type = CF2_NumberInt; stack->top++; }
static size_t cf2_hintmask_setCounts( CF2_HintMask hintmask, size_t bitCount ) { if ( bitCount > CF2_MAX_HINTS ) { /* total of h and v stems must be <= 96 */ CF2_SET_ERROR( hintmask->error, Invalid_Glyph_Format ); return 0; } hintmask->bitCount = bitCount; hintmask->byteCount = ( hintmask->bitCount + 7 ) / 8; hintmask->isValid = TRUE; hintmask->isNew = TRUE; return bitCount; }
cf2_arrstack_getPointer( const CF2_ArrStack arrstack, size_t idx ) { void* newPtr; FT_ASSERT( arrstack != NULL ); if ( idx >= arrstack->count ) { /* overflow */ CF2_SET_ERROR( arrstack->error, Stack_Overflow ); idx = 0; /* choose safe default */ } newPtr = (FT_Byte*)arrstack->ptr + idx * arrstack->sizeItem; return newPtr; }
cf2_stack_popFixed( CF2_Stack stack ) { if ( stack->top == &stack->buffer[0] ) { CF2_SET_ERROR( stack->error, Stack_Underflow ); return cf2_intToFixed( 0 ); /* underflow */ } --stack->top; switch ( stack->top->type ) { case CF2_NumberInt: return cf2_intToFixed( stack->top->u.i ); case CF2_NumberFrac: return cf2_fracToFixed( stack->top->u.f ); default: return stack->top->u.r; } }
cf2_stack_getReal( CF2_Stack stack, CF2_UInt idx ) { FT_ASSERT( cf2_stack_count( stack ) <= CF2_OPERAND_STACK_SIZE ); if ( idx >= cf2_stack_count( stack ) ) { CF2_SET_ERROR( stack->error, Stack_Overflow ); return cf2_intToFixed( 0 ); /* bounds error */ } switch ( stack->buffer[idx].type ) { case CF2_NumberInt: return cf2_intToFixed( stack->buffer[idx].u.i ); case CF2_NumberFrac: return cf2_fracToFixed( stack->buffer[idx].u.f ); default: return stack->buffer[idx].u.r; } }
cf2_stack_roll( CF2_Stack stack, CF2_Int count, CF2_Int shift ) { /* we initialize this variable to avoid compiler warnings */ CF2_StackNumber last = { { 0 }, CF2_NumberInt }; CF2_Int start_idx, idx, i; if ( count < 2 ) return; /* nothing to do (values 0 and 1), or undefined value */ if ( (CF2_UInt)count > cf2_stack_count( stack ) ) { CF2_SET_ERROR( stack->error, Stack_Overflow ); return; } if ( shift < 0 ) shift = -( ( -shift ) % count ); else shift %= count; if ( shift == 0 ) return; /* nothing to do */ /* We use the following algorithm to do the rolling, */ /* which needs two temporary variables only. */ /* */ /* Example: */ /* */ /* count = 8 */ /* shift = 2 */ /* */ /* stack indices before roll: 7 6 5 4 3 2 1 0 */ /* stack indices after roll: 1 0 7 6 5 4 3 2 */ /* */ /* The value of index 0 gets moved to index 2, while */ /* the old value of index 2 gets moved to index 4, */ /* and so on. We thus have the following copying */ /* chains for shift value 2. */ /* */ /* 0 -> 2 -> 4 -> 6 -> 0 */ /* 1 -> 3 -> 5 -> 7 -> 1 */ /* */ /* If `count' and `shift' are incommensurable, we */ /* have a single chain only. Otherwise, increase */ /* the start index by 1 after the first chain, then */ /* do the next chain until all elements in all */ /* chains are handled. */ start_idx = -1; idx = -1; for ( i = 0; i < count; i++ ) { CF2_StackNumber tmp; if ( start_idx == idx ) { start_idx++; idx = start_idx; last = stack->buffer[idx]; } idx += shift; if ( idx >= count ) idx -= count; else if ( idx < 0 ) idx += count; tmp = stack->buffer[idx]; stack->buffer[idx] = last; last = tmp; } }