< prev index next >

src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.c

Print this page

        

*** 1,21 **** ! /***************************************************************************/ ! /* */ ! /* ttinterp.c */ ! /* */ ! /* TrueType bytecode interpreter (body). */ ! /* */ ! /* Copyright 1996-2018 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. */ ! /* */ ! /***************************************************************************/ /* Greg Hitchcock from Microsoft has helped a lot in resolving unclear */ /* issues; many thanks! */ --- 1,21 ---- ! /**************************************************************************** ! * ! * ttinterp.c ! * ! * TrueType bytecode interpreter (body). ! * ! * Copyright (C) 1996-2019 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. ! * ! */ /* Greg Hitchcock from Microsoft has helped a lot in resolving unclear */ /* issues; many thanks! */
*** 37,54 **** #ifdef TT_USE_BYTECODE_INTERPRETER ! /*************************************************************************/ ! /* */ ! /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ ! /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ ! /* messages during execution. */ ! /* */ #undef FT_COMPONENT ! #define FT_COMPONENT trace_ttinterp #define NO_SUBPIXEL_HINTING \ ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ TT_INTERPRETER_VERSION_35 ) --- 37,54 ---- #ifdef TT_USE_BYTECODE_INTERPRETER ! /************************************************************************** ! * ! * The macro FT_COMPONENT is used in trace mode. It is an implicit ! * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log ! * messages during execution. ! */ #undef FT_COMPONENT ! #define FT_COMPONENT ttinterp #define NO_SUBPIXEL_HINTING \ ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ TT_INTERPRETER_VERSION_35 )
*** 80,93 **** #define FAST_DUALPROJ( v ) \ exc->func_dualproj( exc, (v)->x, (v)->y ) ! /*************************************************************************/ ! /* */ ! /* Two simple bounds-checking macros. */ ! /* */ #define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) #define BOUNDSL( x, n ) ( (FT_ULong)(x) >= (FT_ULong)(n) ) #undef SUCCESS --- 80,93 ---- #define FAST_DUALPROJ( v ) \ exc->func_dualproj( exc, (v)->x, (v)->y ) ! /************************************************************************** ! * ! * Two simple bounds-checking macros. ! */ #define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) #define BOUNDSL( x, n ) ( (FT_ULong)(x) >= (FT_ULong)(n) ) #undef SUCCESS
*** 95,128 **** #undef FAILURE #define FAILURE 1 ! /*************************************************************************/ ! /* */ ! /* CODERANGE FUNCTIONS */ ! /* */ ! /*************************************************************************/ ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* TT_Goto_CodeRange */ ! /* */ ! /* <Description> */ ! /* Switches to a new code range (updates the code related elements in */ ! /* `exec', and `IP'). */ ! /* */ ! /* <Input> */ ! /* range :: The new execution code range. */ ! /* */ ! /* IP :: The new IP in the new code range. */ ! /* */ ! /* <InOut> */ ! /* exec :: The target execution context. */ ! /* */ FT_LOCAL_DEF( void ) TT_Goto_CodeRange( TT_ExecContext exec, FT_Int range, FT_Long IP ) { --- 95,131 ---- #undef FAILURE #define FAILURE 1 ! /************************************************************************** ! * ! * CODERANGE FUNCTIONS ! * ! */ ! /************************************************************************** ! * ! * @Function: ! * TT_Goto_CodeRange ! * ! * @Description: ! * Switches to a new code range (updates the code related elements in ! * `exec', and `IP'). ! * ! * @Input: ! * range :: ! * The new execution code range. ! * ! * IP :: ! * The new IP in the new code range. ! * ! * @InOut: ! * exec :: ! * The target execution context. ! */ FT_LOCAL_DEF( void ) TT_Goto_CodeRange( TT_ExecContext exec, FT_Int range, FT_Long IP ) {
*** 146,173 **** exec->IP = IP; exec->curRange = range; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* TT_Set_CodeRange */ ! /* */ ! /* <Description> */ ! /* Sets a code range. */ ! /* */ ! /* <Input> */ ! /* range :: The code range index. */ ! /* */ ! /* base :: The new code base. */ ! /* */ ! /* length :: The range size in bytes. */ ! /* */ ! /* <InOut> */ ! /* exec :: The target execution context. */ ! /* */ FT_LOCAL_DEF( void ) TT_Set_CodeRange( TT_ExecContext exec, FT_Int range, void* base, FT_Long length ) --- 149,180 ---- exec->IP = IP; exec->curRange = range; } ! /************************************************************************** ! * ! * @Function: ! * TT_Set_CodeRange ! * ! * @Description: ! * Sets a code range. ! * ! * @Input: ! * range :: ! * The code range index. ! * ! * base :: ! * The new code base. ! * ! * length :: ! * The range size in bytes. ! * ! * @InOut: ! * exec :: ! * The target execution context. ! */ FT_LOCAL_DEF( void ) TT_Set_CodeRange( TT_ExecContext exec, FT_Int range, void* base, FT_Long length )
*** 177,200 **** exec->codeRangeTable[range - 1].base = (FT_Byte*)base; exec->codeRangeTable[range - 1].size = length; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* TT_Clear_CodeRange */ ! /* */ ! /* <Description> */ ! /* Clears a code range. */ ! /* */ ! /* <Input> */ ! /* range :: The code range index. */ ! /* */ ! /* <InOut> */ ! /* exec :: The target execution context. */ ! /* */ FT_LOCAL_DEF( void ) TT_Clear_CodeRange( TT_ExecContext exec, FT_Int range ) { FT_ASSERT( range >= 1 && range <= 3 ); --- 184,209 ---- exec->codeRangeTable[range - 1].base = (FT_Byte*)base; exec->codeRangeTable[range - 1].size = length; } ! /************************************************************************** ! * ! * @Function: ! * TT_Clear_CodeRange ! * ! * @Description: ! * Clears a code range. ! * ! * @Input: ! * range :: ! * The code range index. ! * ! * @InOut: ! * exec :: ! * The target execution context. ! */ FT_LOCAL_DEF( void ) TT_Clear_CodeRange( TT_ExecContext exec, FT_Int range ) { FT_ASSERT( range >= 1 && range <= 3 );
*** 202,234 **** exec->codeRangeTable[range - 1].base = NULL; exec->codeRangeTable[range - 1].size = 0; } ! /*************************************************************************/ ! /* */ ! /* EXECUTION CONTEXT ROUTINES */ ! /* */ ! /*************************************************************************/ ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* TT_Done_Context */ ! /* */ ! /* <Description> */ ! /* Destroys a given context. */ ! /* */ ! /* <Input> */ ! /* exec :: A handle to the target execution context. */ ! /* */ ! /* memory :: A handle to the parent memory object. */ ! /* */ ! /* <Note> */ ! /* Only the glyph loader and debugger should call this function. */ ! /* */ FT_LOCAL_DEF( void ) TT_Done_Context( TT_ExecContext exec ) { FT_Memory memory = exec->memory; --- 211,245 ---- exec->codeRangeTable[range - 1].base = NULL; exec->codeRangeTable[range - 1].size = 0; } ! /************************************************************************** ! * ! * EXECUTION CONTEXT ROUTINES ! * ! */ ! /************************************************************************** ! * ! * @Function: ! * TT_Done_Context ! * ! * @Description: ! * Destroys a given context. ! * ! * @Input: ! * exec :: ! * A handle to the target execution context. ! * ! * memory :: ! * A handle to the parent memory object. ! * ! * @Note: ! * Only the glyph loader and debugger should call this function. ! */ FT_LOCAL_DEF( void ) TT_Done_Context( TT_ExecContext exec ) { FT_Memory memory = exec->memory;
*** 255,281 **** FT_FREE( exec ); } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Init_Context */ ! /* */ ! /* <Description> */ ! /* Initializes a context object. */ ! /* */ ! /* <Input> */ ! /* memory :: A handle to the parent memory object. */ ! /* */ ! /* <InOut> */ ! /* exec :: A handle to the target execution context. */ ! /* */ ! /* <Return> */ ! /* FreeType error code. 0 means success. */ ! /* */ static FT_Error Init_Context( TT_ExecContext exec, FT_Memory memory ) { FT_Error error; --- 266,294 ---- FT_FREE( exec ); } ! /************************************************************************** ! * ! * @Function: ! * Init_Context ! * ! * @Description: ! * Initializes a context object. ! * ! * @Input: ! * memory :: ! * A handle to the parent memory object. ! * ! * @InOut: ! * exec :: ! * A handle to the target execution context. ! * ! * @Return: ! * FreeType error code. 0 means success. ! */ static FT_Error Init_Context( TT_ExecContext exec, FT_Memory memory ) { FT_Error error;
*** 311,344 **** return error; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Update_Max */ ! /* */ ! /* <Description> */ ! /* Checks the size of a buffer and reallocates it if necessary. */ ! /* */ ! /* <Input> */ ! /* memory :: A handle to the parent memory object. */ ! /* */ ! /* multiplier :: The size in bytes of each element in the buffer. */ ! /* */ ! /* new_max :: The new capacity (size) of the buffer. */ ! /* */ ! /* <InOut> */ ! /* size :: The address of the buffer's current size expressed */ ! /* in elements. */ ! /* */ ! /* buff :: The address of the buffer base pointer. */ ! /* */ ! /* <Return> */ ! /* FreeType error code. 0 means success. */ ! /* */ FT_LOCAL_DEF( FT_Error ) Update_Max( FT_Memory memory, FT_ULong* size, FT_ULong multiplier, void* _pbuff, --- 324,362 ---- return error; } ! /************************************************************************** ! * ! * @Function: ! * Update_Max ! * ! * @Description: ! * Checks the size of a buffer and reallocates it if necessary. ! * ! * @Input: ! * memory :: ! * A handle to the parent memory object. ! * ! * multiplier :: ! * The size in bytes of each element in the buffer. ! * ! * new_max :: ! * The new capacity (size) of the buffer. ! * ! * @InOut: ! * size :: ! * The address of the buffer's current size expressed ! * in elements. ! * ! * buff :: ! * The address of the buffer base pointer. ! * ! * @Return: ! * FreeType error code. 0 means success. ! */ FT_LOCAL_DEF( FT_Error ) Update_Max( FT_Memory memory, FT_ULong* size, FT_ULong multiplier, void* _pbuff,
*** 357,388 **** return FT_Err_Ok; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* TT_Load_Context */ ! /* */ ! /* <Description> */ ! /* Prepare an execution context for glyph hinting. */ ! /* */ ! /* <Input> */ ! /* face :: A handle to the source face object. */ ! /* */ ! /* size :: A handle to the source size object. */ ! /* */ ! /* <InOut> */ ! /* exec :: A handle to the target execution context. */ ! /* */ ! /* <Return> */ ! /* FreeType error code. 0 means success. */ ! /* */ ! /* <Note> */ ! /* Only the glyph loader and debugger should call this function. */ ! /* */ FT_LOCAL_DEF( FT_Error ) TT_Load_Context( TT_ExecContext exec, TT_Face face, TT_Size size ) { --- 375,409 ---- return FT_Err_Ok; } ! /************************************************************************** ! * ! * @Function: ! * TT_Load_Context ! * ! * @Description: ! * Prepare an execution context for glyph hinting. ! * ! * @Input: ! * face :: ! * A handle to the source face object. ! * ! * size :: ! * A handle to the source size object. ! * ! * @InOut: ! * exec :: ! * A handle to the target execution context. ! * ! * @Return: ! * FreeType error code. 0 means success. ! * ! * @Note: ! * Only the glyph loader and debugger should call this function. ! */ FT_LOCAL_DEF( FT_Error ) TT_Load_Context( TT_ExecContext exec, TT_Face face, TT_Size size ) {
*** 465,491 **** return FT_Err_Ok; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* TT_Save_Context */ ! /* */ ! /* <Description> */ ! /* Saves the code ranges in a `size' object. */ ! /* */ ! /* <Input> */ ! /* exec :: A handle to the source execution context. */ ! /* */ ! /* <InOut> */ ! /* size :: A handle to the target size object. */ ! /* */ ! /* <Note> */ ! /* Only the glyph loader and debugger should call this function. */ ! /* */ FT_LOCAL_DEF( void ) TT_Save_Context( TT_ExecContext exec, TT_Size size ) { FT_Int i; --- 486,514 ---- return FT_Err_Ok; } ! /************************************************************************** ! * ! * @Function: ! * TT_Save_Context ! * ! * @Description: ! * Saves the code ranges in a `size' object. ! * ! * @Input: ! * exec :: ! * A handle to the source execution context. ! * ! * @InOut: ! * size :: ! * A handle to the target size object. ! * ! * @Note: ! * Only the glyph loader and debugger should call this function. ! */ FT_LOCAL_DEF( void ) TT_Save_Context( TT_ExecContext exec, TT_Size size ) { FT_Int i;
*** 503,533 **** for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) size->codeRangeTable[i] = exec->codeRangeTable[i]; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* TT_Run_Context */ ! /* */ ! /* <Description> */ ! /* Executes one or more instructions in the execution context. */ ! /* */ ! /* <Input> */ ! /* debug :: A Boolean flag. If set, the function sets some internal */ ! /* variables and returns immediately, otherwise TT_RunIns() */ ! /* is called. */ ! /* */ ! /* This is commented out currently. */ ! /* */ ! /* <Input> */ ! /* exec :: A handle to the target execution context. */ ! /* */ ! /* <Return> */ ! /* TrueType error code. 0 means success. */ ! /* */ FT_LOCAL_DEF( FT_Error ) TT_Run_Context( TT_ExecContext exec ) { TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ); --- 526,550 ---- for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) size->codeRangeTable[i] = exec->codeRangeTable[i]; } ! /************************************************************************** ! * ! * @Function: ! * TT_Run_Context ! * ! * @Description: ! * Executes one or more instructions in the execution context. ! * ! * @Input: ! * exec :: ! * A handle to the target execution context. ! * ! * @Return: ! * TrueType error code. 0 means success. ! */ FT_LOCAL_DEF( FT_Error ) TT_Run_Context( TT_ExecContext exec ) { TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 );
*** 607,632 **** Fail: return NULL; } ! /*************************************************************************/ ! /* */ ! /* Before an opcode is executed, the interpreter verifies that there are */ ! /* enough arguments on the stack, with the help of the `Pop_Push_Count' */ ! /* table. */ ! /* */ ! /* For each opcode, the first column gives the number of arguments that */ ! /* are popped from the stack; the second one gives the number of those */ ! /* that are pushed in result. */ ! /* */ ! /* Opcodes which have a varying number of parameters in the data stream */ ! /* (NPUSHB, NPUSHW) are handled specially; they have a negative value in */ ! /* the `opcode_length' table, and the value in `Pop_Push_Count' is set */ ! /* to zero. */ ! /* */ ! /*************************************************************************/ #undef PACK #define PACK( x, y ) ( ( x << 4 ) | y ) --- 624,649 ---- Fail: return NULL; } ! /************************************************************************** ! * ! * Before an opcode is executed, the interpreter verifies that there are ! * enough arguments on the stack, with the help of the `Pop_Push_Count' ! * table. ! * ! * For each opcode, the first column gives the number of arguments that ! * are popped from the stack; the second one gives the number of those ! * that are pushed in result. ! * ! * Opcodes which have a varying number of parameters in the data stream ! * (NPUSHB, NPUSHW) are handled specially; they have a negative value in ! * the `opcode_length' table, and the value in `Pop_Push_Count' is set ! * to zero. ! * ! */ #undef PACK #define PACK( x, y ) ( ( x << 4 ) | y )
*** 1127,1203 **** "8 PushW[4]", "8 PushW[5]", "8 PushW[6]", "8 PushW[7]", ! "8 MDRP[00]", ! "8 MDRP[01]", ! "8 MDRP[02]", ! "8 MDRP[03]", ! "8 MDRP[04]", ! "8 MDRP[05]", ! "8 MDRP[06]", ! "8 MDRP[07]", ! "8 MDRP[08]", ! "8 MDRP[09]", ! "8 MDRP[10]", ! "8 MDRP[11]", ! "8 MDRP[12]", ! "8 MDRP[13]", ! "8 MDRP[14]", ! "8 MDRP[15]", ! ! "8 MDRP[16]", ! "8 MDRP[17]", ! "8 MDRP[18]", ! "8 MDRP[19]", ! "8 MDRP[20]", ! "8 MDRP[21]", ! "8 MDRP[22]", ! "8 MDRP[23]", ! "8 MDRP[24]", ! "8 MDRP[25]", ! "8 MDRP[26]", ! "8 MDRP[27]", ! "8 MDRP[28]", ! "8 MDRP[29]", ! "8 MDRP[30]", ! "8 MDRP[31]", ! ! "8 MIRP[00]", ! "8 MIRP[01]", ! "8 MIRP[02]", ! "8 MIRP[03]", ! "8 MIRP[04]", ! "8 MIRP[05]", ! "8 MIRP[06]", ! "8 MIRP[07]", ! "8 MIRP[08]", ! "8 MIRP[09]", ! "8 MIRP[10]", ! "8 MIRP[11]", ! "8 MIRP[12]", ! "8 MIRP[13]", ! "8 MIRP[14]", ! "8 MIRP[15]", ! ! "8 MIRP[16]", ! "8 MIRP[17]", ! "8 MIRP[18]", ! "8 MIRP[19]", ! "8 MIRP[20]", ! "8 MIRP[21]", ! "8 MIRP[22]", ! "8 MIRP[23]", ! "8 MIRP[24]", ! "8 MIRP[25]", ! "8 MIRP[26]", ! "8 MIRP[27]", ! "8 MIRP[28]", ! "8 MIRP[29]", ! "8 MIRP[30]", ! "8 MIRP[31]" }; #endif /* FT_DEBUG_LEVEL_TRACE */ --- 1144,1220 ---- "8 PushW[4]", "8 PushW[5]", "8 PushW[6]", "8 PushW[7]", ! "7 MDRP[G]", ! "7 MDRP[B]", ! "7 MDRP[W]", ! "7 MDRP[?]", ! "8 MDRP[rG]", ! "8 MDRP[rB]", ! "8 MDRP[rW]", ! "8 MDRP[r?]", ! "8 MDRP[mG]", ! "8 MDRP[mB]", ! "8 MDRP[mW]", ! "8 MDRP[m?]", ! "9 MDRP[mrG]", ! "9 MDRP[mrB]", ! "9 MDRP[mrW]", ! "9 MDRP[mr?]", ! ! "8 MDRP[pG]", ! "8 MDRP[pB]", ! "8 MDRP[pW]", ! "8 MDRP[p?]", ! "9 MDRP[prG]", ! "9 MDRP[prB]", ! "9 MDRP[prW]", ! "9 MDRP[pr?]", ! "9 MDRP[pmG]", ! "9 MDRP[pmB]", ! "9 MDRP[pmW]", ! "9 MDRP[pm?]", ! "A MDRP[pmrG]", ! "A MDRP[pmrB]", ! "A MDRP[pmrW]", ! "A MDRP[pmr?]", ! ! "7 MIRP[G]", ! "7 MIRP[B]", ! "7 MIRP[W]", ! "7 MIRP[?]", ! "8 MIRP[rG]", ! "8 MIRP[rB]", ! "8 MIRP[rW]", ! "8 MIRP[r?]", ! "8 MIRP[mG]", ! "8 MIRP[mB]", ! "8 MIRP[mW]", ! "8 MIRP[m?]", ! "9 MIRP[mrG]", ! "9 MIRP[mrB]", ! "9 MIRP[mrW]", ! "9 MIRP[mr?]", ! ! "8 MIRP[pG]", ! "8 MIRP[pB]", ! "8 MIRP[pW]", ! "8 MIRP[p?]", ! "9 MIRP[prG]", ! "9 MIRP[prB]", ! "9 MIRP[prW]", ! "9 MIRP[pr?]", ! "9 MIRP[pmG]", ! "9 MIRP[pmB]", ! "9 MIRP[pmW]", ! "9 MIRP[pm?]", ! "A MIRP[pmrG]", ! "A MIRP[pmrB]", ! "A MIRP[pmrW]", ! "A MIRP[pmr?]" }; #endif /* FT_DEBUG_LEVEL_TRACE */
*** 1446,1467 **** } #endif /* TT_DotFix14 */ ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Current_Ratio */ ! /* */ ! /* <Description> */ ! /* Returns the current aspect ratio scaling factor depending on the */ ! /* projection vector's state and device resolutions. */ ! /* */ ! /* <Return> */ ! /* The aspect ratio in 16.16 format, always <= 1.0 . */ ! /* */ static FT_Long Current_Ratio( TT_ExecContext exc ) { if ( !exc->tt_metrics.ratio ) { --- 1463,1484 ---- } #endif /* TT_DotFix14 */ ! /************************************************************************** ! * ! * @Function: ! * Current_Ratio ! * ! * @Description: ! * Returns the current aspect ratio scaling factor depending on the ! * projection vector's state and device resolutions. ! * ! * @Return: ! * The aspect ratio in 16.16 format, always <= 1.0 . ! */ static FT_Long Current_Ratio( TT_ExecContext exc ) { if ( !exc->tt_metrics.ratio ) {
*** 1499,1513 **** { return FT_MulFix( exc->tt_metrics.ppem, Current_Ratio( exc ) ); } ! /*************************************************************************/ ! /* */ ! /* Functions related to the control value table (CVT). */ ! /* */ ! /*************************************************************************/ FT_CALLBACK_DEF( FT_F26Dot6 ) Read_CVT( TT_ExecContext exc, FT_ULong idx ) --- 1516,1530 ---- { return FT_MulFix( exc->tt_metrics.ppem, Current_Ratio( exc ) ); } ! /************************************************************************** ! * ! * Functions related to the control value table (CVT). ! * ! */ FT_CALLBACK_DEF( FT_F26Dot6 ) Read_CVT( TT_ExecContext exc, FT_ULong idx )
*** 1545,1608 **** FT_CALLBACK_DEF( void ) Move_CVT( TT_ExecContext exc, FT_ULong idx, FT_F26Dot6 value ) { ! exc->cvt[idx] += value; } FT_CALLBACK_DEF( void ) Move_CVT_Stretched( TT_ExecContext exc, FT_ULong idx, FT_F26Dot6 value ) { ! exc->cvt[idx] += FT_DivFix( value, Current_Ratio( exc ) ); } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* GetShortIns */ ! /* */ ! /* <Description> */ ! /* Returns a short integer taken from the instruction stream at */ ! /* address IP. */ ! /* */ ! /* <Return> */ ! /* Short read at code[IP]. */ ! /* */ ! /* <Note> */ ! /* This one could become a macro. */ ! /* */ static FT_Short GetShortIns( TT_ExecContext exc ) { /* Reading a byte stream so there is no endianness (DaveP) */ exc->IP += 2; return (FT_Short)( ( exc->code[exc->IP - 2] << 8 ) + exc->code[exc->IP - 1] ); } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Ins_Goto_CodeRange */ ! /* */ ! /* <Description> */ ! /* Goes to a certain code range in the instruction stream. */ ! /* */ ! /* <Input> */ ! /* aRange :: The index of the code range. */ ! /* */ ! /* aIP :: The new IP address in the code range. */ ! /* */ ! /* <Return> */ ! /* SUCCESS or FAILURE. */ ! /* */ static FT_Bool Ins_Goto_CodeRange( TT_ExecContext exc, FT_Int aRange, FT_Long aIP ) { --- 1562,1628 ---- FT_CALLBACK_DEF( void ) Move_CVT( TT_ExecContext exc, FT_ULong idx, FT_F26Dot6 value ) { ! exc->cvt[idx] = ADD_LONG( exc->cvt[idx], value ); } FT_CALLBACK_DEF( void ) Move_CVT_Stretched( TT_ExecContext exc, FT_ULong idx, FT_F26Dot6 value ) { ! exc->cvt[idx] = ADD_LONG( exc->cvt[idx], ! FT_DivFix( value, Current_Ratio( exc ) ) ); } ! /************************************************************************** ! * ! * @Function: ! * GetShortIns ! * ! * @Description: ! * Returns a short integer taken from the instruction stream at ! * address IP. ! * ! * @Return: ! * Short read at code[IP]. ! * ! * @Note: ! * This one could become a macro. ! */ static FT_Short GetShortIns( TT_ExecContext exc ) { /* Reading a byte stream so there is no endianness (DaveP) */ exc->IP += 2; return (FT_Short)( ( exc->code[exc->IP - 2] << 8 ) + exc->code[exc->IP - 1] ); } ! /************************************************************************** ! * ! * @Function: ! * Ins_Goto_CodeRange ! * ! * @Description: ! * Goes to a certain code range in the instruction stream. ! * ! * @Input: ! * aRange :: ! * The index of the code range. ! * ! * aIP :: ! * The new IP address in the code range. ! * ! * @Return: ! * SUCCESS or FAILURE. ! */ static FT_Bool Ins_Goto_CodeRange( TT_ExecContext exc, FT_Int aRange, FT_Long aIP ) {
*** 1640,1670 **** return SUCCESS; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Direct_Move */ ! /* */ ! /* <Description> */ ! /* Moves a point by a given distance along the freedom vector. The */ ! /* point will be `touched'. */ ! /* */ ! /* <Input> */ ! /* point :: The index of the point to move. */ ! /* */ ! /* distance :: The distance to apply. */ ! /* */ ! /* <InOut> */ ! /* zone :: The affected glyph zone. */ ! /* */ ! /* <Note> */ ! /* See `ttinterp.h' for details on backward compatibility mode. */ ! /* `Touches' the point. */ ! /* */ static void Direct_Move( TT_ExecContext exc, TT_GlyphZone zone, FT_UShort point, FT_F26Dot6 distance ) --- 1660,1693 ---- return SUCCESS; } ! /************************************************************************** ! * ! * @Function: ! * Direct_Move ! * ! * @Description: ! * Moves a point by a given distance along the freedom vector. The ! * point will be `touched'. ! * ! * @Input: ! * point :: ! * The index of the point to move. ! * ! * distance :: ! * The distance to apply. ! * ! * @InOut: ! * zone :: ! * The affected glyph zone. ! * ! * @Note: ! * See `ttinterp.h' for details on backward compatibility mode. ! * `Touches' the point. ! */ static void Direct_Move( TT_ExecContext exc, TT_GlyphZone zone, FT_UShort point, FT_F26Dot6 distance )
*** 1726,1752 **** zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Direct_Move_Orig */ ! /* */ ! /* <Description> */ ! /* Moves the *original* position of a point by a given distance along */ ! /* the freedom vector. Obviously, the point will not be `touched'. */ ! /* */ ! /* <Input> */ ! /* point :: The index of the point to move. */ ! /* */ ! /* distance :: The distance to apply. */ ! /* */ ! /* <InOut> */ ! /* zone :: The affected glyph zone. */ ! /* */ static void Direct_Move_Orig( TT_ExecContext exc, TT_GlyphZone zone, FT_UShort point, FT_F26Dot6 distance ) --- 1749,1778 ---- zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } } ! /************************************************************************** ! * ! * @Function: ! * Direct_Move_Orig ! * ! * @Description: ! * Moves the *original* position of a point by a given distance along ! * the freedom vector. Obviously, the point will not be `touched'. ! * ! * @Input: ! * point :: ! * The index of the point to move. ! * ! * distance :: ! * The distance to apply. ! * ! * @InOut: ! * zone :: ! * The affected glyph zone. ! */ static void Direct_Move_Orig( TT_ExecContext exc, TT_GlyphZone zone, FT_UShort point, FT_F26Dot6 distance )
*** 1770,1788 **** v, exc->F_dot_P ) ); } ! /*************************************************************************/ ! /* */ ! /* Special versions of Direct_Move() */ ! /* */ ! /* The following versions are used whenever both vectors are both */ ! /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ ! /* See `ttinterp.h' for details on backward compatibility mode. */ ! /* */ ! /*************************************************************************/ static void Direct_Move_X( TT_ExecContext exc, TT_GlyphZone zone, --- 1796,1814 ---- v, exc->F_dot_P ) ); } ! /************************************************************************** ! * ! * Special versions of Direct_Move() ! * ! * The following versions are used whenever both vectors are both ! * along one of the coordinate unit vectors, i.e. in 90% of the cases. ! * See `ttinterp.h' for details on backward compatibility mode. ! * ! */ static void Direct_Move_X( TT_ExecContext exc, TT_GlyphZone zone,
*** 1825,1842 **** zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } ! /*************************************************************************/ ! /* */ ! /* Special versions of Direct_Move_Orig() */ ! /* */ ! /* The following versions are used whenever both vectors are both */ ! /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ ! /* */ ! /*************************************************************************/ static void Direct_Move_Orig_X( TT_ExecContext exc, TT_GlyphZone zone, --- 1851,1868 ---- zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } ! /************************************************************************** ! * ! * Special versions of Direct_Move_Orig() ! * ! * The following versions are used whenever both vectors are both ! * along one of the coordinate unit vectors, i.e. in 90% of the cases. ! * ! */ static void Direct_Move_Orig_X( TT_ExecContext exc, TT_GlyphZone zone,
*** 1859,1890 **** zone->org[point].y = ADD_LONG( zone->org[point].y, distance ); } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Round_None */ ! /* */ ! /* <Description> */ ! /* Does not round, but adds engine compensation. */ ! /* */ ! /* <Input> */ ! /* distance :: The distance (not) to round. */ ! /* */ ! /* compensation :: The engine compensation. */ ! /* */ ! /* <Return> */ ! /* The compensated distance. */ ! /* */ ! /* <Note> */ ! /* The TrueType specification says very few about the relationship */ ! /* between rounding and engine compensation. However, it seems from */ ! /* the description of super round that we should add the compensation */ ! /* before rounding. */ ! /* */ static FT_F26Dot6 Round_None( TT_ExecContext exc, FT_F26Dot6 distance, FT_F26Dot6 compensation ) { --- 1885,1918 ---- zone->org[point].y = ADD_LONG( zone->org[point].y, distance ); } ! /************************************************************************** ! * ! * @Function: ! * Round_None ! * ! * @Description: ! * Does not round, but adds engine compensation. ! * ! * @Input: ! * distance :: ! * The distance (not) to round. ! * ! * compensation :: ! * The engine compensation. ! * ! * @Return: ! * The compensated distance. ! * ! * @Note: ! * The TrueType specification says very few about the relationship ! * between rounding and engine compensation. However, it seems from ! * the description of super round that we should add the compensation ! * before rounding. ! */ static FT_F26Dot6 Round_None( TT_ExecContext exc, FT_F26Dot6 distance, FT_F26Dot6 compensation ) {
*** 1907,1932 **** } return val; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Round_To_Grid */ ! /* */ ! /* <Description> */ ! /* Rounds value to grid after adding engine compensation. */ ! /* */ ! /* <Input> */ ! /* distance :: The distance to round. */ ! /* */ ! /* compensation :: The engine compensation. */ ! /* */ ! /* <Return> */ ! /* Rounded distance. */ ! /* */ static FT_F26Dot6 Round_To_Grid( TT_ExecContext exc, FT_F26Dot6 distance, FT_F26Dot6 compensation ) { --- 1935,1962 ---- } return val; } ! /************************************************************************** ! * ! * @Function: ! * Round_To_Grid ! * ! * @Description: ! * Rounds value to grid after adding engine compensation. ! * ! * @Input: ! * distance :: ! * The distance to round. ! * ! * compensation :: ! * The engine compensation. ! * ! * @Return: ! * Rounded distance. ! */ static FT_F26Dot6 Round_To_Grid( TT_ExecContext exc, FT_F26Dot6 distance, FT_F26Dot6 compensation ) {
*** 1951,1976 **** return val; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Round_To_Half_Grid */ ! /* */ ! /* <Description> */ ! /* Rounds value to half grid after adding engine compensation. */ ! /* */ ! /* <Input> */ ! /* distance :: The distance to round. */ ! /* */ ! /* compensation :: The engine compensation. */ ! /* */ ! /* <Return> */ ! /* Rounded distance. */ ! /* */ static FT_F26Dot6 Round_To_Half_Grid( TT_ExecContext exc, FT_F26Dot6 distance, FT_F26Dot6 compensation ) { --- 1981,2008 ---- return val; } ! /************************************************************************** ! * ! * @Function: ! * Round_To_Half_Grid ! * ! * @Description: ! * Rounds value to half grid after adding engine compensation. ! * ! * @Input: ! * distance :: ! * The distance to round. ! * ! * compensation :: ! * The engine compensation. ! * ! * @Return: ! * Rounded distance. ! */ static FT_F26Dot6 Round_To_Half_Grid( TT_ExecContext exc, FT_F26Dot6 distance, FT_F26Dot6 compensation ) {
*** 1997,2022 **** return val; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Round_Down_To_Grid */ ! /* */ ! /* <Description> */ ! /* Rounds value down to grid after adding engine compensation. */ ! /* */ ! /* <Input> */ ! /* distance :: The distance to round. */ ! /* */ ! /* compensation :: The engine compensation. */ ! /* */ ! /* <Return> */ ! /* Rounded distance. */ ! /* */ static FT_F26Dot6 Round_Down_To_Grid( TT_ExecContext exc, FT_F26Dot6 distance, FT_F26Dot6 compensation ) { --- 2029,2056 ---- return val; } ! /************************************************************************** ! * ! * @Function: ! * Round_Down_To_Grid ! * ! * @Description: ! * Rounds value down to grid after adding engine compensation. ! * ! * @Input: ! * distance :: ! * The distance to round. ! * ! * compensation :: ! * The engine compensation. ! * ! * @Return: ! * Rounded distance. ! */ static FT_F26Dot6 Round_Down_To_Grid( TT_ExecContext exc, FT_F26Dot6 distance, FT_F26Dot6 compensation ) {
*** 2040,2065 **** return val; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Round_Up_To_Grid */ ! /* */ ! /* <Description> */ ! /* Rounds value up to grid after adding engine compensation. */ ! /* */ ! /* <Input> */ ! /* distance :: The distance to round. */ ! /* */ ! /* compensation :: The engine compensation. */ ! /* */ ! /* <Return> */ ! /* Rounded distance. */ ! /* */ static FT_F26Dot6 Round_Up_To_Grid( TT_ExecContext exc, FT_F26Dot6 distance, FT_F26Dot6 compensation ) { --- 2074,2101 ---- return val; } ! /************************************************************************** ! * ! * @Function: ! * Round_Up_To_Grid ! * ! * @Description: ! * Rounds value up to grid after adding engine compensation. ! * ! * @Input: ! * distance :: ! * The distance to round. ! * ! * compensation :: ! * The engine compensation. ! * ! * @Return: ! * Rounded distance. ! */ static FT_F26Dot6 Round_Up_To_Grid( TT_ExecContext exc, FT_F26Dot6 distance, FT_F26Dot6 compensation ) {
*** 2084,2109 **** return val; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Round_To_Double_Grid */ ! /* */ ! /* <Description> */ ! /* Rounds value to double grid after adding engine compensation. */ ! /* */ ! /* <Input> */ ! /* distance :: The distance to round. */ ! /* */ ! /* compensation :: The engine compensation. */ ! /* */ ! /* <Return> */ ! /* Rounded distance. */ ! /* */ static FT_F26Dot6 Round_To_Double_Grid( TT_ExecContext exc, FT_F26Dot6 distance, FT_F26Dot6 compensation ) { --- 2120,2147 ---- return val; } ! /************************************************************************** ! * ! * @Function: ! * Round_To_Double_Grid ! * ! * @Description: ! * Rounds value to double grid after adding engine compensation. ! * ! * @Input: ! * distance :: ! * The distance to round. ! * ! * compensation :: ! * The engine compensation. ! * ! * @Return: ! * Rounded distance. ! */ static FT_F26Dot6 Round_To_Double_Grid( TT_ExecContext exc, FT_F26Dot6 distance, FT_F26Dot6 compensation ) {
*** 2128,2159 **** return val; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Round_Super */ ! /* */ ! /* <Description> */ ! /* Super-rounds value to grid after adding engine compensation. */ ! /* */ ! /* <Input> */ ! /* distance :: The distance to round. */ ! /* */ ! /* compensation :: The engine compensation. */ ! /* */ ! /* <Return> */ ! /* Rounded distance. */ ! /* */ ! /* <Note> */ ! /* The TrueType specification says very little about the relationship */ ! /* between rounding and engine compensation. However, it seems from */ ! /* the description of super round that we should add the compensation */ ! /* before rounding. */ ! /* */ static FT_F26Dot6 Round_Super( TT_ExecContext exc, FT_F26Dot6 distance, FT_F26Dot6 compensation ) { --- 2166,2199 ---- return val; } ! /************************************************************************** ! * ! * @Function: ! * Round_Super ! * ! * @Description: ! * Super-rounds value to grid after adding engine compensation. ! * ! * @Input: ! * distance :: ! * The distance to round. ! * ! * compensation :: ! * The engine compensation. ! * ! * @Return: ! * Rounded distance. ! * ! * @Note: ! * The TrueType specification says very little about the relationship ! * between rounding and engine compensation. However, it seems from ! * the description of super round that we should add the compensation ! * before rounding. ! */ static FT_F26Dot6 Round_Super( TT_ExecContext exc, FT_F26Dot6 distance, FT_F26Dot6 compensation ) {
*** 2181,2210 **** return val; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Round_Super_45 */ ! /* */ ! /* <Description> */ ! /* Super-rounds value to grid after adding engine compensation. */ ! /* */ ! /* <Input> */ ! /* distance :: The distance to round. */ ! /* */ ! /* compensation :: The engine compensation. */ ! /* */ ! /* <Return> */ ! /* Rounded distance. */ ! /* */ ! /* <Note> */ ! /* There is a separate function for Round_Super_45() as we may need */ ! /* greater precision. */ ! /* */ static FT_F26Dot6 Round_Super_45( TT_ExecContext exc, FT_F26Dot6 distance, FT_F26Dot6 compensation ) { --- 2221,2252 ---- return val; } ! /************************************************************************** ! * ! * @Function: ! * Round_Super_45 ! * ! * @Description: ! * Super-rounds value to grid after adding engine compensation. ! * ! * @Input: ! * distance :: ! * The distance to round. ! * ! * compensation :: ! * The engine compensation. ! * ! * @Return: ! * Rounded distance. ! * ! * @Note: ! * There is a separate function for Round_Super_45() as we may need ! * greater precision. ! */ static FT_F26Dot6 Round_Super_45( TT_ExecContext exc, FT_F26Dot6 distance, FT_F26Dot6 compensation ) {
*** 2232,2252 **** return val; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Compute_Round */ ! /* */ ! /* <Description> */ ! /* Sets the rounding mode. */ ! /* */ ! /* <Input> */ ! /* round_mode :: The rounding mode to be used. */ ! /* */ static void Compute_Round( TT_ExecContext exc, FT_Byte round_mode ) { switch ( round_mode ) --- 2274,2295 ---- return val; } ! /************************************************************************** ! * ! * @Function: ! * Compute_Round ! * ! * @Description: ! * Sets the rounding mode. ! * ! * @Input: ! * round_mode :: ! * The rounding mode to be used. ! */ static void Compute_Round( TT_ExecContext exc, FT_Byte round_mode ) { switch ( round_mode )
*** 2284,2306 **** break; } } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* SetSuperRound */ ! /* */ ! /* <Description> */ ! /* Sets Super Round parameters. */ ! /* */ ! /* <Input> */ ! /* GridPeriod :: The grid period. */ ! /* */ ! /* selector :: The SROUND opcode. */ ! /* */ static void SetSuperRound( TT_ExecContext exc, FT_F2Dot14 GridPeriod, FT_Long selector ) { --- 2327,2351 ---- break; } } ! /************************************************************************** ! * ! * @Function: ! * SetSuperRound ! * ! * @Description: ! * Sets Super Round parameters. ! * ! * @Input: ! * GridPeriod :: ! * The grid period. ! * ! * selector :: ! * The SROUND opcode. ! */ static void SetSuperRound( TT_ExecContext exc, FT_F2Dot14 GridPeriod, FT_Long selector ) {
*** 2353,2378 **** exc->phase >>= 8; exc->threshold >>= 8; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Project */ ! /* */ ! /* <Description> */ ! /* Computes the projection of vector given by (v2-v1) along the */ ! /* current projection vector. */ ! /* */ ! /* <Input> */ ! /* v1 :: First input vector. */ ! /* v2 :: Second input vector. */ ! /* */ ! /* <Return> */ ! /* The distance in F26dot6 format. */ ! /* */ static FT_F26Dot6 Project( TT_ExecContext exc, FT_Pos dx, FT_Pos dy ) { --- 2398,2425 ---- exc->phase >>= 8; exc->threshold >>= 8; } ! /************************************************************************** ! * ! * @Function: ! * Project ! * ! * @Description: ! * Computes the projection of vector given by (v2-v1) along the ! * current projection vector. ! * ! * @Input: ! * v1 :: ! * First input vector. ! * v2 :: ! * Second input vector. ! * ! * @Return: ! * The distance in F26dot6 format. ! */ static FT_F26Dot6 Project( TT_ExecContext exc, FT_Pos dx, FT_Pos dy ) {
*** 2380,2405 **** exc->GS.projVector.x, exc->GS.projVector.y ); } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Dual_Project */ ! /* */ ! /* <Description> */ ! /* Computes the projection of the vector given by (v2-v1) along the */ ! /* current dual vector. */ ! /* */ ! /* <Input> */ ! /* v1 :: First input vector. */ ! /* v2 :: Second input vector. */ ! /* */ ! /* <Return> */ ! /* The distance in F26dot6 format. */ ! /* */ static FT_F26Dot6 Dual_Project( TT_ExecContext exc, FT_Pos dx, FT_Pos dy ) { --- 2427,2454 ---- exc->GS.projVector.x, exc->GS.projVector.y ); } ! /************************************************************************** ! * ! * @Function: ! * Dual_Project ! * ! * @Description: ! * Computes the projection of the vector given by (v2-v1) along the ! * current dual vector. ! * ! * @Input: ! * v1 :: ! * First input vector. ! * v2 :: ! * Second input vector. ! * ! * @Return: ! * The distance in F26dot6 format. ! */ static FT_F26Dot6 Dual_Project( TT_ExecContext exc, FT_Pos dx, FT_Pos dy ) {
*** 2407,2432 **** exc->GS.dualVector.x, exc->GS.dualVector.y ); } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Project_x */ ! /* */ ! /* <Description> */ ! /* Computes the projection of the vector given by (v2-v1) along the */ ! /* horizontal axis. */ ! /* */ ! /* <Input> */ ! /* v1 :: First input vector. */ ! /* v2 :: Second input vector. */ ! /* */ ! /* <Return> */ ! /* The distance in F26dot6 format. */ ! /* */ static FT_F26Dot6 Project_x( TT_ExecContext exc, FT_Pos dx, FT_Pos dy ) { --- 2456,2483 ---- exc->GS.dualVector.x, exc->GS.dualVector.y ); } ! /************************************************************************** ! * ! * @Function: ! * Project_x ! * ! * @Description: ! * Computes the projection of the vector given by (v2-v1) along the ! * horizontal axis. ! * ! * @Input: ! * v1 :: ! * First input vector. ! * v2 :: ! * Second input vector. ! * ! * @Return: ! * The distance in F26dot6 format. ! */ static FT_F26Dot6 Project_x( TT_ExecContext exc, FT_Pos dx, FT_Pos dy ) {
*** 2435,2460 **** return dx; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Project_y */ ! /* */ ! /* <Description> */ ! /* Computes the projection of the vector given by (v2-v1) along the */ ! /* vertical axis. */ ! /* */ ! /* <Input> */ ! /* v1 :: First input vector. */ ! /* v2 :: Second input vector. */ ! /* */ ! /* <Return> */ ! /* The distance in F26dot6 format. */ ! /* */ static FT_F26Dot6 Project_y( TT_ExecContext exc, FT_Pos dx, FT_Pos dy ) { --- 2486,2513 ---- return dx; } ! /************************************************************************** ! * ! * @Function: ! * Project_y ! * ! * @Description: ! * Computes the projection of the vector given by (v2-v1) along the ! * vertical axis. ! * ! * @Input: ! * v1 :: ! * First input vector. ! * v2 :: ! * Second input vector. ! * ! * @Return: ! * The distance in F26dot6 format. ! */ static FT_F26Dot6 Project_y( TT_ExecContext exc, FT_Pos dx, FT_Pos dy ) {
*** 2463,2481 **** return dy; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Compute_Funcs */ ! /* */ ! /* <Description> */ ! /* Computes the projection and movement function pointers according */ ! /* to the current graphics state. */ ! /* */ static void Compute_Funcs( TT_ExecContext exc ) { if ( exc->GS.freeVector.x == 0x4000 ) exc->F_dot_P = exc->GS.projVector.x; --- 2516,2534 ---- return dy; } ! /************************************************************************** ! * ! * @Function: ! * Compute_Funcs ! * ! * @Description: ! * Computes the projection and movement function pointers according ! * to the current graphics state. ! */ static void Compute_Funcs( TT_ExecContext exc ) { if ( exc->GS.freeVector.x == 0x4000 ) exc->F_dot_P = exc->GS.projVector.x;
*** 2526,2557 **** /* Disable cached aspect ratio */ exc->tt_metrics.ratio = 0; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Normalize */ ! /* */ ! /* <Description> */ ! /* Norms a vector. */ ! /* */ ! /* <Input> */ ! /* Vx :: The horizontal input vector coordinate. */ ! /* Vy :: The vertical input vector coordinate. */ ! /* */ ! /* <Output> */ ! /* R :: The normed unit vector. */ ! /* */ ! /* <Return> */ ! /* Returns FAILURE if a vector parameter is zero. */ ! /* */ ! /* <Note> */ ! /* In case Vx and Vy are both zero, `Normalize' returns SUCCESS, and */ ! /* R is undefined. */ ! /* */ static FT_Bool Normalize( FT_F26Dot6 Vx, FT_F26Dot6 Vy, FT_UnitVector* R ) { --- 2579,2613 ---- /* Disable cached aspect ratio */ exc->tt_metrics.ratio = 0; } ! /************************************************************************** ! * ! * @Function: ! * Normalize ! * ! * @Description: ! * Norms a vector. ! * ! * @Input: ! * Vx :: ! * The horizontal input vector coordinate. ! * Vy :: ! * The vertical input vector coordinate. ! * ! * @Output: ! * R :: ! * The normed unit vector. ! * ! * @Return: ! * Returns FAILURE if a vector parameter is zero. ! * ! * @Note: ! * In case Vx and Vy are both zero, `Normalize' returns SUCCESS, and ! * R is undefined. ! */ static FT_Bool Normalize( FT_F26Dot6 Vx, FT_F26Dot6 Vy, FT_UnitVector* R ) {
*** 2575,2619 **** return SUCCESS; } ! /*************************************************************************/ ! /* */ ! /* Here we start with the implementation of the various opcodes. */ ! /* */ ! /*************************************************************************/ #define ARRAY_BOUND_ERROR \ do \ { \ exc->error = FT_THROW( Invalid_Reference ); \ return; \ } while (0) ! /*************************************************************************/ ! /* */ ! /* MPPEM[]: Measure Pixel Per EM */ ! /* Opcode range: 0x4B */ ! /* Stack: --> Euint16 */ ! /* */ static void Ins_MPPEM( TT_ExecContext exc, FT_Long* args ) { args[0] = exc->func_cur_ppem( exc ); } ! /*************************************************************************/ ! /* */ ! /* MPS[]: Measure Point Size */ ! /* Opcode range: 0x4C */ ! /* Stack: --> Euint16 */ ! /* */ static void Ins_MPS( TT_ExecContext exc, FT_Long* args ) { if ( NO_SUBPIXEL_HINTING ) --- 2631,2675 ---- return SUCCESS; } ! /************************************************************************** ! * ! * Here we start with the implementation of the various opcodes. ! * ! */ #define ARRAY_BOUND_ERROR \ do \ { \ exc->error = FT_THROW( Invalid_Reference ); \ return; \ } while (0) ! /************************************************************************** ! * ! * MPPEM[]: Measure Pixel Per EM ! * Opcode range: 0x4B ! * Stack: --> Euint16 ! */ static void Ins_MPPEM( TT_ExecContext exc, FT_Long* args ) { args[0] = exc->func_cur_ppem( exc ); } ! /************************************************************************** ! * ! * MPS[]: Measure Point Size ! * Opcode range: 0x4C ! * Stack: --> Euint16 ! */ static void Ins_MPS( TT_ExecContext exc, FT_Long* args ) { if ( NO_SUBPIXEL_HINTING )
*** 2631,2685 **** args[0] = exc->pointSize; } } ! /*************************************************************************/ ! /* */ ! /* DUP[]: DUPlicate the stack's top element */ ! /* Opcode range: 0x20 */ ! /* Stack: StkElt --> StkElt StkElt */ ! /* */ static void Ins_DUP( FT_Long* args ) { args[1] = args[0]; } ! /*************************************************************************/ ! /* */ ! /* POP[]: POP the stack's top element */ ! /* Opcode range: 0x21 */ ! /* Stack: StkElt --> */ ! /* */ static void Ins_POP( void ) { /* nothing to do */ } ! /*************************************************************************/ ! /* */ ! /* CLEAR[]: CLEAR the entire stack */ ! /* Opcode range: 0x22 */ ! /* Stack: StkElt... --> */ ! /* */ static void Ins_CLEAR( TT_ExecContext exc ) { exc->new_top = 0; } ! /*************************************************************************/ ! /* */ ! /* SWAP[]: SWAP the stack's top two elements */ ! /* Opcode range: 0x23 */ ! /* Stack: 2 * StkElt --> 2 * StkElt */ ! /* */ static void Ins_SWAP( FT_Long* args ) { FT_Long L; --- 2687,2741 ---- args[0] = exc->pointSize; } } ! /************************************************************************** ! * ! * DUP[]: DUPlicate the stack's top element ! * Opcode range: 0x20 ! * Stack: StkElt --> StkElt StkElt ! */ static void Ins_DUP( FT_Long* args ) { args[1] = args[0]; } ! /************************************************************************** ! * ! * POP[]: POP the stack's top element ! * Opcode range: 0x21 ! * Stack: StkElt --> ! */ static void Ins_POP( void ) { /* nothing to do */ } ! /************************************************************************** ! * ! * CLEAR[]: CLEAR the entire stack ! * Opcode range: 0x22 ! * Stack: StkElt... --> ! */ static void Ins_CLEAR( TT_ExecContext exc ) { exc->new_top = 0; } ! /************************************************************************** ! * ! * SWAP[]: SWAP the stack's top two elements ! * Opcode range: 0x23 ! * Stack: 2 * StkElt --> 2 * StkElt ! */ static void Ins_SWAP( FT_Long* args ) { FT_Long L;
*** 2688,2888 **** args[0] = args[1]; args[1] = L; } ! /*************************************************************************/ ! /* */ ! /* DEPTH[]: return the stack DEPTH */ ! /* Opcode range: 0x24 */ ! /* Stack: --> uint32 */ ! /* */ static void Ins_DEPTH( TT_ExecContext exc, FT_Long* args ) { args[0] = exc->top; } ! /*************************************************************************/ ! /* */ ! /* LT[]: Less Than */ ! /* Opcode range: 0x50 */ ! /* Stack: int32? int32? --> bool */ ! /* */ static void Ins_LT( FT_Long* args ) { args[0] = ( args[0] < args[1] ); } ! /*************************************************************************/ ! /* */ ! /* LTEQ[]: Less Than or EQual */ ! /* Opcode range: 0x51 */ ! /* Stack: int32? int32? --> bool */ ! /* */ static void Ins_LTEQ( FT_Long* args ) { args[0] = ( args[0] <= args[1] ); } ! /*************************************************************************/ ! /* */ ! /* GT[]: Greater Than */ ! /* Opcode range: 0x52 */ ! /* Stack: int32? int32? --> bool */ ! /* */ static void Ins_GT( FT_Long* args ) { args[0] = ( args[0] > args[1] ); } ! /*************************************************************************/ ! /* */ ! /* GTEQ[]: Greater Than or EQual */ ! /* Opcode range: 0x53 */ ! /* Stack: int32? int32? --> bool */ ! /* */ static void Ins_GTEQ( FT_Long* args ) { args[0] = ( args[0] >= args[1] ); } ! /*************************************************************************/ ! /* */ ! /* EQ[]: EQual */ ! /* Opcode range: 0x54 */ ! /* Stack: StkElt StkElt --> bool */ ! /* */ static void Ins_EQ( FT_Long* args ) { args[0] = ( args[0] == args[1] ); } ! /*************************************************************************/ ! /* */ ! /* NEQ[]: Not EQual */ ! /* Opcode range: 0x55 */ ! /* Stack: StkElt StkElt --> bool */ ! /* */ static void Ins_NEQ( FT_Long* args ) { args[0] = ( args[0] != args[1] ); } ! /*************************************************************************/ ! /* */ ! /* ODD[]: Is ODD */ ! /* Opcode range: 0x56 */ ! /* Stack: f26.6 --> bool */ ! /* */ static void Ins_ODD( TT_ExecContext exc, FT_Long* args ) { args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 64 ); } ! /*************************************************************************/ ! /* */ ! /* EVEN[]: Is EVEN */ ! /* Opcode range: 0x57 */ ! /* Stack: f26.6 --> bool */ ! /* */ static void Ins_EVEN( TT_ExecContext exc, FT_Long* args ) { args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 0 ); } ! /*************************************************************************/ ! /* */ ! /* AND[]: logical AND */ ! /* Opcode range: 0x5A */ ! /* Stack: uint32 uint32 --> uint32 */ ! /* */ static void Ins_AND( FT_Long* args ) { args[0] = ( args[0] && args[1] ); } ! /*************************************************************************/ ! /* */ ! /* OR[]: logical OR */ ! /* Opcode range: 0x5B */ ! /* Stack: uint32 uint32 --> uint32 */ ! /* */ static void Ins_OR( FT_Long* args ) { args[0] = ( args[0] || args[1] ); } ! /*************************************************************************/ ! /* */ ! /* NOT[]: logical NOT */ ! /* Opcode range: 0x5C */ ! /* Stack: StkElt --> uint32 */ ! /* */ static void Ins_NOT( FT_Long* args ) { args[0] = !args[0]; } ! /*************************************************************************/ ! /* */ ! /* ADD[]: ADD */ ! /* Opcode range: 0x60 */ ! /* Stack: f26.6 f26.6 --> f26.6 */ ! /* */ static void Ins_ADD( FT_Long* args ) { args[0] = ADD_LONG( args[0], args[1] ); } ! /*************************************************************************/ ! /* */ ! /* SUB[]: SUBtract */ ! /* Opcode range: 0x61 */ ! /* Stack: f26.6 f26.6 --> f26.6 */ ! /* */ static void Ins_SUB( FT_Long* args ) { args[0] = SUB_LONG( args[0], args[1] ); } ! /*************************************************************************/ ! /* */ ! /* DIV[]: DIVide */ ! /* Opcode range: 0x62 */ ! /* Stack: f26.6 f26.6 --> f26.6 */ ! /* */ static void Ins_DIV( TT_ExecContext exc, FT_Long* args ) { if ( args[1] == 0 ) --- 2744,2944 ---- args[0] = args[1]; args[1] = L; } ! /************************************************************************** ! * ! * DEPTH[]: return the stack DEPTH ! * Opcode range: 0x24 ! * Stack: --> uint32 ! */ static void Ins_DEPTH( TT_ExecContext exc, FT_Long* args ) { args[0] = exc->top; } ! /************************************************************************** ! * ! * LT[]: Less Than ! * Opcode range: 0x50 ! * Stack: int32? int32? --> bool ! */ static void Ins_LT( FT_Long* args ) { args[0] = ( args[0] < args[1] ); } ! /************************************************************************** ! * ! * LTEQ[]: Less Than or EQual ! * Opcode range: 0x51 ! * Stack: int32? int32? --> bool ! */ static void Ins_LTEQ( FT_Long* args ) { args[0] = ( args[0] <= args[1] ); } ! /************************************************************************** ! * ! * GT[]: Greater Than ! * Opcode range: 0x52 ! * Stack: int32? int32? --> bool ! */ static void Ins_GT( FT_Long* args ) { args[0] = ( args[0] > args[1] ); } ! /************************************************************************** ! * ! * GTEQ[]: Greater Than or EQual ! * Opcode range: 0x53 ! * Stack: int32? int32? --> bool ! */ static void Ins_GTEQ( FT_Long* args ) { args[0] = ( args[0] >= args[1] ); } ! /************************************************************************** ! * ! * EQ[]: EQual ! * Opcode range: 0x54 ! * Stack: StkElt StkElt --> bool ! */ static void Ins_EQ( FT_Long* args ) { args[0] = ( args[0] == args[1] ); } ! /************************************************************************** ! * ! * NEQ[]: Not EQual ! * Opcode range: 0x55 ! * Stack: StkElt StkElt --> bool ! */ static void Ins_NEQ( FT_Long* args ) { args[0] = ( args[0] != args[1] ); } ! /************************************************************************** ! * ! * ODD[]: Is ODD ! * Opcode range: 0x56 ! * Stack: f26.6 --> bool ! */ static void Ins_ODD( TT_ExecContext exc, FT_Long* args ) { args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 64 ); } ! /************************************************************************** ! * ! * EVEN[]: Is EVEN ! * Opcode range: 0x57 ! * Stack: f26.6 --> bool ! */ static void Ins_EVEN( TT_ExecContext exc, FT_Long* args ) { args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 0 ); } ! /************************************************************************** ! * ! * AND[]: logical AND ! * Opcode range: 0x5A ! * Stack: uint32 uint32 --> uint32 ! */ static void Ins_AND( FT_Long* args ) { args[0] = ( args[0] && args[1] ); } ! /************************************************************************** ! * ! * OR[]: logical OR ! * Opcode range: 0x5B ! * Stack: uint32 uint32 --> uint32 ! */ static void Ins_OR( FT_Long* args ) { args[0] = ( args[0] || args[1] ); } ! /************************************************************************** ! * ! * NOT[]: logical NOT ! * Opcode range: 0x5C ! * Stack: StkElt --> uint32 ! */ static void Ins_NOT( FT_Long* args ) { args[0] = !args[0]; } ! /************************************************************************** ! * ! * ADD[]: ADD ! * Opcode range: 0x60 ! * Stack: f26.6 f26.6 --> f26.6 ! */ static void Ins_ADD( FT_Long* args ) { args[0] = ADD_LONG( args[0], args[1] ); } ! /************************************************************************** ! * ! * SUB[]: SUBtract ! * Opcode range: 0x61 ! * Stack: f26.6 f26.6 --> f26.6 ! */ static void Ins_SUB( FT_Long* args ) { args[0] = SUB_LONG( args[0], args[1] ); } ! /************************************************************************** ! * ! * DIV[]: DIVide ! * Opcode range: 0x62 ! * Stack: f26.6 f26.6 --> f26.6 ! */ static void Ins_DIV( TT_ExecContext exc, FT_Long* args ) { if ( args[1] == 0 )
*** 2890,2971 **** else args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] ); } ! /*************************************************************************/ ! /* */ ! /* MUL[]: MULtiply */ ! /* Opcode range: 0x63 */ ! /* Stack: f26.6 f26.6 --> f26.6 */ ! /* */ static void Ins_MUL( FT_Long* args ) { args[0] = FT_MulDiv( args[0], args[1], 64L ); } ! /*************************************************************************/ ! /* */ ! /* ABS[]: ABSolute value */ ! /* Opcode range: 0x64 */ ! /* Stack: f26.6 --> f26.6 */ ! /* */ static void Ins_ABS( FT_Long* args ) { if ( args[0] < 0 ) args[0] = NEG_LONG( args[0] ); } ! /*************************************************************************/ ! /* */ ! /* NEG[]: NEGate */ ! /* Opcode range: 0x65 */ ! /* Stack: f26.6 --> f26.6 */ ! /* */ static void Ins_NEG( FT_Long* args ) { args[0] = NEG_LONG( args[0] ); } ! /*************************************************************************/ ! /* */ ! /* FLOOR[]: FLOOR */ ! /* Opcode range: 0x66 */ ! /* Stack: f26.6 --> f26.6 */ ! /* */ static void Ins_FLOOR( FT_Long* args ) { args[0] = FT_PIX_FLOOR( args[0] ); } ! /*************************************************************************/ ! /* */ ! /* CEILING[]: CEILING */ ! /* Opcode range: 0x67 */ ! /* Stack: f26.6 --> f26.6 */ ! /* */ static void Ins_CEILING( FT_Long* args ) { args[0] = FT_PIX_CEIL_LONG( args[0] ); } ! /*************************************************************************/ ! /* */ ! /* RS[]: Read Store */ ! /* Opcode range: 0x43 */ ! /* Stack: uint32 --> uint32 */ ! /* */ static void Ins_RS( TT_ExecContext exc, FT_Long* args ) { FT_ULong I = (FT_ULong)args[0]; --- 2946,3027 ---- else args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] ); } ! /************************************************************************** ! * ! * MUL[]: MULtiply ! * Opcode range: 0x63 ! * Stack: f26.6 f26.6 --> f26.6 ! */ static void Ins_MUL( FT_Long* args ) { args[0] = FT_MulDiv( args[0], args[1], 64L ); } ! /************************************************************************** ! * ! * ABS[]: ABSolute value ! * Opcode range: 0x64 ! * Stack: f26.6 --> f26.6 ! */ static void Ins_ABS( FT_Long* args ) { if ( args[0] < 0 ) args[0] = NEG_LONG( args[0] ); } ! /************************************************************************** ! * ! * NEG[]: NEGate ! * Opcode range: 0x65 ! * Stack: f26.6 --> f26.6 ! */ static void Ins_NEG( FT_Long* args ) { args[0] = NEG_LONG( args[0] ); } ! /************************************************************************** ! * ! * FLOOR[]: FLOOR ! * Opcode range: 0x66 ! * Stack: f26.6 --> f26.6 ! */ static void Ins_FLOOR( FT_Long* args ) { args[0] = FT_PIX_FLOOR( args[0] ); } ! /************************************************************************** ! * ! * CEILING[]: CEILING ! * Opcode range: 0x67 ! * Stack: f26.6 --> f26.6 ! */ static void Ins_CEILING( FT_Long* args ) { args[0] = FT_PIX_CEIL_LONG( args[0] ); } ! /************************************************************************** ! * ! * RS[]: Read Store ! * Opcode range: 0x43 ! * Stack: uint32 --> uint32 ! */ static void Ins_RS( TT_ExecContext exc, FT_Long* args ) { FT_ULong I = (FT_ULong)args[0];
*** 3002,3017 **** args[0] = exc->storage[I]; } } ! /*************************************************************************/ ! /* */ ! /* WS[]: Write Store */ ! /* Opcode range: 0x42 */ ! /* Stack: uint32 uint32 --> */ ! /* */ static void Ins_WS( TT_ExecContext exc, FT_Long* args ) { FT_ULong I = (FT_ULong)args[0]; --- 3058,3073 ---- args[0] = exc->storage[I]; } } ! /************************************************************************** ! * ! * WS[]: Write Store ! * Opcode range: 0x42 ! * Stack: uint32 uint32 --> ! */ static void Ins_WS( TT_ExecContext exc, FT_Long* args ) { FT_ULong I = (FT_ULong)args[0];
*** 3025,3040 **** else exc->storage[I] = args[1]; } ! /*************************************************************************/ ! /* */ ! /* WCVTP[]: Write CVT in Pixel units */ ! /* Opcode range: 0x44 */ ! /* Stack: f26.6 uint32 --> */ ! /* */ static void Ins_WCVTP( TT_ExecContext exc, FT_Long* args ) { FT_ULong I = (FT_ULong)args[0]; --- 3081,3096 ---- else exc->storage[I] = args[1]; } ! /************************************************************************** ! * ! * WCVTP[]: Write CVT in Pixel units ! * Opcode range: 0x44 ! * Stack: f26.6 uint32 --> ! */ static void Ins_WCVTP( TT_ExecContext exc, FT_Long* args ) { FT_ULong I = (FT_ULong)args[0];
*** 3048,3063 **** else exc->func_write_cvt( exc, I, args[1] ); } ! /*************************************************************************/ ! /* */ ! /* WCVTF[]: Write CVT in Funits */ ! /* Opcode range: 0x70 */ ! /* Stack: uint32 uint32 --> */ ! /* */ static void Ins_WCVTF( TT_ExecContext exc, FT_Long* args ) { FT_ULong I = (FT_ULong)args[0]; --- 3104,3119 ---- else exc->func_write_cvt( exc, I, args[1] ); } ! /************************************************************************** ! * ! * WCVTF[]: Write CVT in Funits ! * Opcode range: 0x70 ! * Stack: uint32 uint32 --> ! */ static void Ins_WCVTF( TT_ExecContext exc, FT_Long* args ) { FT_ULong I = (FT_ULong)args[0];
*** 3071,3086 **** else exc->cvt[I] = FT_MulFix( args[1], exc->tt_metrics.scale ); } ! /*************************************************************************/ ! /* */ ! /* RCVT[]: Read CVT */ ! /* Opcode range: 0x45 */ ! /* Stack: uint32 --> f26.6 */ ! /* */ static void Ins_RCVT( TT_ExecContext exc, FT_Long* args ) { FT_ULong I = (FT_ULong)args[0]; --- 3127,3142 ---- else exc->cvt[I] = FT_MulFix( args[1], exc->tt_metrics.scale ); } ! /************************************************************************** ! * ! * RCVT[]: Read CVT ! * Opcode range: 0x45 ! * Stack: uint32 --> f26.6 ! */ static void Ins_RCVT( TT_ExecContext exc, FT_Long* args ) { FT_ULong I = (FT_ULong)args[0];
*** 3096,3139 **** else args[0] = exc->func_read_cvt( exc, I ); } ! /*************************************************************************/ ! /* */ ! /* AA[]: Adjust Angle */ ! /* Opcode range: 0x7F */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_AA( void ) { /* intentionally no longer supported */ } ! /*************************************************************************/ ! /* */ ! /* DEBUG[]: DEBUG. Unsupported. */ ! /* Opcode range: 0x4F */ ! /* Stack: uint32 --> */ ! /* */ ! /* Note: The original instruction pops a value from the stack. */ ! /* */ static void Ins_DEBUG( TT_ExecContext exc ) { exc->error = FT_THROW( Debug_OpCode ); } ! /*************************************************************************/ ! /* */ ! /* ROUND[ab]: ROUND value */ ! /* Opcode range: 0x68-0x6B */ ! /* Stack: f26.6 --> f26.6 */ ! /* */ static void Ins_ROUND( TT_ExecContext exc, FT_Long* args ) { args[0] = exc->func_round( --- 3152,3195 ---- else args[0] = exc->func_read_cvt( exc, I ); } ! /************************************************************************** ! * ! * AA[]: Adjust Angle ! * Opcode range: 0x7F ! * Stack: uint32 --> ! */ static void Ins_AA( void ) { /* intentionally no longer supported */ } ! /************************************************************************** ! * ! * DEBUG[]: DEBUG. Unsupported. ! * Opcode range: 0x4F ! * Stack: uint32 --> ! * ! * Note: The original instruction pops a value from the stack. ! */ static void Ins_DEBUG( TT_ExecContext exc ) { exc->error = FT_THROW( Debug_OpCode ); } ! /************************************************************************** ! * ! * ROUND[ab]: ROUND value ! * Opcode range: 0x68-0x6B ! * Stack: f26.6 --> f26.6 ! */ static void Ins_ROUND( TT_ExecContext exc, FT_Long* args ) { args[0] = exc->func_round(
*** 3141,3156 **** args[0], exc->tt_metrics.compensations[exc->opcode - 0x68] ); } ! /*************************************************************************/ ! /* */ ! /* NROUND[ab]: No ROUNDing of value */ ! /* Opcode range: 0x6C-0x6F */ ! /* Stack: f26.6 --> f26.6 */ ! /* */ static void Ins_NROUND( TT_ExecContext exc, FT_Long* args ) { args[0] = Round_None( --- 3197,3212 ---- args[0], exc->tt_metrics.compensations[exc->opcode - 0x68] ); } ! /************************************************************************** ! * ! * NROUND[ab]: No ROUNDing of value ! * Opcode range: 0x6C-0x6F ! * Stack: f26.6 --> f26.6 ! */ static void Ins_NROUND( TT_ExecContext exc, FT_Long* args ) { args[0] = Round_None(
*** 3158,3201 **** args[0], exc->tt_metrics.compensations[exc->opcode - 0x6C] ); } ! /*************************************************************************/ ! /* */ ! /* MAX[]: MAXimum */ ! /* Opcode range: 0x8B */ ! /* Stack: int32? int32? --> int32 */ ! /* */ static void Ins_MAX( FT_Long* args ) { if ( args[1] > args[0] ) args[0] = args[1]; } ! /*************************************************************************/ ! /* */ ! /* MIN[]: MINimum */ ! /* Opcode range: 0x8C */ ! /* Stack: int32? int32? --> int32 */ ! /* */ static void Ins_MIN( FT_Long* args ) { if ( args[1] < args[0] ) args[0] = args[1]; } ! /*************************************************************************/ ! /* */ ! /* MINDEX[]: Move INDEXed element */ ! /* Opcode range: 0x26 */ ! /* Stack: int32? --> StkElt */ ! /* */ static void Ins_MINDEX( TT_ExecContext exc, FT_Long* args ) { FT_Long L, K; --- 3214,3257 ---- args[0], exc->tt_metrics.compensations[exc->opcode - 0x6C] ); } ! /************************************************************************** ! * ! * MAX[]: MAXimum ! * Opcode range: 0x8B ! * Stack: int32? int32? --> int32 ! */ static void Ins_MAX( FT_Long* args ) { if ( args[1] > args[0] ) args[0] = args[1]; } ! /************************************************************************** ! * ! * MIN[]: MINimum ! * Opcode range: 0x8C ! * Stack: int32? int32? --> int32 ! */ static void Ins_MIN( FT_Long* args ) { if ( args[1] < args[0] ) args[0] = args[1]; } ! /************************************************************************** ! * ! * MINDEX[]: Move INDEXed element ! * Opcode range: 0x26 ! * Stack: int32? --> StkElt ! */ static void Ins_MINDEX( TT_ExecContext exc, FT_Long* args ) { FT_Long L, K;
*** 3219,3234 **** exc->stack[exc->args - 1] = K; } } ! /*************************************************************************/ ! /* */ ! /* CINDEX[]: Copy INDEXed element */ ! /* Opcode range: 0x25 */ ! /* Stack: int32 --> StkElt */ ! /* */ static void Ins_CINDEX( TT_ExecContext exc, FT_Long* args ) { FT_Long L; --- 3275,3290 ---- exc->stack[exc->args - 1] = K; } } ! /************************************************************************** ! * ! * CINDEX[]: Copy INDEXed element ! * Opcode range: 0x25 ! * Stack: int32 --> StkElt ! */ static void Ins_CINDEX( TT_ExecContext exc, FT_Long* args ) { FT_Long L;
*** 3245,3260 **** else args[0] = exc->stack[exc->args - L]; } ! /*************************************************************************/ ! /* */ ! /* ROLL[]: ROLL top three elements */ ! /* Opcode range: 0x8A */ ! /* Stack: 3 * StkElt --> 3 * StkElt */ ! /* */ static void Ins_ROLL( FT_Long* args ) { FT_Long A, B, C; --- 3301,3316 ---- else args[0] = exc->stack[exc->args - L]; } ! /************************************************************************** ! * ! * ROLL[]: ROLL top three elements ! * Opcode range: 0x8A ! * Stack: 3 * StkElt --> 3 * StkElt ! */ static void Ins_ROLL( FT_Long* args ) { FT_Long A, B, C;
*** 3267,3289 **** args[1] = A; args[0] = B; } ! /*************************************************************************/ ! /* */ ! /* MANAGING THE FLOW OF CONTROL */ ! /* */ ! /*************************************************************************/ ! /*************************************************************************/ ! /* */ ! /* SLOOP[]: Set LOOP variable */ ! /* Opcode range: 0x17 */ ! /* Stack: int32? --> */ ! /* */ static void Ins_SLOOP( TT_ExecContext exc, FT_Long* args ) { if ( args[0] < 0 ) --- 3323,3345 ---- args[1] = A; args[0] = B; } ! /************************************************************************** ! * ! * MANAGING THE FLOW OF CONTROL ! * ! */ ! /************************************************************************** ! * ! * SLOOP[]: Set LOOP variable ! * Opcode range: 0x17 ! * Stack: int32? --> ! */ static void Ins_SLOOP( TT_ExecContext exc, FT_Long* args ) { if ( args[0] < 0 )
*** 3321,3336 **** exc->error = FT_THROW( Code_Overflow ); return FAILURE; } ! /*************************************************************************/ ! /* */ ! /* IF[]: IF test */ ! /* Opcode range: 0x58 */ ! /* Stack: StkElt --> */ ! /* */ static void Ins_IF( TT_ExecContext exc, FT_Long* args ) { FT_Int nIfs; --- 3377,3392 ---- exc->error = FT_THROW( Code_Overflow ); return FAILURE; } ! /************************************************************************** ! * ! * IF[]: IF test ! * Opcode range: 0x58 ! * Stack: StkElt --> ! */ static void Ins_IF( TT_ExecContext exc, FT_Long* args ) { FT_Int nIfs;
*** 3365,3380 **** } } while ( Out == 0 ); } ! /*************************************************************************/ ! /* */ ! /* ELSE[]: ELSE */ ! /* Opcode range: 0x1B */ ! /* Stack: --> */ ! /* */ static void Ins_ELSE( TT_ExecContext exc ) { FT_Int nIfs; --- 3421,3436 ---- } } while ( Out == 0 ); } ! /************************************************************************** ! * ! * ELSE[]: ELSE ! * Opcode range: 0x1B ! * Stack: --> ! */ static void Ins_ELSE( TT_ExecContext exc ) { FT_Int nIfs;
*** 3398,3426 **** } } while ( nIfs != 0 ); } ! /*************************************************************************/ ! /* */ ! /* EIF[]: End IF */ ! /* Opcode range: 0x59 */ ! /* Stack: --> */ ! /* */ static void Ins_EIF( void ) { /* nothing to do */ } ! /*************************************************************************/ ! /* */ ! /* JMPR[]: JuMP Relative */ ! /* Opcode range: 0x1C */ ! /* Stack: int32 --> */ ! /* */ static void Ins_JMPR( TT_ExecContext exc, FT_Long* args ) { if ( args[0] == 0 && exc->args == 0 ) --- 3454,3482 ---- } } while ( nIfs != 0 ); } ! /************************************************************************** ! * ! * EIF[]: End IF ! * Opcode range: 0x59 ! * Stack: --> ! */ static void Ins_EIF( void ) { /* nothing to do */ } ! /************************************************************************** ! * ! * JMPR[]: JuMP Relative ! * Opcode range: 0x1C ! * Stack: int32 --> ! */ static void Ins_JMPR( TT_ExecContext exc, FT_Long* args ) { if ( args[0] == 0 && exc->args == 0 )
*** 3446,3498 **** exc->error = FT_THROW( Execution_Too_Long ); } } ! /*************************************************************************/ ! /* */ ! /* JROT[]: Jump Relative On True */ ! /* Opcode range: 0x78 */ ! /* Stack: StkElt int32 --> */ ! /* */ static void Ins_JROT( TT_ExecContext exc, FT_Long* args ) { if ( args[1] != 0 ) Ins_JMPR( exc, args ); } ! /*************************************************************************/ ! /* */ ! /* JROF[]: Jump Relative On False */ ! /* Opcode range: 0x79 */ ! /* Stack: StkElt int32 --> */ ! /* */ static void Ins_JROF( TT_ExecContext exc, FT_Long* args ) { if ( args[1] == 0 ) Ins_JMPR( exc, args ); } ! /*************************************************************************/ ! /* */ ! /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */ ! /* */ ! /*************************************************************************/ ! /*************************************************************************/ ! /* */ ! /* FDEF[]: Function DEFinition */ ! /* Opcode range: 0x2C */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_FDEF( TT_ExecContext exc, FT_Long* args ) { FT_ULong n; --- 3502,3554 ---- exc->error = FT_THROW( Execution_Too_Long ); } } ! /************************************************************************** ! * ! * JROT[]: Jump Relative On True ! * Opcode range: 0x78 ! * Stack: StkElt int32 --> ! */ static void Ins_JROT( TT_ExecContext exc, FT_Long* args ) { if ( args[1] != 0 ) Ins_JMPR( exc, args ); } ! /************************************************************************** ! * ! * JROF[]: Jump Relative On False ! * Opcode range: 0x79 ! * Stack: StkElt int32 --> ! */ static void Ins_JROF( TT_ExecContext exc, FT_Long* args ) { if ( args[1] == 0 ) Ins_JMPR( exc, args ); } ! /************************************************************************** ! * ! * DEFINING AND USING FUNCTIONS AND INSTRUCTIONS ! * ! */ ! /************************************************************************** ! * ! * FDEF[]: Function DEFinition ! * Opcode range: 0x2C ! * Stack: uint32 --> ! */ static void Ins_FDEF( TT_ExecContext exc, FT_Long* args ) { FT_ULong n;
*** 3786,3801 **** } } } ! /*************************************************************************/ ! /* */ ! /* ENDF[]: END Function definition */ ! /* Opcode range: 0x2D */ ! /* Stack: --> */ ! /* */ static void Ins_ENDF( TT_ExecContext exc ) { TT_CallRec* pRec; --- 3842,3857 ---- } } } ! /************************************************************************** ! * ! * ENDF[]: END Function definition ! * Opcode range: 0x2D ! * Stack: --> ! */ static void Ins_ENDF( TT_ExecContext exc ) { TT_CallRec* pRec;
*** 3835,3850 **** /* valid address, and it is why we do not test */ /* the result of Ins_Goto_CodeRange() here! */ } ! /*************************************************************************/ ! /* */ ! /* CALL[]: CALL function */ ! /* Opcode range: 0x2B */ ! /* Stack: uint32? --> */ ! /* */ static void Ins_CALL( TT_ExecContext exc, FT_Long* args ) { FT_ULong F; --- 3891,3906 ---- /* valid address, and it is why we do not test */ /* the result of Ins_Goto_CodeRange() here! */ } ! /************************************************************************** ! * ! * CALL[]: CALL function ! * Opcode range: 0x2B ! * Stack: uint32? --> ! */ static void Ins_CALL( TT_ExecContext exc, FT_Long* args ) { FT_ULong F;
*** 3924,3939 **** Fail: exc->error = FT_THROW( Invalid_Reference ); } ! /*************************************************************************/ ! /* */ ! /* LOOPCALL[]: LOOP and CALL function */ ! /* Opcode range: 0x2A */ ! /* Stack: uint32? Eint16? --> */ ! /* */ static void Ins_LOOPCALL( TT_ExecContext exc, FT_Long* args ) { FT_ULong F; --- 3980,3995 ---- Fail: exc->error = FT_THROW( Invalid_Reference ); } ! /************************************************************************** ! * ! * LOOPCALL[]: LOOP and CALL function ! * Opcode range: 0x2A ! * Stack: uint32? Eint16? --> ! */ static void Ins_LOOPCALL( TT_ExecContext exc, FT_Long* args ) { FT_ULong F;
*** 4017,4032 **** Fail: exc->error = FT_THROW( Invalid_Reference ); } ! /*************************************************************************/ ! /* */ ! /* IDEF[]: Instruction DEFinition */ ! /* Opcode range: 0x89 */ ! /* Stack: Eint8 --> */ ! /* */ static void Ins_IDEF( TT_ExecContext exc, FT_Long* args ) { TT_DefRecord* def; --- 4073,4088 ---- Fail: exc->error = FT_THROW( Invalid_Reference ); } ! /************************************************************************** ! * ! * IDEF[]: Instruction DEFinition ! * Opcode range: 0x89 ! * Stack: Eint8 --> ! */ static void Ins_IDEF( TT_ExecContext exc, FT_Long* args ) { TT_DefRecord* def;
*** 4092,4114 **** } } } ! /*************************************************************************/ ! /* */ ! /* PUSHING DATA ONTO THE INTERPRETER STACK */ ! /* */ ! /*************************************************************************/ ! /*************************************************************************/ ! /* */ ! /* NPUSHB[]: PUSH N Bytes */ ! /* Opcode range: 0x40 */ ! /* Stack: --> uint32... */ ! /* */ static void Ins_NPUSHB( TT_ExecContext exc, FT_Long* args ) { FT_UShort L, K; --- 4148,4170 ---- } } } ! /************************************************************************** ! * ! * PUSHING DATA ONTO THE INTERPRETER STACK ! * ! */ ! /************************************************************************** ! * ! * NPUSHB[]: PUSH N Bytes ! * Opcode range: 0x40 ! * Stack: --> uint32... ! */ static void Ins_NPUSHB( TT_ExecContext exc, FT_Long* args ) { FT_UShort L, K;
*** 4127,4142 **** exc->new_top += L; } ! /*************************************************************************/ ! /* */ ! /* NPUSHW[]: PUSH N Words */ ! /* Opcode range: 0x41 */ ! /* Stack: --> int32... */ ! /* */ static void Ins_NPUSHW( TT_ExecContext exc, FT_Long* args ) { FT_UShort L, K; --- 4183,4198 ---- exc->new_top += L; } ! /************************************************************************** ! * ! * NPUSHW[]: PUSH N Words ! * Opcode range: 0x41 ! * Stack: --> int32... ! */ static void Ins_NPUSHW( TT_ExecContext exc, FT_Long* args ) { FT_UShort L, K;
*** 4158,4173 **** exc->step_ins = FALSE; exc->new_top += L; } ! /*************************************************************************/ ! /* */ ! /* PUSHB[abc]: PUSH Bytes */ ! /* Opcode range: 0xB0-0xB7 */ ! /* Stack: --> uint32... */ ! /* */ static void Ins_PUSHB( TT_ExecContext exc, FT_Long* args ) { FT_UShort L, K; --- 4214,4229 ---- exc->step_ins = FALSE; exc->new_top += L; } ! /************************************************************************** ! * ! * PUSHB[abc]: PUSH Bytes ! * Opcode range: 0xB0-0xB7 ! * Stack: --> uint32... ! */ static void Ins_PUSHB( TT_ExecContext exc, FT_Long* args ) { FT_UShort L, K;
*** 4184,4199 **** for ( K = 1; K <= L; K++ ) args[K - 1] = exc->code[exc->IP + K]; } ! /*************************************************************************/ ! /* */ ! /* PUSHW[abc]: PUSH Words */ ! /* Opcode range: 0xB8-0xBF */ ! /* Stack: --> int32... */ ! /* */ static void Ins_PUSHW( TT_ExecContext exc, FT_Long* args ) { FT_UShort L, K; --- 4240,4255 ---- for ( K = 1; K <= L; K++ ) args[K - 1] = exc->code[exc->IP + K]; } ! /************************************************************************** ! * ! * PUSHW[abc]: PUSH Words ! * Opcode range: 0xB8-0xBF ! * Stack: --> int32... ! */ static void Ins_PUSHW( TT_ExecContext exc, FT_Long* args ) { FT_UShort L, K;
*** 4214,4228 **** exc->step_ins = FALSE; } ! /*************************************************************************/ ! /* */ ! /* MANAGING THE GRAPHICS STATE */ ! /* */ ! /*************************************************************************/ static FT_Bool Ins_SxVTL( TT_ExecContext exc, FT_UShort aIdx1, --- 4270,4284 ---- exc->step_ins = FALSE; } ! /************************************************************************** ! * ! * MANAGING THE GRAPHICS STATE ! * ! */ static FT_Bool Ins_SxVTL( TT_ExecContext exc, FT_UShort aIdx1,
*** 4272,4295 **** return SUCCESS; } ! /*************************************************************************/ ! /* */ ! /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */ ! /* Opcode range: 0x00-0x01 */ ! /* Stack: --> */ ! /* */ ! /* SPvTCA[a]: Set PVector to Coordinate Axis */ ! /* Opcode range: 0x02-0x03 */ ! /* Stack: --> */ ! /* */ ! /* SFvTCA[a]: Set FVector to Coordinate Axis */ ! /* Opcode range: 0x04-0x05 */ ! /* Stack: --> */ ! /* */ static void Ins_SxyTCA( TT_ExecContext exc ) { FT_Short AA, BB; --- 4328,4351 ---- return SUCCESS; } ! /************************************************************************** ! * ! * SVTCA[a]: Set (F and P) Vectors to Coordinate Axis ! * Opcode range: 0x00-0x01 ! * Stack: --> ! * ! * SPvTCA[a]: Set PVector to Coordinate Axis ! * Opcode range: 0x02-0x03 ! * Stack: --> ! * ! * SFvTCA[a]: Set FVector to Coordinate Axis ! * Opcode range: 0x04-0x05 ! * Stack: --> ! */ static void Ins_SxyTCA( TT_ExecContext exc ) { FT_Short AA, BB;
*** 4316,4331 **** Compute_Funcs( exc ); } ! /*************************************************************************/ ! /* */ ! /* SPvTL[a]: Set PVector To Line */ ! /* Opcode range: 0x06-0x07 */ ! /* Stack: uint32 uint32 --> */ ! /* */ static void Ins_SPVTL( TT_ExecContext exc, FT_Long* args ) { if ( Ins_SxVTL( exc, --- 4372,4387 ---- Compute_Funcs( exc ); } ! /************************************************************************** ! * ! * SPvTL[a]: Set PVector To Line ! * Opcode range: 0x06-0x07 ! * Stack: uint32 uint32 --> ! */ static void Ins_SPVTL( TT_ExecContext exc, FT_Long* args ) { if ( Ins_SxVTL( exc,
*** 4337,4352 **** Compute_Funcs( exc ); } } ! /*************************************************************************/ ! /* */ ! /* SFvTL[a]: Set FVector To Line */ ! /* Opcode range: 0x08-0x09 */ ! /* Stack: uint32 uint32 --> */ ! /* */ static void Ins_SFVTL( TT_ExecContext exc, FT_Long* args ) { if ( Ins_SxVTL( exc, --- 4393,4408 ---- Compute_Funcs( exc ); } } ! /************************************************************************** ! * ! * SFvTL[a]: Set FVector To Line ! * Opcode range: 0x08-0x09 ! * Stack: uint32 uint32 --> ! */ static void Ins_SFVTL( TT_ExecContext exc, FT_Long* args ) { if ( Ins_SxVTL( exc,
*** 4357,4386 **** Compute_Funcs( exc ); } } ! /*************************************************************************/ ! /* */ ! /* SFvTPv[]: Set FVector To PVector */ ! /* Opcode range: 0x0E */ ! /* Stack: --> */ ! /* */ static void Ins_SFVTPV( TT_ExecContext exc ) { exc->GS.freeVector = exc->GS.projVector; Compute_Funcs( exc ); } ! /*************************************************************************/ ! /* */ ! /* SPvFS[]: Set PVector From Stack */ ! /* Opcode range: 0x0A */ ! /* Stack: f2.14 f2.14 --> */ ! /* */ static void Ins_SPVFS( TT_ExecContext exc, FT_Long* args ) { FT_Short S; --- 4413,4442 ---- Compute_Funcs( exc ); } } ! /************************************************************************** ! * ! * SFvTPv[]: Set FVector To PVector ! * Opcode range: 0x0E ! * Stack: --> ! */ static void Ins_SFVTPV( TT_ExecContext exc ) { exc->GS.freeVector = exc->GS.projVector; Compute_Funcs( exc ); } ! /************************************************************************** ! * ! * SPvFS[]: Set PVector From Stack ! * Opcode range: 0x0A ! * Stack: f2.14 f2.14 --> ! */ static void Ins_SPVFS( TT_ExecContext exc, FT_Long* args ) { FT_Short S;
*** 4398,4413 **** exc->GS.dualVector = exc->GS.projVector; Compute_Funcs( exc ); } ! /*************************************************************************/ ! /* */ ! /* SFvFS[]: Set FVector From Stack */ ! /* Opcode range: 0x0B */ ! /* Stack: f2.14 f2.14 --> */ ! /* */ static void Ins_SFVFS( TT_ExecContext exc, FT_Long* args ) { FT_Short S; --- 4454,4469 ---- exc->GS.dualVector = exc->GS.projVector; Compute_Funcs( exc ); } ! /************************************************************************** ! * ! * SFvFS[]: Set FVector From Stack ! * Opcode range: 0x0B ! * Stack: f2.14 f2.14 --> ! */ static void Ins_SFVFS( TT_ExecContext exc, FT_Long* args ) { FT_Short S;
*** 4423,4620 **** Normalize( X, Y, &exc->GS.freeVector ); Compute_Funcs( exc ); } ! /*************************************************************************/ ! /* */ ! /* GPv[]: Get Projection Vector */ ! /* Opcode range: 0x0C */ ! /* Stack: ef2.14 --> ef2.14 */ ! /* */ static void Ins_GPV( TT_ExecContext exc, FT_Long* args ) { args[0] = exc->GS.projVector.x; args[1] = exc->GS.projVector.y; } ! /*************************************************************************/ ! /* */ ! /* GFv[]: Get Freedom Vector */ ! /* Opcode range: 0x0D */ ! /* Stack: ef2.14 --> ef2.14 */ ! /* */ static void Ins_GFV( TT_ExecContext exc, FT_Long* args ) { args[0] = exc->GS.freeVector.x; args[1] = exc->GS.freeVector.y; } ! /*************************************************************************/ ! /* */ ! /* SRP0[]: Set Reference Point 0 */ ! /* Opcode range: 0x10 */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_SRP0( TT_ExecContext exc, FT_Long* args ) { exc->GS.rp0 = (FT_UShort)args[0]; } ! /*************************************************************************/ ! /* */ ! /* SRP1[]: Set Reference Point 1 */ ! /* Opcode range: 0x11 */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_SRP1( TT_ExecContext exc, FT_Long* args ) { exc->GS.rp1 = (FT_UShort)args[0]; } ! /*************************************************************************/ ! /* */ ! /* SRP2[]: Set Reference Point 2 */ ! /* Opcode range: 0x12 */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_SRP2( TT_ExecContext exc, FT_Long* args ) { exc->GS.rp2 = (FT_UShort)args[0]; } ! /*************************************************************************/ ! /* */ ! /* SMD[]: Set Minimum Distance */ ! /* Opcode range: 0x1A */ ! /* Stack: f26.6 --> */ ! /* */ static void Ins_SMD( TT_ExecContext exc, FT_Long* args ) { exc->GS.minimum_distance = args[0]; } ! /*************************************************************************/ ! /* */ ! /* SCVTCI[]: Set Control Value Table Cut In */ ! /* Opcode range: 0x1D */ ! /* Stack: f26.6 --> */ ! /* */ static void Ins_SCVTCI( TT_ExecContext exc, FT_Long* args ) { exc->GS.control_value_cutin = (FT_F26Dot6)args[0]; } ! /*************************************************************************/ ! /* */ ! /* SSWCI[]: Set Single Width Cut In */ ! /* Opcode range: 0x1E */ ! /* Stack: f26.6 --> */ ! /* */ static void Ins_SSWCI( TT_ExecContext exc, FT_Long* args ) { exc->GS.single_width_cutin = (FT_F26Dot6)args[0]; } ! /*************************************************************************/ ! /* */ ! /* SSW[]: Set Single Width */ ! /* Opcode range: 0x1F */ ! /* Stack: int32? --> */ ! /* */ static void Ins_SSW( TT_ExecContext exc, FT_Long* args ) { exc->GS.single_width_value = FT_MulFix( args[0], exc->tt_metrics.scale ); } ! /*************************************************************************/ ! /* */ ! /* FLIPON[]: Set auto-FLIP to ON */ ! /* Opcode range: 0x4D */ ! /* Stack: --> */ ! /* */ static void Ins_FLIPON( TT_ExecContext exc ) { exc->GS.auto_flip = TRUE; } ! /*************************************************************************/ ! /* */ ! /* FLIPOFF[]: Set auto-FLIP to OFF */ ! /* Opcode range: 0x4E */ ! /* Stack: --> */ ! /* */ static void Ins_FLIPOFF( TT_ExecContext exc ) { exc->GS.auto_flip = FALSE; } ! /*************************************************************************/ ! /* */ ! /* SANGW[]: Set ANGle Weight */ ! /* Opcode range: 0x7E */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_SANGW( void ) { /* instruction not supported anymore */ } ! /*************************************************************************/ ! /* */ ! /* SDB[]: Set Delta Base */ ! /* Opcode range: 0x5E */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_SDB( TT_ExecContext exc, FT_Long* args ) { exc->GS.delta_base = (FT_UShort)args[0]; } ! /*************************************************************************/ ! /* */ ! /* SDS[]: Set Delta Shift */ ! /* Opcode range: 0x5F */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_SDS( TT_ExecContext exc, FT_Long* args ) { if ( (FT_ULong)args[0] > 6UL ) --- 4479,4676 ---- Normalize( X, Y, &exc->GS.freeVector ); Compute_Funcs( exc ); } ! /************************************************************************** ! * ! * GPv[]: Get Projection Vector ! * Opcode range: 0x0C ! * Stack: ef2.14 --> ef2.14 ! */ static void Ins_GPV( TT_ExecContext exc, FT_Long* args ) { args[0] = exc->GS.projVector.x; args[1] = exc->GS.projVector.y; } ! /************************************************************************** ! * ! * GFv[]: Get Freedom Vector ! * Opcode range: 0x0D ! * Stack: ef2.14 --> ef2.14 ! */ static void Ins_GFV( TT_ExecContext exc, FT_Long* args ) { args[0] = exc->GS.freeVector.x; args[1] = exc->GS.freeVector.y; } ! /************************************************************************** ! * ! * SRP0[]: Set Reference Point 0 ! * Opcode range: 0x10 ! * Stack: uint32 --> ! */ static void Ins_SRP0( TT_ExecContext exc, FT_Long* args ) { exc->GS.rp0 = (FT_UShort)args[0]; } ! /************************************************************************** ! * ! * SRP1[]: Set Reference Point 1 ! * Opcode range: 0x11 ! * Stack: uint32 --> ! */ static void Ins_SRP1( TT_ExecContext exc, FT_Long* args ) { exc->GS.rp1 = (FT_UShort)args[0]; } ! /************************************************************************** ! * ! * SRP2[]: Set Reference Point 2 ! * Opcode range: 0x12 ! * Stack: uint32 --> ! */ static void Ins_SRP2( TT_ExecContext exc, FT_Long* args ) { exc->GS.rp2 = (FT_UShort)args[0]; } ! /************************************************************************** ! * ! * SMD[]: Set Minimum Distance ! * Opcode range: 0x1A ! * Stack: f26.6 --> ! */ static void Ins_SMD( TT_ExecContext exc, FT_Long* args ) { exc->GS.minimum_distance = args[0]; } ! /************************************************************************** ! * ! * SCVTCI[]: Set Control Value Table Cut In ! * Opcode range: 0x1D ! * Stack: f26.6 --> ! */ static void Ins_SCVTCI( TT_ExecContext exc, FT_Long* args ) { exc->GS.control_value_cutin = (FT_F26Dot6)args[0]; } ! /************************************************************************** ! * ! * SSWCI[]: Set Single Width Cut In ! * Opcode range: 0x1E ! * Stack: f26.6 --> ! */ static void Ins_SSWCI( TT_ExecContext exc, FT_Long* args ) { exc->GS.single_width_cutin = (FT_F26Dot6)args[0]; } ! /************************************************************************** ! * ! * SSW[]: Set Single Width ! * Opcode range: 0x1F ! * Stack: int32? --> ! */ static void Ins_SSW( TT_ExecContext exc, FT_Long* args ) { exc->GS.single_width_value = FT_MulFix( args[0], exc->tt_metrics.scale ); } ! /************************************************************************** ! * ! * FLIPON[]: Set auto-FLIP to ON ! * Opcode range: 0x4D ! * Stack: --> ! */ static void Ins_FLIPON( TT_ExecContext exc ) { exc->GS.auto_flip = TRUE; } ! /************************************************************************** ! * ! * FLIPOFF[]: Set auto-FLIP to OFF ! * Opcode range: 0x4E ! * Stack: --> ! */ static void Ins_FLIPOFF( TT_ExecContext exc ) { exc->GS.auto_flip = FALSE; } ! /************************************************************************** ! * ! * SANGW[]: Set ANGle Weight ! * Opcode range: 0x7E ! * Stack: uint32 --> ! */ static void Ins_SANGW( void ) { /* instruction not supported anymore */ } ! /************************************************************************** ! * ! * SDB[]: Set Delta Base ! * Opcode range: 0x5E ! * Stack: uint32 --> ! */ static void Ins_SDB( TT_ExecContext exc, FT_Long* args ) { exc->GS.delta_base = (FT_UShort)args[0]; } ! /************************************************************************** ! * ! * SDS[]: Set Delta Shift ! * Opcode range: 0x5F ! * Stack: uint32 --> ! */ static void Ins_SDS( TT_ExecContext exc, FT_Long* args ) { if ( (FT_ULong)args[0] > 6UL )
*** 4622,4719 **** else exc->GS.delta_shift = (FT_UShort)args[0]; } ! /*************************************************************************/ ! /* */ ! /* RTHG[]: Round To Half Grid */ ! /* Opcode range: 0x19 */ ! /* Stack: --> */ ! /* */ static void Ins_RTHG( TT_ExecContext exc ) { exc->GS.round_state = TT_Round_To_Half_Grid; exc->func_round = (TT_Round_Func)Round_To_Half_Grid; } ! /*************************************************************************/ ! /* */ ! /* RTG[]: Round To Grid */ ! /* Opcode range: 0x18 */ ! /* Stack: --> */ ! /* */ static void Ins_RTG( TT_ExecContext exc ) { exc->GS.round_state = TT_Round_To_Grid; exc->func_round = (TT_Round_Func)Round_To_Grid; } ! /*************************************************************************/ ! /* RTDG[]: Round To Double Grid */ ! /* Opcode range: 0x3D */ ! /* Stack: --> */ ! /* */ static void Ins_RTDG( TT_ExecContext exc ) { exc->GS.round_state = TT_Round_To_Double_Grid; exc->func_round = (TT_Round_Func)Round_To_Double_Grid; } ! /*************************************************************************/ ! /* RUTG[]: Round Up To Grid */ ! /* Opcode range: 0x7C */ ! /* Stack: --> */ ! /* */ static void Ins_RUTG( TT_ExecContext exc ) { exc->GS.round_state = TT_Round_Up_To_Grid; exc->func_round = (TT_Round_Func)Round_Up_To_Grid; } ! /*************************************************************************/ ! /* */ ! /* RDTG[]: Round Down To Grid */ ! /* Opcode range: 0x7D */ ! /* Stack: --> */ ! /* */ static void Ins_RDTG( TT_ExecContext exc ) { exc->GS.round_state = TT_Round_Down_To_Grid; exc->func_round = (TT_Round_Func)Round_Down_To_Grid; } ! /*************************************************************************/ ! /* */ ! /* ROFF[]: Round OFF */ ! /* Opcode range: 0x7A */ ! /* Stack: --> */ ! /* */ static void Ins_ROFF( TT_ExecContext exc ) { exc->GS.round_state = TT_Round_Off; exc->func_round = (TT_Round_Func)Round_None; } ! /*************************************************************************/ ! /* */ ! /* SROUND[]: Super ROUND */ ! /* Opcode range: 0x76 */ ! /* Stack: Eint8 --> */ ! /* */ static void Ins_SROUND( TT_ExecContext exc, FT_Long* args ) { SetSuperRound( exc, 0x4000, args[0] ); --- 4678,4775 ---- else exc->GS.delta_shift = (FT_UShort)args[0]; } ! /************************************************************************** ! * ! * RTHG[]: Round To Half Grid ! * Opcode range: 0x19 ! * Stack: --> ! */ static void Ins_RTHG( TT_ExecContext exc ) { exc->GS.round_state = TT_Round_To_Half_Grid; exc->func_round = (TT_Round_Func)Round_To_Half_Grid; } ! /************************************************************************** ! * ! * RTG[]: Round To Grid ! * Opcode range: 0x18 ! * Stack: --> ! */ static void Ins_RTG( TT_ExecContext exc ) { exc->GS.round_state = TT_Round_To_Grid; exc->func_round = (TT_Round_Func)Round_To_Grid; } ! /************************************************************************** ! * RTDG[]: Round To Double Grid ! * Opcode range: 0x3D ! * Stack: --> ! */ static void Ins_RTDG( TT_ExecContext exc ) { exc->GS.round_state = TT_Round_To_Double_Grid; exc->func_round = (TT_Round_Func)Round_To_Double_Grid; } ! /************************************************************************** ! * RUTG[]: Round Up To Grid ! * Opcode range: 0x7C ! * Stack: --> ! */ static void Ins_RUTG( TT_ExecContext exc ) { exc->GS.round_state = TT_Round_Up_To_Grid; exc->func_round = (TT_Round_Func)Round_Up_To_Grid; } ! /************************************************************************** ! * ! * RDTG[]: Round Down To Grid ! * Opcode range: 0x7D ! * Stack: --> ! */ static void Ins_RDTG( TT_ExecContext exc ) { exc->GS.round_state = TT_Round_Down_To_Grid; exc->func_round = (TT_Round_Func)Round_Down_To_Grid; } ! /************************************************************************** ! * ! * ROFF[]: Round OFF ! * Opcode range: 0x7A ! * Stack: --> ! */ static void Ins_ROFF( TT_ExecContext exc ) { exc->GS.round_state = TT_Round_Off; exc->func_round = (TT_Round_Func)Round_None; } ! /************************************************************************** ! * ! * SROUND[]: Super ROUND ! * Opcode range: 0x76 ! * Stack: Eint8 --> ! */ static void Ins_SROUND( TT_ExecContext exc, FT_Long* args ) { SetSuperRound( exc, 0x4000, args[0] );
*** 4721,4736 **** exc->GS.round_state = TT_Round_Super; exc->func_round = (TT_Round_Func)Round_Super; } ! /*************************************************************************/ ! /* */ ! /* S45ROUND[]: Super ROUND 45 degrees */ ! /* Opcode range: 0x77 */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_S45ROUND( TT_ExecContext exc, FT_Long* args ) { SetSuperRound( exc, 0x2D41, args[0] ); --- 4777,4792 ---- exc->GS.round_state = TT_Round_Super; exc->func_round = (TT_Round_Func)Round_Super; } ! /************************************************************************** ! * ! * S45ROUND[]: Super ROUND 45 degrees ! * Opcode range: 0x77 ! * Stack: uint32 --> ! */ static void Ins_S45ROUND( TT_ExecContext exc, FT_Long* args ) { SetSuperRound( exc, 0x2D41, args[0] );
*** 4738,4756 **** exc->GS.round_state = TT_Round_Super_45; exc->func_round = (TT_Round_Func)Round_Super_45; } ! /*************************************************************************/ ! /* */ ! /* GC[a]: Get Coordinate projected onto */ ! /* Opcode range: 0x46-0x47 */ ! /* Stack: uint32 --> f26.6 */ ! /* */ ! /* XXX: UNDOCUMENTED: Measures from the original glyph must be taken */ ! /* along the dual projection vector! */ ! /* */ static void Ins_GC( TT_ExecContext exc, FT_Long* args ) { FT_ULong L; --- 4794,4812 ---- exc->GS.round_state = TT_Round_Super_45; exc->func_round = (TT_Round_Func)Round_Super_45; } ! /************************************************************************** ! * ! * GC[a]: Get Coordinate projected onto ! * Opcode range: 0x46-0x47 ! * Stack: uint32 --> f26.6 ! * ! * XXX: UNDOCUMENTED: Measures from the original glyph must be taken ! * along the dual projection vector! ! */ static void Ins_GC( TT_ExecContext exc, FT_Long* args ) { FT_ULong L;
*** 4775,4794 **** args[0] = R; } ! /*************************************************************************/ ! /* */ ! /* SCFS[]: Set Coordinate From Stack */ ! /* Opcode range: 0x48 */ ! /* Stack: f26.6 uint32 --> */ ! /* */ ! /* Formula: */ ! /* */ ! /* OA := OA + ( value - OA.p )/( f.p ) * f */ ! /* */ static void Ins_SCFS( TT_ExecContext exc, FT_Long* args ) { FT_Long K; --- 4831,4850 ---- args[0] = R; } ! /************************************************************************** ! * ! * SCFS[]: Set Coordinate From Stack ! * Opcode range: 0x48 ! * Stack: f26.6 uint32 --> ! * ! * Formula: ! * ! * OA := OA + ( value - OA.p )/( f.p ) * f ! */ static void Ins_SCFS( TT_ExecContext exc, FT_Long* args ) { FT_Long K;
*** 4813,4837 **** if ( exc->GS.gep2 == 0 ) exc->zp2.org[L] = exc->zp2.cur[L]; } ! /*************************************************************************/ ! /* */ ! /* MD[a]: Measure Distance */ ! /* Opcode range: 0x49-0x4A */ ! /* Stack: uint32 uint32 --> f26.6 */ ! /* */ ! /* XXX: UNDOCUMENTED: Measure taken in the original glyph must be along */ ! /* the dual projection vector. */ ! /* */ ! /* XXX: UNDOCUMENTED: Flag attributes are inverted! */ ! /* 0 => measure distance in original outline */ ! /* 1 => measure distance in grid-fitted outline */ ! /* */ ! /* XXX: UNDOCUMENTED: `zp0 - zp1', and not `zp2 - zp1! */ ! /* */ static void Ins_MD( TT_ExecContext exc, FT_Long* args ) { FT_UShort K, L; --- 4869,4893 ---- if ( exc->GS.gep2 == 0 ) exc->zp2.org[L] = exc->zp2.cur[L]; } ! /************************************************************************** ! * ! * MD[a]: Measure Distance ! * Opcode range: 0x49-0x4A ! * Stack: uint32 uint32 --> f26.6 ! * ! * XXX: UNDOCUMENTED: Measure taken in the original glyph must be along ! * the dual projection vector. ! * ! * XXX: UNDOCUMENTED: Flag attributes are inverted! ! * 0 => measure distance in original outline ! * 1 => measure distance in grid-fitted outline ! * ! * XXX: UNDOCUMENTED: `zp0 - zp1', and not `zp2 - zp1! ! */ static void Ins_MD( TT_ExecContext exc, FT_Long* args ) { FT_UShort K, L;
*** 4900,4915 **** args[0] = D; } ! /*************************************************************************/ ! /* */ ! /* SDPvTL[a]: Set Dual PVector to Line */ ! /* Opcode range: 0x86-0x87 */ ! /* Stack: uint32 uint32 --> */ ! /* */ static void Ins_SDPVTL( TT_ExecContext exc, FT_Long* args ) { FT_Long A, B, C; --- 4956,4971 ---- args[0] = D; } ! /************************************************************************** ! * ! * SDPvTL[a]: Set Dual PVector to Line ! * Opcode range: 0x86-0x87 ! * Stack: uint32 uint32 --> ! */ static void Ins_SDPVTL( TT_ExecContext exc, FT_Long* args ) { FT_Long A, B, C;
*** 4983,4998 **** Normalize( A, B, &exc->GS.projVector ); Compute_Funcs( exc ); } ! /*************************************************************************/ ! /* */ ! /* SZP0[]: Set Zone Pointer 0 */ ! /* Opcode range: 0x13 */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_SZP0( TT_ExecContext exc, FT_Long* args ) { switch ( (FT_Int)args[0] ) --- 5039,5054 ---- Normalize( A, B, &exc->GS.projVector ); Compute_Funcs( exc ); } ! /************************************************************************** ! * ! * SZP0[]: Set Zone Pointer 0 ! * Opcode range: 0x13 ! * Stack: uint32 --> ! */ static void Ins_SZP0( TT_ExecContext exc, FT_Long* args ) { switch ( (FT_Int)args[0] )
*** 5013,5028 **** exc->GS.gep0 = (FT_UShort)args[0]; } ! /*************************************************************************/ ! /* */ ! /* SZP1[]: Set Zone Pointer 1 */ ! /* Opcode range: 0x14 */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_SZP1( TT_ExecContext exc, FT_Long* args ) { switch ( (FT_Int)args[0] ) --- 5069,5084 ---- exc->GS.gep0 = (FT_UShort)args[0]; } ! /************************************************************************** ! * ! * SZP1[]: Set Zone Pointer 1 ! * Opcode range: 0x14 ! * Stack: uint32 --> ! */ static void Ins_SZP1( TT_ExecContext exc, FT_Long* args ) { switch ( (FT_Int)args[0] )
*** 5043,5058 **** exc->GS.gep1 = (FT_UShort)args[0]; } ! /*************************************************************************/ ! /* */ ! /* SZP2[]: Set Zone Pointer 2 */ ! /* Opcode range: 0x15 */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_SZP2( TT_ExecContext exc, FT_Long* args ) { switch ( (FT_Int)args[0] ) --- 5099,5114 ---- exc->GS.gep1 = (FT_UShort)args[0]; } ! /************************************************************************** ! * ! * SZP2[]: Set Zone Pointer 2 ! * Opcode range: 0x15 ! * Stack: uint32 --> ! */ static void Ins_SZP2( TT_ExecContext exc, FT_Long* args ) { switch ( (FT_Int)args[0] )
*** 5073,5088 **** exc->GS.gep2 = (FT_UShort)args[0]; } ! /*************************************************************************/ ! /* */ ! /* SZPS[]: Set Zone PointerS */ ! /* Opcode range: 0x16 */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_SZPS( TT_ExecContext exc, FT_Long* args ) { switch ( (FT_Int)args[0] ) --- 5129,5144 ---- exc->GS.gep2 = (FT_UShort)args[0]; } ! /************************************************************************** ! * ! * SZPS[]: Set Zone PointerS ! * Opcode range: 0x16 ! * Stack: uint32 --> ! */ static void Ins_SZPS( TT_ExecContext exc, FT_Long* args ) { switch ( (FT_Int)args[0] )
*** 5108,5123 **** exc->GS.gep1 = (FT_UShort)args[0]; exc->GS.gep2 = (FT_UShort)args[0]; } ! /*************************************************************************/ ! /* */ ! /* INSTCTRL[]: INSTruction ConTRoL */ ! /* Opcode range: 0x8E */ ! /* Stack: int32 int32 --> */ ! /* */ static void Ins_INSTCTRL( TT_ExecContext exc, FT_Long* args ) { FT_ULong K, L, Kf; --- 5164,5179 ---- exc->GS.gep1 = (FT_UShort)args[0]; exc->GS.gep2 = (FT_UShort)args[0]; } ! /************************************************************************** ! * ! * INSTCTRL[]: INSTruction ConTRoL ! * Opcode range: 0x8E ! * Stack: int32 int32 --> ! */ static void Ins_INSTCTRL( TT_ExecContext exc, FT_Long* args ) { FT_ULong K, L, Kf;
*** 5170,5185 **** #endif } } ! /*************************************************************************/ ! /* */ ! /* SCANCTRL[]: SCAN ConTRoL */ ! /* Opcode range: 0x85 */ ! /* Stack: uint32? --> */ ! /* */ static void Ins_SCANCTRL( TT_ExecContext exc, FT_Long* args ) { FT_Int A; --- 5226,5241 ---- #endif } } ! /************************************************************************** ! * ! * SCANCTRL[]: SCAN ConTRoL ! * Opcode range: 0x85 ! * Stack: uint32? --> ! */ static void Ins_SCANCTRL( TT_ExecContext exc, FT_Long* args ) { FT_Int A;
*** 5217,5254 **** if ( ( args[0] & 0x2000 ) != 0 && exc->tt_metrics.stretched ) exc->GS.scan_control = FALSE; } ! /*************************************************************************/ ! /* */ ! /* SCANTYPE[]: SCAN TYPE */ ! /* Opcode range: 0x8D */ ! /* Stack: uint16 --> */ ! /* */ static void Ins_SCANTYPE( TT_ExecContext exc, FT_Long* args ) { if ( args[0] >= 0 ) exc->GS.scan_type = (FT_Int)args[0] & 0xFFFF; } ! /*************************************************************************/ ! /* */ ! /* MANAGING OUTLINES */ ! /* */ ! /*************************************************************************/ ! /*************************************************************************/ ! /* */ ! /* FLIPPT[]: FLIP PoinT */ ! /* Opcode range: 0x80 */ ! /* Stack: uint32... --> */ ! /* */ static void Ins_FLIPPT( TT_ExecContext exc ) { FT_UShort point; --- 5273,5310 ---- if ( ( args[0] & 0x2000 ) != 0 && exc->tt_metrics.stretched ) exc->GS.scan_control = FALSE; } ! /************************************************************************** ! * ! * SCANTYPE[]: SCAN TYPE ! * Opcode range: 0x8D ! * Stack: uint16 --> ! */ static void Ins_SCANTYPE( TT_ExecContext exc, FT_Long* args ) { if ( args[0] >= 0 ) exc->GS.scan_type = (FT_Int)args[0] & 0xFFFF; } ! /************************************************************************** ! * ! * MANAGING OUTLINES ! * ! */ ! /************************************************************************** ! * ! * FLIPPT[]: FLIP PoinT ! * Opcode range: 0x80 ! * Stack: uint32... --> ! */ static void Ins_FLIPPT( TT_ExecContext exc ) { FT_UShort point;
*** 5293,5308 **** exc->GS.loop = 1; exc->new_top = exc->args; } ! /*************************************************************************/ ! /* */ ! /* FLIPRGON[]: FLIP RanGe ON */ ! /* Opcode range: 0x81 */ ! /* Stack: uint32 uint32 --> */ ! /* */ static void Ins_FLIPRGON( TT_ExecContext exc, FT_Long* args ) { FT_UShort I, K, L; --- 5349,5364 ---- exc->GS.loop = 1; exc->new_top = exc->args; } ! /************************************************************************** ! * ! * FLIPRGON[]: FLIP RanGe ON ! * Opcode range: 0x81 ! * Stack: uint32 uint32 --> ! */ static void Ins_FLIPRGON( TT_ExecContext exc, FT_Long* args ) { FT_UShort I, K, L;
*** 5331,5346 **** for ( I = L; I <= K; I++ ) exc->pts.tags[I] |= FT_CURVE_TAG_ON; } ! /*************************************************************************/ ! /* */ ! /* FLIPRGOFF: FLIP RanGe OFF */ ! /* Opcode range: 0x82 */ ! /* Stack: uint32 uint32 --> */ ! /* */ static void Ins_FLIPRGOFF( TT_ExecContext exc, FT_Long* args ) { FT_UShort I, K, L; --- 5387,5402 ---- for ( I = L; I <= K; I++ ) exc->pts.tags[I] |= FT_CURVE_TAG_ON; } ! /************************************************************************** ! * ! * FLIPRGOFF: FLIP RanGe OFF ! * Opcode range: 0x82 ! * Stack: uint32 uint32 --> ! */ static void Ins_FLIPRGOFF( TT_ExecContext exc, FT_Long* args ) { FT_UShort I, K, L;
*** 5448,5463 **** exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; } } ! /*************************************************************************/ ! /* */ ! /* SHP[a]: SHift Point by the last point */ ! /* Opcode range: 0x32-0x33 */ ! /* Stack: uint32... --> */ ! /* */ static void Ins_SHP( TT_ExecContext exc ) { TT_GlyphZoneRec zp; FT_UShort refp; --- 5504,5519 ---- exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; } } ! /************************************************************************** ! * ! * SHP[a]: SHift Point by the last point ! * Opcode range: 0x32-0x33 ! * Stack: uint32... --> ! */ static void Ins_SHP( TT_ExecContext exc ) { TT_GlyphZoneRec zp; FT_UShort refp;
*** 5505,5524 **** exc->GS.loop = 1; exc->new_top = exc->args; } ! /*************************************************************************/ ! /* */ ! /* SHC[a]: SHift Contour */ ! /* Opcode range: 0x34-35 */ ! /* Stack: uint32 --> */ ! /* */ ! /* UNDOCUMENTED: According to Greg Hitchcock, there is one (virtual) */ ! /* contour in the twilight zone, namely contour number */ ! /* zero which includes all points of it. */ ! /* */ static void Ins_SHC( TT_ExecContext exc, FT_Long* args ) { TT_GlyphZoneRec zp; --- 5561,5580 ---- exc->GS.loop = 1; exc->new_top = exc->args; } ! /************************************************************************** ! * ! * SHC[a]: SHift Contour ! * Opcode range: 0x34-35 ! * Stack: uint32 --> ! * ! * UNDOCUMENTED: According to Greg Hitchcock, there is one (virtual) ! * contour in the twilight zone, namely contour number ! * zero which includes all points of it. ! */ static void Ins_SHC( TT_ExecContext exc, FT_Long* args ) { TT_GlyphZoneRec zp;
*** 5561,5576 **** Move_Zp2_Point( exc, i, dx, dy, TRUE ); } } ! /*************************************************************************/ ! /* */ ! /* SHZ[a]: SHift Zone */ ! /* Opcode range: 0x36-37 */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_SHZ( TT_ExecContext exc, FT_Long* args ) { TT_GlyphZoneRec zp; --- 5617,5632 ---- Move_Zp2_Point( exc, i, dx, dy, TRUE ); } } ! /************************************************************************** ! * ! * SHZ[a]: SHift Zone ! * Opcode range: 0x36-37 ! * Stack: uint32 --> ! */ static void Ins_SHZ( TT_ExecContext exc, FT_Long* args ) { TT_GlyphZoneRec zp;
*** 5609,5624 **** Move_Zp2_Point( exc, i, dx, dy, FALSE ); } } ! /*************************************************************************/ ! /* */ ! /* SHPIX[]: SHift points by a PIXel amount */ ! /* Opcode range: 0x38 */ ! /* Stack: f26.6 uint32... --> */ ! /* */ static void Ins_SHPIX( TT_ExecContext exc, FT_Long* args ) { FT_F26Dot6 dx, dy; --- 5665,5680 ---- Move_Zp2_Point( exc, i, dx, dy, FALSE ); } } ! /************************************************************************** ! * ! * SHPIX[]: SHift points by a PIXel amount ! * Opcode range: 0x38 ! * Stack: f26.6 uint32... --> ! */ static void Ins_SHPIX( TT_ExecContext exc, FT_Long* args ) { FT_F26Dot6 dx, dy;
*** 5769,5784 **** exc->GS.loop = 1; exc->new_top = exc->args; } ! /*************************************************************************/ ! /* */ ! /* MSIRP[a]: Move Stack Indirect Relative Position */ ! /* Opcode range: 0x3A-0x3B */ ! /* Stack: f26.6 uint32 --> */ ! /* */ static void Ins_MSIRP( TT_ExecContext exc, FT_Long* args ) { FT_UShort point = 0; --- 5825,5840 ---- exc->GS.loop = 1; exc->new_top = exc->args; } ! /************************************************************************** ! * ! * MSIRP[a]: Move Stack Indirect Relative Position ! * Opcode range: 0x3A-0x3B ! * Stack: f26.6 uint32 --> ! */ static void Ins_MSIRP( TT_ExecContext exc, FT_Long* args ) { FT_UShort point = 0;
*** 5844,5859 **** if ( ( exc->opcode & 1 ) != 0 ) exc->GS.rp0 = point; } ! /*************************************************************************/ ! /* */ ! /* MDAP[a]: Move Direct Absolute Point */ ! /* Opcode range: 0x2E-0x2F */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_MDAP( TT_ExecContext exc, FT_Long* args ) { FT_UShort point; --- 5900,5915 ---- if ( ( exc->opcode & 1 ) != 0 ) exc->GS.rp0 = point; } ! /************************************************************************** ! * ! * MDAP[a]: Move Direct Absolute Point ! * Opcode range: 0x2E-0x2F ! * Stack: uint32 --> ! */ static void Ins_MDAP( TT_ExecContext exc, FT_Long* args ) { FT_UShort point;
*** 5898,5913 **** exc->GS.rp0 = point; exc->GS.rp1 = point; } ! /*************************************************************************/ ! /* */ ! /* MIAP[a]: Move Indirect Absolute Point */ ! /* Opcode range: 0x3E-0x3F */ ! /* Stack: uint32 uint32 --> */ ! /* */ static void Ins_MIAP( TT_ExecContext exc, FT_Long* args ) { FT_ULong cvtEntry; --- 5954,5969 ---- exc->GS.rp0 = point; exc->GS.rp1 = point; } ! /************************************************************************** ! * ! * MIAP[a]: Move Indirect Absolute Point ! * Opcode range: 0x3E-0x3F ! * Stack: uint32 uint32 --> ! */ static void Ins_MIAP( TT_ExecContext exc, FT_Long* args ) { FT_ULong cvtEntry;
*** 6018,6033 **** exc->GS.rp0 = point; exc->GS.rp1 = point; } ! /*************************************************************************/ ! /* */ ! /* MDRP[abcde]: Move Direct Relative Point */ ! /* Opcode range: 0xC0-0xDF */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_MDRP( TT_ExecContext exc, FT_Long* args ) { FT_UShort point = 0; --- 6074,6089 ---- exc->GS.rp0 = point; exc->GS.rp1 = point; } ! /************************************************************************** ! * ! * MDRP[abcde]: Move Direct Relative Point ! * Opcode range: 0xC0-0xDF ! * Stack: uint32 --> ! */ static void Ins_MDRP( TT_ExecContext exc, FT_Long* args ) { FT_UShort point = 0;
*** 6162,6177 **** if ( ( exc->opcode & 16 ) != 0 ) exc->GS.rp0 = point; } ! /*************************************************************************/ ! /* */ ! /* MIRP[abcde]: Move Indirect Relative Point */ ! /* Opcode range: 0xE0-0xFF */ ! /* Stack: int32? uint32 --> */ ! /* */ static void Ins_MIRP( TT_ExecContext exc, FT_Long* args ) { FT_UShort point; --- 6218,6233 ---- if ( ( exc->opcode & 16 ) != 0 ) exc->GS.rp0 = point; } ! /************************************************************************** ! * ! * MIRP[abcde]: Move Indirect Relative Point ! * Opcode range: 0xE0-0xFF ! * Stack: int32? uint32 --> ! */ static void Ins_MIRP( TT_ExecContext exc, FT_Long* args ) { FT_UShort point;
*** 6187,6196 **** --- 6243,6254 ---- FT_Int B1 = 0; /* pacify compiler */ FT_Int B2 = 0; FT_Bool reverse_move = FALSE; #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + FT_F26Dot6 delta; + minimum_distance = exc->GS.minimum_distance; control_value_cutin = exc->GS.control_value_cutin; point = (FT_UShort)args[0]; cvtEntry = (FT_ULong)( ADD_LONG( args[1], 1 ) );
*** 6219,6230 **** else cvt_dist = exc->func_read_cvt( exc, cvtEntry - 1 ); /* single width test */ ! if ( FT_ABS( cvt_dist - exc->GS.single_width_value ) < ! exc->GS.single_width_cutin ) { if ( cvt_dist >= 0 ) cvt_dist = exc->GS.single_width_value; else cvt_dist = -exc->GS.single_width_value; --- 6277,6291 ---- else cvt_dist = exc->func_read_cvt( exc, cvtEntry - 1 ); /* single width test */ ! delta = SUB_LONG( cvt_dist, exc->GS.single_width_value ); ! if ( delta < 0 ) ! delta = NEG_LONG( delta ); ! ! if ( delta < exc->GS.single_width_cutin ) { if ( cvt_dist >= 0 ) cvt_dist = exc->GS.single_width_value; else cvt_dist = -exc->GS.single_width_value;
*** 6249,6259 **** /* auto-flip test */ if ( exc->GS.auto_flip ) { if ( ( org_dist ^ cvt_dist ) < 0 ) ! cvt_dist = -cvt_dist; } #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && --- 6310,6320 ---- /* auto-flip test */ if ( exc->GS.auto_flip ) { if ( ( org_dist ^ cvt_dist ) < 0 ) ! cvt_dist = NEG_LONG( cvt_dist ); } #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode &&
*** 6274,6286 **** /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */ /* refer to the same zone. */ if ( exc->GS.gep0 == exc->GS.gep1 ) { - FT_F26Dot6 delta; - - /* XXX: According to Greg Hitchcock, the following wording is */ /* the right one: */ /* */ /* When the absolute difference between the value in */ /* the table [CVT] and the measurement directly from */ --- 6335,6344 ----
*** 6311,6323 **** /* do cvt cut-in always in MIRP for sph */ if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->GS.gep0 == exc->GS.gep1 ) { - FT_F26Dot6 delta; - - delta = SUB_LONG( cvt_dist, org_dist ); if ( delta < 0 ) delta = NEG_LONG( delta ); if ( delta > control_value_cutin ) --- 6369,6378 ----
*** 6410,6425 **** exc->GS.rp2 = point; } ! /*************************************************************************/ ! /* */ ! /* ALIGNRP[]: ALIGN Relative Point */ ! /* Opcode range: 0x3C */ ! /* Stack: uint32 uint32... --> */ ! /* */ static void Ins_ALIGNRP( TT_ExecContext exc ) { FT_UShort point; FT_F26Dot6 distance; --- 6465,6480 ---- exc->GS.rp2 = point; } ! /************************************************************************** ! * ! * ALIGNRP[]: ALIGN Relative Point ! * Opcode range: 0x3C ! * Stack: uint32 uint32... --> ! */ static void Ins_ALIGNRP( TT_ExecContext exc ) { FT_UShort point; FT_F26Dot6 distance;
*** 6473,6488 **** exc->GS.loop = 1; exc->new_top = exc->args; } ! /*************************************************************************/ ! /* */ ! /* ISECT[]: moves point to InterSECTion */ ! /* Opcode range: 0x0F */ ! /* Stack: 5 * uint32 --> */ ! /* */ static void Ins_ISECT( TT_ExecContext exc, FT_Long* args ) { FT_UShort point, --- 6528,6543 ---- exc->GS.loop = 1; exc->new_top = exc->args; } ! /************************************************************************** ! * ! * ISECT[]: moves point to InterSECTion ! * Opcode range: 0x0F ! * Stack: 5 * uint32 --> ! */ static void Ins_ISECT( TT_ExecContext exc, FT_Long* args ) { FT_UShort point,
*** 6569,6584 **** exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; } ! /*************************************************************************/ ! /* */ ! /* ALIGNPTS[]: ALIGN PoinTS */ ! /* Opcode range: 0x27 */ ! /* Stack: uint32 uint32 --> */ ! /* */ static void Ins_ALIGNPTS( TT_ExecContext exc, FT_Long* args ) { FT_UShort p1, p2; --- 6624,6639 ---- exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; } ! /************************************************************************** ! * ! * ALIGNPTS[]: ALIGN PoinTS ! * Opcode range: 0x27 ! * Stack: uint32 uint32 --> ! */ static void Ins_ALIGNPTS( TT_ExecContext exc, FT_Long* args ) { FT_UShort p1, p2;
*** 6601,6616 **** exc->func_move( exc, &exc->zp1, p1, distance ); exc->func_move( exc, &exc->zp0, p2, NEG_LONG( distance ) ); } ! /*************************************************************************/ ! /* */ ! /* IP[]: Interpolate Point */ ! /* Opcode range: 0x39 */ ! /* Stack: uint32... --> */ ! /* */ /* SOMETIMES, DUMBER CODE IS BETTER CODE */ static void Ins_IP( TT_ExecContext exc ) --- 6656,6671 ---- exc->func_move( exc, &exc->zp1, p1, distance ); exc->func_move( exc, &exc->zp0, p2, NEG_LONG( distance ) ); } ! /************************************************************************** ! * ! * IP[]: Interpolate Point ! * Opcode range: 0x39 ! * Stack: uint32... --> ! */ /* SOMETIMES, DUMBER CODE IS BETTER CODE */ static void Ins_IP( TT_ExecContext exc )
*** 6761,6776 **** exc->GS.loop = 1; exc->new_top = exc->args; } ! /*************************************************************************/ ! /* */ ! /* UTP[a]: UnTouch Point */ ! /* Opcode range: 0x29 */ ! /* Stack: uint32 --> */ ! /* */ static void Ins_UTP( TT_ExecContext exc, FT_Long* args ) { FT_UShort point; --- 6816,6831 ---- exc->GS.loop = 1; exc->new_top = exc->args; } ! /************************************************************************** ! * ! * UTP[a]: UnTouch Point ! * Opcode range: 0x29 ! * Stack: uint32 --> ! */ static void Ins_UTP( TT_ExecContext exc, FT_Long* args ) { FT_UShort point;
*** 6930,6945 **** } } } ! /*************************************************************************/ ! /* */ ! /* IUP[a]: Interpolate Untouched Points */ ! /* Opcode range: 0x30-0x31 */ ! /* Stack: --> */ ! /* */ static void Ins_IUP( TT_ExecContext exc ) { IUP_WorkerRec V; FT_Byte mask; --- 6985,7000 ---- } } } ! /************************************************************************** ! * ! * IUP[a]: Interpolate Untouched Points ! * Opcode range: 0x30-0x31 ! * Stack: --> ! */ static void Ins_IUP( TT_ExecContext exc ) { IUP_WorkerRec V; FT_Byte mask;
*** 7058,7073 **** contour++; } while ( contour < exc->pts.n_contours ); } ! /*************************************************************************/ ! /* */ ! /* DELTAPn[]: DELTA exceptions P1, P2, P3 */ ! /* Opcode range: 0x5D,0x71,0x72 */ ! /* Stack: uint32 (2 * uint32)... --> */ ! /* */ static void Ins_DELTAP( TT_ExecContext exc, FT_Long* args ) { FT_ULong nump, k; --- 7113,7128 ---- contour++; } while ( contour < exc->pts.n_contours ); } ! /************************************************************************** ! * ! * DELTAPn[]: DELTA exceptions P1, P2, P3 ! * Opcode range: 0x5D,0x71,0x72 ! * Stack: uint32 (2 * uint32)... --> ! */ static void Ins_DELTAP( TT_ExecContext exc, FT_Long* args ) { FT_ULong nump, k;
*** 7225,7240 **** Fail: exc->new_top = exc->args; } ! /*************************************************************************/ ! /* */ ! /* DELTACn[]: DELTA exceptions C1, C2, C3 */ ! /* Opcode range: 0x73,0x74,0x75 */ ! /* Stack: uint32 (2 * uint32)... --> */ ! /* */ static void Ins_DELTAC( TT_ExecContext exc, FT_Long* args ) { FT_ULong nump, k; --- 7280,7295 ---- Fail: exc->new_top = exc->args; } ! /************************************************************************** ! * ! * DELTACn[]: DELTA exceptions C1, C2, C3 ! * Opcode range: 0x73,0x74,0x75 ! * Stack: uint32 (2 * uint32)... --> ! */ static void Ins_DELTAC( TT_ExecContext exc, FT_Long* args ) { FT_ULong nump, k;
*** 7303,7333 **** Fail: exc->new_top = exc->args; } ! /*************************************************************************/ ! /* */ ! /* MISC. INSTRUCTIONS */ ! /* */ ! /*************************************************************************/ ! /*************************************************************************/ ! /* */ ! /* GETINFO[]: GET INFOrmation */ ! /* Opcode range: 0x88 */ ! /* Stack: uint32 --> uint32 */ ! /* */ ! /* XXX: UNDOCUMENTED: Selector bits higher than 9 are currently (May */ ! /* 2015) not documented in the OpenType specification. */ ! /* */ ! /* Selector bit 11 is incorrectly described as bit 8, while the */ ! /* real meaning of bit 8 (vertical LCD subpixels) stays */ ! /* undocumented. The same mistake can be found in Greg Hitchcock's */ ! /* whitepaper. */ ! /* */ static void Ins_GETINFO( TT_ExecContext exc, FT_Long* args ) { FT_Long K; --- 7358,7388 ---- Fail: exc->new_top = exc->args; } ! /************************************************************************** ! * ! * MISC. INSTRUCTIONS ! * ! */ ! /************************************************************************** ! * ! * GETINFO[]: GET INFOrmation ! * Opcode range: 0x88 ! * Stack: uint32 --> uint32 ! * ! * XXX: UNDOCUMENTED: Selector bits higher than 9 are currently (May ! * 2015) not documented in the OpenType specification. ! * ! * Selector bit 11 is incorrectly described as bit 8, while the ! * real meaning of bit 8 (vertical LCD subpixels) stays ! * undocumented. The same mistake can be found in Greg Hitchcock's ! * whitepaper. ! */ static void Ins_GETINFO( TT_ExecContext exc, FT_Long* args ) { FT_Long K;
*** 7335,7349 **** K = 0; #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY ! /********************************/ ! /* RASTERIZER VERSION */ ! /* Selector Bit: 0 */ ! /* Return Bit(s): 0-7 */ ! /* */ if ( SUBPIXEL_HINTING_INFINALITY && ( args[0] & 1 ) != 0 && exc->subpixel_hinting ) { if ( exc->ignore_x_mode ) --- 7390,7404 ---- K = 0; #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY ! /********************************* ! * RASTERIZER VERSION ! * Selector Bit: 0 ! * Return Bit(s): 0-7 ! */ if ( SUBPIXEL_HINTING_INFINALITY && ( args[0] & 1 ) != 0 && exc->subpixel_hinting ) { if ( exc->ignore_x_mode )
*** 7360,7456 **** else #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ if ( ( args[0] & 1 ) != 0 ) K = driver->interpreter_version; ! /********************************/ ! /* GLYPH ROTATED */ ! /* Selector Bit: 1 */ ! /* Return Bit(s): 8 */ ! /* */ if ( ( args[0] & 2 ) != 0 && exc->tt_metrics.rotated ) K |= 1 << 8; ! /********************************/ ! /* GLYPH STRETCHED */ ! /* Selector Bit: 2 */ ! /* Return Bit(s): 9 */ ! /* */ if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched ) K |= 1 << 9; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT ! /********************************/ ! /* VARIATION GLYPH */ ! /* Selector Bit: 3 */ ! /* Return Bit(s): 10 */ ! /* */ ! /* XXX: UNDOCUMENTED! */ if ( (args[0] & 8 ) != 0 && exc->face->blend ) K |= 1 << 10; #endif ! /********************************/ ! /* BI-LEVEL HINTING AND */ ! /* GRAYSCALE RENDERING */ ! /* Selector Bit: 5 */ ! /* Return Bit(s): 12 */ ! /* */ if ( ( args[0] & 32 ) != 0 && exc->grayscale ) K |= 1 << 12; #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL /* Toggle the following flags only outside of monochrome mode. */ /* Otherwise, instructions may behave weirdly and rendering results */ /* may differ between v35 and v40 mode, e.g., in `Times New Roman */ /* Bold Italic'. */ if ( SUBPIXEL_HINTING_MINIMAL && exc->subpixel_hinting_lean ) { ! /********************************/ ! /* HINTING FOR SUBPIXEL */ ! /* Selector Bit: 6 */ ! /* Return Bit(s): 13 */ ! /* */ ! /* v40 does subpixel hinting by default. */ if ( ( args[0] & 64 ) != 0 ) K |= 1 << 13; ! /********************************/ ! /* VERTICAL LCD SUBPIXELS? */ ! /* Selector Bit: 8 */ ! /* Return Bit(s): 15 */ ! /* */ if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd_lean ) K |= 1 << 15; ! /********************************/ ! /* SUBPIXEL POSITIONED? */ ! /* Selector Bit: 10 */ ! /* Return Bit(s): 17 */ ! /* */ ! /* XXX: FreeType supports it, dependent on what client does? */ if ( ( args[0] & 1024 ) != 0 ) K |= 1 << 17; ! /********************************/ ! /* SYMMETRICAL SMOOTHING */ ! /* Selector Bit: 11 */ ! /* Return Bit(s): 18 */ ! /* */ ! /* The only smoothing method FreeType supports unless someone sets */ ! /* FT_LOAD_TARGET_MONO. */ if ( ( args[0] & 2048 ) != 0 && exc->subpixel_hinting_lean ) K |= 1 << 18; ! /********************************/ ! /* CLEARTYPE HINTING AND */ ! /* GRAYSCALE RENDERING */ ! /* Selector Bit: 12 */ ! /* Return Bit(s): 19 */ ! /* */ ! /* Grayscale rendering is what FreeType does anyway unless someone */ ! /* sets FT_LOAD_TARGET_MONO or FT_LOAD_TARGET_LCD(_V) */ if ( ( args[0] & 4096 ) != 0 && exc->grayscale_cleartype ) K |= 1 << 19; } #endif --- 7415,7516 ---- else #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ if ( ( args[0] & 1 ) != 0 ) K = driver->interpreter_version; ! /********************************* ! * GLYPH ROTATED ! * Selector Bit: 1 ! * Return Bit(s): 8 ! */ if ( ( args[0] & 2 ) != 0 && exc->tt_metrics.rotated ) K |= 1 << 8; ! /********************************* ! * GLYPH STRETCHED ! * Selector Bit: 2 ! * Return Bit(s): 9 ! */ if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched ) K |= 1 << 9; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT ! /********************************* ! * VARIATION GLYPH ! * Selector Bit: 3 ! * Return Bit(s): 10 ! * ! * XXX: UNDOCUMENTED! ! */ if ( (args[0] & 8 ) != 0 && exc->face->blend ) K |= 1 << 10; #endif ! /********************************* ! * BI-LEVEL HINTING AND ! * GRAYSCALE RENDERING ! * Selector Bit: 5 ! * Return Bit(s): 12 ! */ if ( ( args[0] & 32 ) != 0 && exc->grayscale ) K |= 1 << 12; #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL /* Toggle the following flags only outside of monochrome mode. */ /* Otherwise, instructions may behave weirdly and rendering results */ /* may differ between v35 and v40 mode, e.g., in `Times New Roman */ /* Bold Italic'. */ if ( SUBPIXEL_HINTING_MINIMAL && exc->subpixel_hinting_lean ) { ! /********************************* ! * HINTING FOR SUBPIXEL ! * Selector Bit: 6 ! * Return Bit(s): 13 ! * ! * v40 does subpixel hinting by default. ! */ if ( ( args[0] & 64 ) != 0 ) K |= 1 << 13; ! /********************************* ! * VERTICAL LCD SUBPIXELS? ! * Selector Bit: 8 ! * Return Bit(s): 15 ! */ if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd_lean ) K |= 1 << 15; ! /********************************* ! * SUBPIXEL POSITIONED? ! * Selector Bit: 10 ! * Return Bit(s): 17 ! * ! * XXX: FreeType supports it, dependent on what client does? ! */ if ( ( args[0] & 1024 ) != 0 ) K |= 1 << 17; ! /********************************* ! * SYMMETRICAL SMOOTHING ! * Selector Bit: 11 ! * Return Bit(s): 18 ! * ! * The only smoothing method FreeType supports unless someone sets ! * FT_LOAD_TARGET_MONO. ! */ if ( ( args[0] & 2048 ) != 0 && exc->subpixel_hinting_lean ) K |= 1 << 18; ! /********************************* ! * CLEARTYPE HINTING AND ! * GRAYSCALE RENDERING ! * Selector Bit: 12 ! * Return Bit(s): 19 ! * ! * Grayscale rendering is what FreeType does anyway unless someone ! * sets FT_LOAD_TARGET_MONO or FT_LOAD_TARGET_LCD(_V) ! */ if ( ( args[0] & 4096 ) != 0 && exc->grayscale_cleartype ) K |= 1 << 19; } #endif
*** 7460,7530 **** exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 ) { if ( exc->rasterizer_version >= 37 ) { ! /********************************/ ! /* HINTING FOR SUBPIXEL */ ! /* Selector Bit: 6 */ ! /* Return Bit(s): 13 */ ! /* */ if ( ( args[0] & 64 ) != 0 && exc->subpixel_hinting ) K |= 1 << 13; ! /********************************/ ! /* COMPATIBLE WIDTHS ENABLED */ ! /* Selector Bit: 7 */ ! /* Return Bit(s): 14 */ ! /* */ ! /* Functionality still needs to be added */ if ( ( args[0] & 128 ) != 0 && exc->compatible_widths ) K |= 1 << 14; ! /********************************/ ! /* VERTICAL LCD SUBPIXELS? */ ! /* Selector Bit: 8 */ ! /* Return Bit(s): 15 */ ! /* */ ! /* Functionality still needs to be added */ if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd ) K |= 1 << 15; ! /********************************/ ! /* HINTING FOR BGR? */ ! /* Selector Bit: 9 */ ! /* Return Bit(s): 16 */ ! /* */ ! /* Functionality still needs to be added */ if ( ( args[0] & 512 ) != 0 && exc->bgr ) K |= 1 << 16; if ( exc->rasterizer_version >= 38 ) { ! /********************************/ ! /* SUBPIXEL POSITIONED? */ ! /* Selector Bit: 10 */ ! /* Return Bit(s): 17 */ ! /* */ ! /* Functionality still needs to be added */ if ( ( args[0] & 1024 ) != 0 && exc->subpixel_positioned ) K |= 1 << 17; ! /********************************/ ! /* SYMMETRICAL SMOOTHING */ ! /* Selector Bit: 11 */ ! /* Return Bit(s): 18 */ ! /* */ ! /* Functionality still needs to be added */ if ( ( args[0] & 2048 ) != 0 && exc->symmetrical_smoothing ) K |= 1 << 18; ! /********************************/ ! /* GRAY CLEARTYPE */ ! /* Selector Bit: 12 */ ! /* Return Bit(s): 19 */ ! /* */ ! /* Functionality still needs to be added */ if ( ( args[0] & 4096 ) != 0 && exc->gray_cleartype ) K |= 1 << 19; } } } --- 7520,7596 ---- exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 ) { if ( exc->rasterizer_version >= 37 ) { ! /********************************* ! * HINTING FOR SUBPIXEL ! * Selector Bit: 6 ! * Return Bit(s): 13 ! */ if ( ( args[0] & 64 ) != 0 && exc->subpixel_hinting ) K |= 1 << 13; ! /********************************* ! * COMPATIBLE WIDTHS ENABLED ! * Selector Bit: 7 ! * Return Bit(s): 14 ! * ! * Functionality still needs to be added ! */ if ( ( args[0] & 128 ) != 0 && exc->compatible_widths ) K |= 1 << 14; ! /********************************* ! * VERTICAL LCD SUBPIXELS? ! * Selector Bit: 8 ! * Return Bit(s): 15 ! * ! * Functionality still needs to be added ! */ if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd ) K |= 1 << 15; ! /********************************* ! * HINTING FOR BGR? ! * Selector Bit: 9 ! * Return Bit(s): 16 ! * ! * Functionality still needs to be added ! */ if ( ( args[0] & 512 ) != 0 && exc->bgr ) K |= 1 << 16; if ( exc->rasterizer_version >= 38 ) { ! /********************************* ! * SUBPIXEL POSITIONED? ! * Selector Bit: 10 ! * Return Bit(s): 17 ! * ! * Functionality still needs to be added ! */ if ( ( args[0] & 1024 ) != 0 && exc->subpixel_positioned ) K |= 1 << 17; ! /********************************* ! * SYMMETRICAL SMOOTHING ! * Selector Bit: 11 ! * Return Bit(s): 18 ! * ! * Functionality still needs to be added ! */ if ( ( args[0] & 2048 ) != 0 && exc->symmetrical_smoothing ) K |= 1 << 18; ! /********************************* ! * GRAY CLEARTYPE ! * Selector Bit: 12 ! * Return Bit(s): 19 ! * ! * Functionality still needs to be added ! */ if ( ( args[0] & 4096 ) != 0 && exc->gray_cleartype ) K |= 1 << 19; } } }
*** 7535,7554 **** } #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT ! /*************************************************************************/ ! /* */ ! /* GETVARIATION[]: get normalized variation (blend) coordinates */ ! /* Opcode range: 0x91 */ ! /* Stack: --> f2.14... */ ! /* */ ! /* XXX: UNDOCUMENTED! There is no official documentation from Apple for */ ! /* this bytecode instruction. Active only if a font has GX */ ! /* variation axes. */ ! /* */ static void Ins_GETVARIATION( TT_ExecContext exc, FT_Long* args ) { FT_UInt num_axes = exc->face->blend->num_axis; --- 7601,7620 ---- } #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT ! /************************************************************************** ! * ! * GETVARIATION[]: get normalized variation (blend) coordinates ! * Opcode range: 0x91 ! * Stack: --> f2.14... ! * ! * XXX: UNDOCUMENTED! There is no official documentation from Apple for ! * this bytecode instruction. Active only if a font has GX ! * variation axes. ! */ static void Ins_GETVARIATION( TT_ExecContext exc, FT_Long* args ) { FT_UInt num_axes = exc->face->blend->num_axis;
*** 7574,7592 **** args[i] = 0; } } ! /*************************************************************************/ ! /* */ ! /* GETDATA[]: no idea what this is good for */ ! /* Opcode range: 0x92 */ ! /* Stack: --> 17 */ ! /* */ ! /* XXX: UNDOCUMENTED! There is no documentation from Apple for this */ ! /* very weird bytecode instruction. */ ! /* */ static void Ins_GETDATA( FT_Long* args ) { args[0] = 17; } --- 7640,7658 ---- args[i] = 0; } } ! /************************************************************************** ! * ! * GETDATA[]: no idea what this is good for ! * Opcode range: 0x92 ! * Stack: --> 17 ! * ! * XXX: UNDOCUMENTED! There is no documentation from Apple for this ! * very weird bytecode instruction. ! */ static void Ins_GETDATA( FT_Long* args ) { args[0] = 17; }
*** 7630,7667 **** exc->error = FT_THROW( Invalid_Opcode ); } ! /*************************************************************************/ ! /* */ ! /* RUN */ ! /* */ ! /* This function executes a run of opcodes. It will exit in the */ ! /* following cases: */ ! /* */ ! /* - Errors (in which case it returns FALSE). */ ! /* */ ! /* - Reaching the end of the main code range (returns TRUE). */ ! /* Reaching the end of a code range within a function call is an */ ! /* error. */ ! /* */ ! /* - After executing one single opcode, if the flag `Instruction_Trap' */ ! /* is set to TRUE (returns TRUE). */ ! /* */ ! /* On exit with TRUE, test IP < CodeSize to know whether it comes from */ ! /* an instruction trap or a normal termination. */ ! /* */ ! /* */ ! /* Note: The documented DEBUG opcode pops a value from the stack. This */ ! /* behaviour is unsupported; here a DEBUG opcode is always an */ ! /* error. */ ! /* */ ! /* */ ! /* THIS IS THE INTERPRETER'S MAIN LOOP. */ ! /* */ ! /*************************************************************************/ /* documentation is in ttinterp.h */ FT_EXPORT_DEF( FT_Error ) --- 7696,7733 ---- exc->error = FT_THROW( Invalid_Opcode ); } ! /************************************************************************** ! * ! * RUN ! * ! * This function executes a run of opcodes. It will exit in the ! * following cases: ! * ! * - Errors (in which case it returns FALSE). ! * ! * - Reaching the end of the main code range (returns TRUE). ! * Reaching the end of a code range within a function call is an ! * error. ! * ! * - After executing one single opcode, if the flag `Instruction_Trap' ! * is set to TRUE (returns TRUE). ! * ! * On exit with TRUE, test IP < CodeSize to know whether it comes from ! * an instruction trap or a normal termination. ! * ! * ! * Note: The documented DEBUG opcode pops a value from the stack. This ! * behaviour is unsupported; here a DEBUG opcode is always an ! * error. ! * ! * ! * THIS IS THE INTERPRETER'S MAIN LOOP. ! * ! */ /* documentation is in ttinterp.h */ FT_EXPORT_DEF( FT_Error )
*** 7799,7809 **** /* if tracing level is 7, show current code position */ /* and the first few stack elements also */ FT_TRACE6(( " " )); FT_TRACE7(( "%06d ", exc->IP )); ! FT_TRACE6(( opcode_name[exc->opcode] + 2 )); FT_TRACE7(( "%*s", *opcode_name[exc->opcode] == 'A' ? 2 : 12 - ( *opcode_name[exc->opcode] - '0' ), "#" )); for ( n = 1; n <= cnt; n++ ) --- 7865,7875 ---- /* if tracing level is 7, show current code position */ /* and the first few stack elements also */ FT_TRACE6(( " " )); FT_TRACE7(( "%06d ", exc->IP )); ! FT_TRACE6(( "%s", opcode_name[exc->opcode] + 2 )); FT_TRACE7(( "%*s", *opcode_name[exc->opcode] == 'A' ? 2 : 12 - ( *opcode_name[exc->opcode] - '0' ), "#" )); for ( n = 1; n <= cnt; n++ )
< prev index next >