⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ttinterp.c

📁 神龙卡开发原代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************************* * *  ttinterp.c                                              3.1 * *  TrueType bytecode intepreter. * *  Copyright 1996-1999 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. * * *  Changes between 3.1 and 3.0: * *  - A more relaxed version of the interpreter.  It is now able to *    ignore errors like out-of-bound array access and writes in order *    to silently support broken glyphs (even if the results are not *    always pretty). * *    Note that one can use the flag TTLOAD_PEDANTIC to force *    TrueType-compliant interpretation. * *  - A big #if used to completely disable the interpreter, which *    is due to the Apple patents issues which emerged recently. * ******************************************************************/#include "freetype.h"#include "tttypes.h"#include "ttdebug.h"#include "ttcalc.h"#include "ttmemory.h"#include "ttinterp.h"#ifdef TT_CONFIG_OPTION_NO_INTERPRETER  LOCAL_FUNC  TT_Error  RunIns( PExecution_Context  exc )  {    /* do nothing - always successful */    (void)exc;    return TT_Err_Ok;  }#else#ifdef DEBUG_INTERPRETER#include <memory.h>#include "ttdebug.h"/* Define the `getch()' function.  On Unix systems, it is an alias  *//* for `getchar()', and the debugger front end must ensure that the *//* `stdin' file descriptor is not in line-by-line input mode.       */#ifdef OS2#include <conio.h>#else#define getch  getchar#endif#endif /* DEBUG_INTEPRETER *//* required by the tracing mode */#undef  TT_COMPONENT#define TT_COMPONENT      trace_interp/* In order to detect infinite loops in the code, we set-up         *//* a counter within the run loop. a singly stroke of interpretation *//* is now limited to a maximum number of opcodes defined below..    *//*                                                                  */#define MAX_RUNNABLE_OPCODES  1000000/* There are two kinds of implementations there:              *//*                                                            *//* a. static implementation:                                  *//*                                                            *//*    The current execution context is a static variable,     *//*    which fields are accessed directly by the interpreter   *//*    during execution.  The context is named 'cur'.          *//*                                                            *//*    This version is non-reentrant, of course.               *//*                                                            *//*                                                            *//* b. indirect implementation:                                *//*                                                            *//*    The current execution context is passed to _each_       *//*    function as its first argument, and each field is       *//*    thus accessed indirectly.                               *//*                                                            *//*    This version is, however, fully re-entrant.             *//*                                                            *//*                                                            *//*  The idea is that an indirect implementation may be        *//*  slower to execute on the low-end processors that are      *//*  used in some systems (like 386s or even 486s).            *//*                                                            *//*  When the interpreter started, we had no idea of the       *//*  time that glyph hinting (i.e. executing instructions)     *//*  could take in the whole process of rendering a glyph,     *//*  and a 10 to 30% performance penalty on low-end systems    *//*  didn't seem much of a good idea.  This question led us    *//*  to provide two distinct builds of the C version from      *//*  a single source, with the use of macros (again).          *//*                                                            *//*  Now that the engine is working (and working really        *//*  well!), it seems that the greatest time-consuming         *//*  factors are: file i/o, glyph loading, rasterizing and     *//*  _then_ glyph hinting!                                     *//*                                                            *//*  Tests performed with two versions of the 'fttimer'        *//*  program seem to indicate that hinting takes less than 5%  *//*  of the rendering process, which is dominated by glyph     *//*  loading and scan-line conversion by an high order of      *//*  magnitude.                                                *//*                                                            *//*  As a consequence, the indirect implementation is now the  *//*  default, as its performance costs can be considered       *//*  negligible in our context. Note, however, that we         *//*  kept the same source with macros because:                 *//*                                                            *//*    - the code is kept very close in design to the          *//*      Pascal one used for development.                      *//*                                                            *//*    - it's much more readable that way!                     *//*                                                            *//*    - it's still open to later experimentation and tuning   */#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER      /* indirect implementation */#define CUR (*exc)                 /* see ttobjs.h */#else                              /* static implementation */#define CUR cur  static TExecution_Context  cur;  /* static exec. context variable */  /* apparently, we have a _lot_ of direct indexing when accessing  */  /* the static 'cur', which makes the code bigger (due to all the  */  /* four bytes addresses).                                         */#endif  /* !TT_CONFIG_OPTION_STATIC_INTERPRETER */#define INS_ARG         EXEC_OPS PStorage args  /* see ttobjs.h */#define SKIP_Code()     SkipCode( EXEC_ARG )#define GET_ShortIns()  GetShortIns( EXEC_ARG )#define COMPUTE_Funcs() Compute_Funcs( EXEC_ARG )#define NORMalize( x, y, v )  Normalize( EXEC_ARGS x, y, v )#define SET_SuperRound( scale, flags ) \                        SetSuperRound( EXEC_ARGS scale, flags )#define INS_Goto_CodeRange( range, ip ) \                        Ins_Goto_CodeRange( EXEC_ARGS range, ip )#define CUR_Func_project( x, y )   CUR.func_project( EXEC_ARGS x, y )#define CUR_Func_move( z, p, d )   CUR.func_move( EXEC_ARGS z, p, d )#define CUR_Func_dualproj( x, y )  CUR.func_dualproj( EXEC_ARGS x, y )#define CUR_Func_freeProj( x, y )  CUR.func_freeProj( EXEC_ARGS x, y )#define CUR_Func_round( d, c )     CUR.func_round( EXEC_ARGS d, c )#define CUR_Func_read_cvt( index )       \          CUR.func_read_cvt( EXEC_ARGS index )#define CUR_Func_write_cvt( index, val ) \          CUR.func_write_cvt( EXEC_ARGS index, val )#define CUR_Func_move_cvt( index, val )  \          CUR.func_move_cvt( EXEC_ARGS index, val )#define CURRENT_Ratio()  Current_Ratio( EXEC_ARG )#define CURRENT_Ppem()   Current_Ppem( EXEC_ARG )#define CALC_Length()  Calc_Length( EXEC_ARG )#define INS_SxVTL( a, b, c, d ) Ins_SxVTL( EXEC_ARGS a, b, c, d )#define COMPUTE_Point_Displacement( a, b, c, d ) \           Compute_Point_Displacement( EXEC_ARGS a, b, c, d )#define MOVE_Zp2_Point( a, b, c, t )  Move_Zp2_Point( EXEC_ARGS a, b, c, t )#define CUR_Ppem()  Cur_PPEM( EXEC_ARG )  /* Instruction dispatch function, as used by the interpreter */  typedef void  (*TInstruction_Function)( INS_ARG );#define BOUNDS( x, n )  ( (x) >= (n) )/*********************************************************************//*                                                                   *//*  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.                              *//*                                                                   *//*  Note that for opcodes with a varying number of parameters,       *//*  either 0 or 1 arg is verified before execution, depending        *//*  on the nature of the instruction:                                *//*                                                                   *//*   - if the number of arguments is given by the bytecode           *//*     stream or the loop variable, 0 is chosen.                     *//*                                                                   *//*   - if the first argument is a count n that is followed           *//*     by arguments a1..an, then 1 is chosen.                        *//*                                                                   *//*********************************************************************/#undef  PACK#define PACK( x, y )  ((x << 4) | y)  static const Byte  Pop_Push_Count[256] =  {    /* opcodes are gathered in groups of 16 */    /* please keep the spaces as they are   */    /*  SVTCA  y  */  PACK( 0, 0 ),    /*  SVTCA  x  */  PACK( 0, 0 ),    /*  SPvTCA y  */  PACK( 0, 0 ),    /*  SPvTCA x  */  PACK( 0, 0 ),    /*  SFvTCA y  */  PACK( 0, 0 ),    /*  SFvTCA x  */  PACK( 0, 0 ),    /*  SPvTL //  */  PACK( 2, 0 ),    /*  SPvTL +   */  PACK( 2, 0 ),    /*  SFvTL //  */  PACK( 2, 0 ),    /*  SFvTL +   */  PACK( 2, 0 ),    /*  SPvFS     */  PACK( 2, 0 ),    /*  SFvFS     */  PACK( 2, 0 ),    /*  GPV       */  PACK( 0, 2 ),    /*  GFV       */  PACK( 0, 2 ),    /*  SFvTPv    */  PACK( 0, 0 ),    /*  ISECT     */  PACK( 5, 0 ),    /*  SRP0      */  PACK( 1, 0 ),    /*  SRP1      */  PACK( 1, 0 ),    /*  SRP2      */  PACK( 1, 0 ),    /*  SZP0      */  PACK( 1, 0 ),    /*  SZP1      */  PACK( 1, 0 ),    /*  SZP2      */  PACK( 1, 0 ),    /*  SZPS      */  PACK( 1, 0 ),    /*  SLOOP     */  PACK( 1, 0 ),    /*  RTG       */  PACK( 0, 0 ),    /*  RTHG      */  PACK( 0, 0 ),    /*  SMD       */  PACK( 1, 0 ),    /*  ELSE      */  PACK( 0, 0 ),    /*  JMPR      */  PACK( 1, 0 ),    /*  SCvTCi    */  PACK( 1, 0 ),    /*  SSwCi     */  PACK( 1, 0 ),    /*  SSW       */  PACK( 1, 0 ),    /*  DUP       */  PACK( 1, 2 ),    /*  POP       */  PACK( 1, 0 ),    /*  CLEAR     */  PACK( 0, 0 ),    /*  SWAP      */  PACK( 2, 2 ),    /*  DEPTH     */  PACK( 0, 1 ),    /*  CINDEX    */  PACK( 1, 1 ),    /*  MINDEX    */  PACK( 1, 0 ),    /*  AlignPTS  */  PACK( 2, 0 ),    /*  INS_$28   */  PACK( 0, 0 ),    /*  UTP       */  PACK( 1, 0 ),    /*  LOOPCALL  */  PACK( 2, 0 ),    /*  CALL      */  PACK( 1, 0 ),    /*  FDEF      */  PACK( 1, 0 ),    /*  ENDF      */  PACK( 0, 0 ),    /*  MDAP[0]   */  PACK( 1, 0 ),    /*  MDAP[1]   */  PACK( 1, 0 ),    /*  IUP[0]    */  PACK( 0, 0 ),    /*  IUP[1]    */  PACK( 0, 0 ),    /*  SHP[0]    */  PACK( 0, 0 ),    /*  SHP[1]    */  PACK( 0, 0 ),    /*  SHC[0]    */  PACK( 1, 0 ),    /*  SHC[1]    */  PACK( 1, 0 ),    /*  SHZ[0]    */  PACK( 1, 0 ),    /*  SHZ[1]    */  PACK( 1, 0 ),    /*  SHPIX     */  PACK( 1, 0 ),    /*  IP        */  PACK( 0, 0 ),    /*  MSIRP[0]  */  PACK( 2, 0 ),    /*  MSIRP[1]  */  PACK( 2, 0 ),    /*  AlignRP   */  PACK( 0, 0 ),    /*  RTDG      */  PACK( 0, 0 ),    /*  MIAP[0]   */  PACK( 2, 0 ),    /*  MIAP[1]   */  PACK( 2, 0 ),    /*  NPushB    */  PACK( 0, 0 ),    /*  NPushW    */  PACK( 0, 0 ),    /*  WS        */  PACK( 2, 0 ),    /*  RS        */  PACK( 1, 1 ),    /*  WCvtP     */  PACK( 2, 0 ),    /*  RCvt      */  PACK( 1, 1 ),    /*  GC[0]     */  PACK( 1, 1 ),    /*  GC[1]     */  PACK( 1, 1 ),    /*  SCFS      */  PACK( 2, 0 ),    /*  MD[0]     */  PACK( 2, 1 ),    /*  MD[1]     */  PACK( 2, 1 ),    /*  MPPEM     */  PACK( 0, 1 ),    /*  MPS       */  PACK( 0, 1 ),    /*  FlipON    */  PACK( 0, 0 ),    /*  FlipOFF   */  PACK( 0, 0 ),    /*  DEBUG     */  PACK( 1, 0 ),    /*  LT        */  PACK( 2, 1 ),    /*  LTEQ      */  PACK( 2, 1 ),    /*  GT        */  PACK( 2, 1 ),    /*  GTEQ      */  PACK( 2, 1 ),    /*  EQ        */  PACK( 2, 1 ),    /*  NEQ       */  PACK( 2, 1 ),    /*  ODD       */  PACK( 1, 1 ),    /*  EVEN      */  PACK( 1, 1 ),    /*  IF        */  PACK( 1, 0 ),    /*  EIF       */  PACK( 0, 0 ),    /*  AND       */  PACK( 2, 1 ),    /*  OR        */  PACK( 2, 1 ),    /*  NOT       */  PACK( 1, 1 ),    /*  DeltaP1   */  PACK( 1, 0 ),    /*  SDB       */  PACK( 1, 0 ),    /*  SDS       */  PACK( 1, 0 ),    /*  ADD       */  PACK( 2, 1 ),    /*  SUB       */  PACK( 2, 1 ),    /*  DIV       */  PACK( 2, 1 ),    /*  MUL       */  PACK( 2, 1 ),    /*  ABS       */  PACK( 1, 1 ),    /*  NEG       */  PACK( 1, 1 ),    /*  FLOOR     */  PACK( 1, 1 ),    /*  CEILING   */  PACK( 1, 1 ),    /*  ROUND[0]  */  PACK( 1, 1 ),    /*  ROUND[1]  */  PACK( 1, 1 ),    /*  ROUND[2]  */  PACK( 1, 1 ),    /*  ROUND[3]  */  PACK( 1, 1 ),    /*  NROUND[0] */  PACK( 1, 1 ),    /*  NROUND[1] */  PACK( 1, 1 ),    /*  NROUND[2] */  PACK( 1, 1 ),    /*  NROUND[3] */  PACK( 1, 1 ),    /*  WCvtF     */  PACK( 2, 0 ),    /*  DeltaP2   */  PACK( 1, 0 ),    /*  DeltaP3   */  PACK( 1, 0 ),    /*  DeltaCn[0] */ PACK( 1, 0 ),    /*  DeltaCn[1] */ PACK( 1, 0 ),    /*  DeltaCn[2] */ PACK( 1, 0 ),    /*  SROUND    */  PACK( 1, 0 ),    /*  S45Round  */  PACK( 1, 0 ),    /*  JROT      */  PACK( 2, 0 ),    /*  JROF      */  PACK( 2, 0 ),    /*  ROFF      */  PACK( 0, 0 ),    /*  INS_$7B   */  PACK( 0, 0 ),    /*  RUTG      */  PACK( 0, 0 ),    /*  RDTG      */  PACK( 0, 0 ),    /*  SANGW     */  PACK( 1, 0 ),    /*  AA        */  PACK( 1, 0 ),    /*  FlipPT    */  PACK( 0, 0 ),    /*  FlipRgON  */  PACK( 2, 0 ),    /*  FlipRgOFF */  PACK( 2, 0 ),    /*  INS_$83   */  PACK( 0, 0 ),    /*  INS_$84   */  PACK( 0, 0 ),    /*  ScanCTRL  */  PACK( 1, 0 ),    /*  SDVPTL[0] */  PACK( 2, 0 ),    /*  SDVPTL[1] */  PACK( 2, 0 ),    /*  GetINFO   */  PACK( 1, 1 ),    /*  IDEF      */  PACK( 1, 0 ),    /*  ROLL      */  PACK( 3, 3 ),    /*  MAX       */  PACK( 2, 1 ),    /*  MIN       */  PACK( 2, 1 ),    /*  ScanTYPE  */  PACK( 1, 0 ),    /*  InstCTRL  */  PACK( 2, 0 ),    /*  INS_$8F   */  PACK( 0, 0 ),    /*  INS_$90  */   PACK( 0, 0 ),    /*  INS_$91  */   PACK( 0, 0 ),    /*  INS_$92  */   PACK( 0, 0 ),    /*  INS_$93  */   PACK( 0, 0 ),    /*  INS_$94  */   PACK( 0, 0 ),    /*  INS_$95  */   PACK( 0, 0 ),    /*  INS_$96  */   PACK( 0, 0 ),    /*  INS_$97  */   PACK( 0, 0 ),    /*  INS_$98  */   PACK( 0, 0 ),    /*  INS_$99  */   PACK( 0, 0 ),    /*  INS_$9A  */   PACK( 0, 0 ),    /*  INS_$9B  */   PACK( 0, 0 ),    /*  INS_$9C  */   PACK( 0, 0 ),    /*  INS_$9D  */   PACK( 0, 0 ),    /*  INS_$9E  */   PACK( 0, 0 ),    /*  INS_$9F  */   PACK( 0, 0 ),    /*  INS_$A0  */   PACK( 0, 0 ),    /*  INS_$A1  */   PACK( 0, 0 ),    /*  INS_$A2  */   PACK( 0, 0 ),    /*  INS_$A3  */   PACK( 0, 0 ),    /*  INS_$A4  */   PACK( 0, 0 ),    /*  INS_$A5  */   PACK( 0, 0 ),    /*  INS_$A6  */   PACK( 0, 0 ),    /*  INS_$A7  */   PACK( 0, 0 ),    /*  INS_$A8  */   PACK( 0, 0 ),    /*  INS_$A9  */   PACK( 0, 0 ),    /*  INS_$AA  */   PACK( 0, 0 ),    /*  INS_$AB  */   PACK( 0, 0 ),    /*  INS_$AC  */   PACK( 0, 0 ),    /*  INS_$AD  */   PACK( 0, 0 ),    /*  INS_$AE  */   PACK( 0, 0 ),    /*  INS_$AF  */   PACK( 0, 0 ),    /*  PushB[0]  */  PACK( 0, 1 ),    /*  PushB[1]  */  PACK( 0, 2 ),    /*  PushB[2]  */  PACK( 0, 3 ),    /*  PushB[3]  */  PACK( 0, 4 ),    /*  PushB[4]  */  PACK( 0, 5 ),    /*  PushB[5]  */  PACK( 0, 6 ),    /*  PushB[6]  */  PACK( 0, 7 ),    /*  PushB[7]  */  PACK( 0, 8 ),    /*  PushW[0]  */  PACK( 0, 1 ),    /*  PushW[1]  */  PACK( 0, 2 ),    /*  PushW[2]  */  PACK( 0, 3 ),    /*  PushW[3]  */  PACK( 0, 4 ),    /*  PushW[4]  */  PACK( 0, 5 ),    /*  PushW[5]  */  PACK( 0, 6 ),    /*  PushW[6]  */  PACK( 0, 7 ),    /*  PushW[7]  */  PACK( 0, 8 ),    /*  MDRP[00]  */  PACK( 1, 0 ),    /*  MDRP[01]  */  PACK( 1, 0 ),    /*  MDRP[02]  */  PACK( 1, 0 ),    /*  MDRP[03]  */  PACK( 1, 0 ),    /*  MDRP[04]  */  PACK( 1, 0 ),    /*  MDRP[05]  */  PACK( 1, 0 ),    /*  MDRP[06]  */  PACK( 1, 0 ),    /*  MDRP[07]  */  PACK( 1, 0 ),    /*  MDRP[08]  */  PACK( 1, 0 ),    /*  MDRP[09]  */  PACK( 1, 0 ),    /*  MDRP[10]  */  PACK( 1, 0 ),    /*  MDRP[11]  */  PACK( 1, 0 ),    /*  MDRP[12]  */  PACK( 1, 0 ),    /*  MDRP[13]  */  PACK( 1, 0 ),    /*  MDRP[14]  */  PACK( 1, 0 ),    /*  MDRP[15]  */  PACK( 1, 0 ),    /*  MDRP[16]  */  PACK( 1, 0 ),    /*  MDRP[17]  */  PACK( 1, 0 ),    /*  MDRP[18]  */  PACK( 1, 0 ),    /*  MDRP[19]  */  PACK( 1, 0 ),    /*  MDRP[20]  */  PACK( 1, 0 ),    /*  MDRP[21]  */  PACK( 1, 0 ),    /*  MDRP[22]  */  PACK( 1, 0 ),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -