forked from minhngoc25a/freetype2
[cff] Implement missing operators in new engine (except `random').
* src/cff/cf2font.h (CF2_STORAGE_SIZE): New macro. * src/cff/cf2intrp.c (cf2_interpT2CharString): Implement the following operators: abs, add, and, div, drop, dup, eq, exch, get, ifelse, index, mul, neg, not, or, put, roll, sqrt, sub. * src/cff/cf2stack.h, src/cff/cf2stack.c (cf2_stack_roll): New auxiliary function for `roll' operator.
This commit is contained in:
parent
1a95d00210
commit
950f16969e
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
||||||
|
2016-02-07 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
|
[cff] Implement missing operators in new engine (except `random').
|
||||||
|
|
||||||
|
* src/cff/cf2font.h (CF2_STORAGE_SIZE): New macro.
|
||||||
|
|
||||||
|
* src/cff/cf2intrp.c (cf2_interpT2CharString): Implement the
|
||||||
|
following operators: abs, add, and, div, drop, dup, eq, exch, get,
|
||||||
|
ifelse, index, mul, neg, not, or, put, roll, sqrt, sub.
|
||||||
|
|
||||||
|
* src/cff/cf2stack.h, src/cff/cf2stack.c (cf2_stack_roll): New
|
||||||
|
auxiliary function for `roll' operator.
|
||||||
|
|
||||||
2016-02-06 Werner Lemberg <wl@gnu.org>
|
2016-02-06 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
[cff] Fix some Type 2 operators in old CFF engine.
|
[cff] Fix some Type 2 operators in old CFF engine.
|
||||||
|
|
|
@ -54,6 +54,7 @@ FT_BEGIN_HEADER
|
||||||
/* (Hiragino Kaku Gothic ProN W3; */
|
/* (Hiragino Kaku Gothic ProN W3; */
|
||||||
/* 8.2d6e1; 2014-12-19) that exceed */
|
/* 8.2d6e1; 2014-12-19) that exceed */
|
||||||
/* this limit */
|
/* this limit */
|
||||||
|
#define CF2_STORAGE_SIZE 32
|
||||||
|
|
||||||
|
|
||||||
/* typedef is in `cf2glue.h' */
|
/* typedef is in `cf2glue.h' */
|
||||||
|
|
|
@ -447,6 +447,8 @@
|
||||||
CF2_Stack opStack = NULL;
|
CF2_Stack opStack = NULL;
|
||||||
FT_Byte op1; /* first opcode byte */
|
FT_Byte op1; /* first opcode byte */
|
||||||
|
|
||||||
|
CF2_F16Dot16 storage[CF2_STORAGE_SIZE]; /* for `put' and `get' */
|
||||||
|
|
||||||
/* instruction limit; 20,000,000 matches Avalon */
|
/* instruction limit; 20,000,000 matches Avalon */
|
||||||
FT_UInt32 instructionLimit = 20000000UL;
|
FT_UInt32 instructionLimit = 20000000UL;
|
||||||
|
|
||||||
|
@ -834,84 +836,189 @@
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* TODO: should these operators be supported? */
|
case cf2_escAND:
|
||||||
case cf2_escAND: /* in spec */
|
{
|
||||||
FT_TRACE4(( " and\n" ));
|
CF2_F16Dot16 arg1;
|
||||||
|
CF2_F16Dot16 arg2;
|
||||||
|
|
||||||
CF2_FIXME;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case cf2_escOR: /* in spec */
|
FT_TRACE4(( " and\n" ));
|
||||||
FT_TRACE4(( " or\n" ));
|
|
||||||
|
|
||||||
CF2_FIXME;
|
arg2 = cf2_stack_popFixed( opStack );
|
||||||
break;
|
arg1 = cf2_stack_popFixed( opStack );
|
||||||
|
|
||||||
case cf2_escNOT: /* in spec */
|
cf2_stack_pushInt( opStack, arg1 && arg2 );
|
||||||
FT_TRACE4(( " not\n" ));
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
CF2_FIXME;
|
case cf2_escOR:
|
||||||
break;
|
{
|
||||||
|
CF2_F16Dot16 arg1;
|
||||||
|
CF2_F16Dot16 arg2;
|
||||||
|
|
||||||
case cf2_escABS: /* in spec */
|
|
||||||
FT_TRACE4(( " abs\n" ));
|
|
||||||
|
|
||||||
CF2_FIXME;
|
FT_TRACE4(( " or\n" ));
|
||||||
break;
|
|
||||||
|
|
||||||
case cf2_escADD: /* in spec */
|
arg2 = cf2_stack_popFixed( opStack );
|
||||||
FT_TRACE4(( " add\n" ));
|
arg1 = cf2_stack_popFixed( opStack );
|
||||||
|
|
||||||
CF2_FIXME;
|
cf2_stack_pushInt( opStack, arg1 || arg2 );
|
||||||
break;
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
case cf2_escSUB: /* in spec */
|
case cf2_escNOT:
|
||||||
FT_TRACE4(( " sub\n" ));
|
{
|
||||||
|
CF2_F16Dot16 arg;
|
||||||
|
|
||||||
CF2_FIXME;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case cf2_escDIV: /* in spec */
|
FT_TRACE4(( " not\n" ));
|
||||||
FT_TRACE4(( " div\n" ));
|
|
||||||
|
|
||||||
CF2_FIXME;
|
arg = cf2_stack_popFixed( opStack );
|
||||||
break;
|
|
||||||
|
|
||||||
case cf2_escNEG: /* in spec */
|
cf2_stack_pushInt( opStack, !arg );
|
||||||
FT_TRACE4(( " neg\n" ));
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
CF2_FIXME;
|
case cf2_escABS:
|
||||||
break;
|
{
|
||||||
|
CF2_F16Dot16 arg;
|
||||||
|
|
||||||
case cf2_escEQ: /* in spec */
|
|
||||||
FT_TRACE4(( " eq\n" ));
|
|
||||||
|
|
||||||
CF2_FIXME;
|
FT_TRACE4(( " abs\n" ));
|
||||||
break;
|
|
||||||
|
|
||||||
case cf2_escDROP: /* in spec */
|
arg = cf2_stack_popFixed( opStack );
|
||||||
|
|
||||||
|
cf2_stack_pushFixed( opStack, FT_ABS( arg ) );
|
||||||
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
|
case cf2_escADD:
|
||||||
|
{
|
||||||
|
CF2_F16Dot16 summand1;
|
||||||
|
CF2_F16Dot16 summand2;
|
||||||
|
|
||||||
|
|
||||||
|
FT_TRACE4(( " add\n" ));
|
||||||
|
|
||||||
|
summand2 = cf2_stack_popFixed( opStack );
|
||||||
|
summand1 = cf2_stack_popFixed( opStack );
|
||||||
|
|
||||||
|
cf2_stack_pushFixed( opStack, summand1 + summand2 );
|
||||||
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
|
case cf2_escSUB:
|
||||||
|
{
|
||||||
|
CF2_F16Dot16 minuend;
|
||||||
|
CF2_F16Dot16 subtrahend;
|
||||||
|
|
||||||
|
|
||||||
|
FT_TRACE4(( " sub\n" ));
|
||||||
|
|
||||||
|
subtrahend = cf2_stack_popFixed( opStack );
|
||||||
|
minuend = cf2_stack_popFixed( opStack );
|
||||||
|
|
||||||
|
cf2_stack_pushFixed( opStack, minuend - subtrahend );
|
||||||
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
|
case cf2_escDIV:
|
||||||
|
{
|
||||||
|
CF2_F16Dot16 dividend;
|
||||||
|
CF2_F16Dot16 divisor;
|
||||||
|
|
||||||
|
|
||||||
|
FT_TRACE4(( " div\n" ));
|
||||||
|
|
||||||
|
divisor = cf2_stack_popFixed( opStack );
|
||||||
|
dividend = cf2_stack_popFixed( opStack );
|
||||||
|
|
||||||
|
cf2_stack_pushFixed( opStack, FT_DivFix( dividend, divisor ) );
|
||||||
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
|
case cf2_escNEG:
|
||||||
|
{
|
||||||
|
CF2_F16Dot16 arg;
|
||||||
|
|
||||||
|
|
||||||
|
FT_TRACE4(( " neg\n" ));
|
||||||
|
|
||||||
|
arg = cf2_stack_popFixed( opStack );
|
||||||
|
|
||||||
|
cf2_stack_pushFixed( opStack, -arg );
|
||||||
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
|
case cf2_escEQ:
|
||||||
|
{
|
||||||
|
CF2_F16Dot16 arg1;
|
||||||
|
CF2_F16Dot16 arg2;
|
||||||
|
|
||||||
|
|
||||||
|
FT_TRACE4(( " eq\n" ));
|
||||||
|
|
||||||
|
arg2 = cf2_stack_popFixed( opStack );
|
||||||
|
arg1 = cf2_stack_popFixed( opStack );
|
||||||
|
|
||||||
|
cf2_stack_pushInt( opStack, arg1 == arg2 );
|
||||||
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
|
case cf2_escDROP:
|
||||||
FT_TRACE4(( " drop\n" ));
|
FT_TRACE4(( " drop\n" ));
|
||||||
|
|
||||||
CF2_FIXME;
|
(void)cf2_stack_popFixed( opStack );
|
||||||
break;
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
case cf2_escPUT: /* in spec */
|
case cf2_escPUT:
|
||||||
FT_TRACE4(( " put\n" ));
|
{
|
||||||
|
CF2_F16Dot16 val;
|
||||||
|
CF2_Int idx;
|
||||||
|
|
||||||
CF2_FIXME;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case cf2_escGET: /* in spec */
|
FT_TRACE4(( " put\n" ));
|
||||||
FT_TRACE4(( " get\n" ));
|
|
||||||
|
|
||||||
CF2_FIXME;
|
idx = cf2_stack_popInt( opStack );
|
||||||
break;
|
val = cf2_stack_popFixed( opStack );
|
||||||
|
|
||||||
case cf2_escIFELSE: /* in spec */
|
if ( idx >= 0 && idx < CF2_STORAGE_SIZE )
|
||||||
FT_TRACE4(( " ifelse\n" ));
|
storage[idx] = val;
|
||||||
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
CF2_FIXME;
|
case cf2_escGET:
|
||||||
break;
|
{
|
||||||
|
CF2_Int idx;
|
||||||
|
|
||||||
|
|
||||||
|
FT_TRACE4(( " get\n" ));
|
||||||
|
|
||||||
|
idx = cf2_stack_popInt( opStack );
|
||||||
|
|
||||||
|
if ( idx >= 0 && idx < CF2_STORAGE_SIZE )
|
||||||
|
cf2_stack_pushFixed( opStack, storage[idx] );
|
||||||
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
|
case cf2_escIFELSE:
|
||||||
|
{
|
||||||
|
CF2_F16Dot16 arg1;
|
||||||
|
CF2_F16Dot16 arg2;
|
||||||
|
CF2_F16Dot16 cond1;
|
||||||
|
CF2_F16Dot16 cond2;
|
||||||
|
|
||||||
|
|
||||||
|
FT_TRACE4(( " ifelse\n" ));
|
||||||
|
|
||||||
|
cond2 = cf2_stack_popFixed( opStack );
|
||||||
|
cond1 = cf2_stack_popFixed( opStack );
|
||||||
|
arg2 = cf2_stack_popFixed( opStack );
|
||||||
|
arg1 = cf2_stack_popFixed( opStack );
|
||||||
|
|
||||||
|
cf2_stack_pushFixed( opStack, cond1 <= cond2 ? arg1 : arg2 );
|
||||||
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
case cf2_escRANDOM: /* in spec */
|
case cf2_escRANDOM: /* in spec */
|
||||||
FT_TRACE4(( " random\n" ));
|
FT_TRACE4(( " random\n" ));
|
||||||
|
@ -919,41 +1026,126 @@
|
||||||
CF2_FIXME;
|
CF2_FIXME;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cf2_escMUL: /* in spec */
|
case cf2_escMUL:
|
||||||
FT_TRACE4(( " mul\n" ));
|
{
|
||||||
|
CF2_F16Dot16 factor1;
|
||||||
|
CF2_F16Dot16 factor2;
|
||||||
|
|
||||||
CF2_FIXME;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case cf2_escSQRT: /* in spec */
|
FT_TRACE4(( " mul\n" ));
|
||||||
FT_TRACE4(( " sqrt\n" ));
|
|
||||||
|
|
||||||
CF2_FIXME;
|
factor2 = cf2_stack_popFixed( opStack );
|
||||||
break;
|
factor1 = cf2_stack_popFixed( opStack );
|
||||||
|
|
||||||
case cf2_escDUP: /* in spec */
|
cf2_stack_pushFixed( opStack, FT_MulFix( factor1, factor2 ) );
|
||||||
FT_TRACE4(( " dup\n" ));
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
CF2_FIXME;
|
case cf2_escSQRT:
|
||||||
break;
|
{
|
||||||
|
CF2_F16Dot16 arg;
|
||||||
|
|
||||||
case cf2_escEXCH: /* in spec */
|
|
||||||
FT_TRACE4(( " exch\n" ));
|
|
||||||
|
|
||||||
CF2_FIXME;
|
FT_TRACE4(( " sqrt\n" ));
|
||||||
break;
|
|
||||||
|
|
||||||
case cf2_escINDEX: /* in spec */
|
arg = cf2_stack_popFixed( opStack );
|
||||||
FT_TRACE4(( " index\n" ));
|
if ( arg > 0 )
|
||||||
|
{
|
||||||
|
FT_Fixed root = arg;
|
||||||
|
FT_Fixed new_root;
|
||||||
|
|
||||||
CF2_FIXME;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case cf2_escROLL: /* in spec */
|
/* Babylonian method */
|
||||||
FT_TRACE4(( " roll\n" ));
|
for (;;)
|
||||||
|
{
|
||||||
|
new_root = ( root + FT_DivFix( arg, root ) + 1 ) >> 1;
|
||||||
|
if ( new_root == root )
|
||||||
|
break;
|
||||||
|
root = new_root;
|
||||||
|
}
|
||||||
|
arg = new_root;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
arg = 0;
|
||||||
|
|
||||||
CF2_FIXME;
|
cf2_stack_pushFixed( opStack, arg );
|
||||||
break;
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
|
case cf2_escDUP:
|
||||||
|
{
|
||||||
|
CF2_F16Dot16 arg;
|
||||||
|
|
||||||
|
|
||||||
|
FT_TRACE4(( " dup\n" ));
|
||||||
|
|
||||||
|
arg = cf2_stack_popFixed( opStack );
|
||||||
|
|
||||||
|
cf2_stack_pushFixed( opStack, arg );
|
||||||
|
cf2_stack_pushFixed( opStack, arg );
|
||||||
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
|
case cf2_escEXCH:
|
||||||
|
{
|
||||||
|
CF2_F16Dot16 arg1;
|
||||||
|
CF2_F16Dot16 arg2;
|
||||||
|
|
||||||
|
|
||||||
|
FT_TRACE4(( " exch\n" ));
|
||||||
|
|
||||||
|
arg2 = cf2_stack_popFixed( opStack );
|
||||||
|
arg1 = cf2_stack_popFixed( opStack );
|
||||||
|
|
||||||
|
cf2_stack_pushFixed( opStack, arg2 );
|
||||||
|
cf2_stack_pushFixed( opStack, arg1 );
|
||||||
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
|
case cf2_escINDEX:
|
||||||
|
{
|
||||||
|
CF2_Int idx;
|
||||||
|
CF2_UInt size;
|
||||||
|
|
||||||
|
|
||||||
|
FT_TRACE4(( " index\n" ));
|
||||||
|
|
||||||
|
idx = cf2_stack_popInt( opStack );
|
||||||
|
size = cf2_stack_count( opStack );
|
||||||
|
|
||||||
|
if ( size > 0 )
|
||||||
|
{
|
||||||
|
/* for `cf2_stack_getReal', index 0 is bottom of stack */
|
||||||
|
CF2_UInt gr_idx;
|
||||||
|
|
||||||
|
|
||||||
|
if ( idx < 0 )
|
||||||
|
gr_idx = size - 1;
|
||||||
|
else if ( (CF2_UInt)idx >= size )
|
||||||
|
gr_idx = 0;
|
||||||
|
else
|
||||||
|
gr_idx = size - 1 - (CF2_UInt)idx;
|
||||||
|
|
||||||
|
cf2_stack_pushFixed( opStack,
|
||||||
|
cf2_stack_getReal( opStack, gr_idx ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
|
case cf2_escROLL:
|
||||||
|
{
|
||||||
|
CF2_Int idx;
|
||||||
|
CF2_Int count;
|
||||||
|
|
||||||
|
|
||||||
|
FT_TRACE4(( " roll\n" ));
|
||||||
|
|
||||||
|
idx = cf2_stack_popInt( opStack );
|
||||||
|
count = cf2_stack_popInt( opStack );
|
||||||
|
|
||||||
|
cf2_stack_roll( opStack, count, idx );
|
||||||
|
}
|
||||||
|
continue; /* do not clear the stack */
|
||||||
|
|
||||||
case cf2_escHFLEX:
|
case cf2_escHFLEX:
|
||||||
{
|
{
|
||||||
|
|
|
@ -145,7 +145,7 @@
|
||||||
|
|
||||||
|
|
||||||
/* Note: type mismatch is silently cast */
|
/* Note: type mismatch is silently cast */
|
||||||
/* TODO: check this */
|
/* TODO: check this */
|
||||||
FT_LOCAL_DEF( CF2_Fixed )
|
FT_LOCAL_DEF( CF2_Fixed )
|
||||||
cf2_stack_popFixed( CF2_Stack stack )
|
cf2_stack_popFixed( CF2_Stack stack )
|
||||||
{
|
{
|
||||||
|
@ -170,7 +170,7 @@
|
||||||
|
|
||||||
|
|
||||||
/* Note: type mismatch is silently cast */
|
/* Note: type mismatch is silently cast */
|
||||||
/* TODO: check this */
|
/* TODO: check this */
|
||||||
FT_LOCAL_DEF( CF2_Fixed )
|
FT_LOCAL_DEF( CF2_Fixed )
|
||||||
cf2_stack_getReal( CF2_Stack stack,
|
cf2_stack_getReal( CF2_Stack stack,
|
||||||
CF2_UInt idx )
|
CF2_UInt idx )
|
||||||
|
@ -195,6 +195,86 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FT_LOCAL( void )
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FT_LOCAL_DEF( void )
|
FT_LOCAL_DEF( void )
|
||||||
cf2_stack_clear( CF2_Stack stack )
|
cf2_stack_clear( CF2_Stack stack )
|
||||||
{
|
{
|
||||||
|
|
|
@ -93,6 +93,11 @@ FT_BEGIN_HEADER
|
||||||
cf2_stack_getReal( CF2_Stack stack,
|
cf2_stack_getReal( CF2_Stack stack,
|
||||||
CF2_UInt idx );
|
CF2_UInt idx );
|
||||||
|
|
||||||
|
FT_LOCAL( void )
|
||||||
|
cf2_stack_roll( CF2_Stack stack,
|
||||||
|
CF2_Int count,
|
||||||
|
CF2_Int idx );
|
||||||
|
|
||||||
FT_LOCAL( void )
|
FT_LOCAL( void )
|
||||||
cf2_stack_clear( CF2_Stack stack );
|
cf2_stack_clear( CF2_Stack stack );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue