(root)/
freetype-2.13.2/
src/
truetype/
ttinterp.h
       1  /****************************************************************************
       2   *
       3   * ttinterp.h
       4   *
       5   *   TrueType bytecode interpreter (specification).
       6   *
       7   * Copyright (C) 1996-2023 by
       8   * David Turner, Robert Wilhelm, and Werner Lemberg.
       9   *
      10   * This file is part of the FreeType project, and may only be used,
      11   * modified, and distributed under the terms of the FreeType project
      12   * license, LICENSE.TXT.  By continuing to use, modify, or distribute
      13   * this file you indicate that you have read the license and
      14   * understand and accept it fully.
      15   *
      16   */
      17  
      18  
      19  #ifndef TTINTERP_H_
      20  #define TTINTERP_H_
      21  
      22  #include "ttobjs.h"
      23  
      24  
      25  FT_BEGIN_HEADER
      26  
      27  
      28    /**************************************************************************
      29     *
      30     * Rounding mode constants.
      31     */
      32  #define TT_Round_Off             5
      33  #define TT_Round_To_Half_Grid    0
      34  #define TT_Round_To_Grid         1
      35  #define TT_Round_To_Double_Grid  2
      36  #define TT_Round_Up_To_Grid      4
      37  #define TT_Round_Down_To_Grid    3
      38  #define TT_Round_Super           6
      39  #define TT_Round_Super_45        7
      40  
      41  
      42    /**************************************************************************
      43     *
      44     * Function types used by the interpreter, depending on various modes
      45     * (e.g. the rounding mode, whether to render a vertical or horizontal
      46     * line etc).
      47     *
      48     */
      49  
      50    /* Rounding function */
      51    typedef FT_F26Dot6
      52    (*TT_Round_Func)( TT_ExecContext  exc,
      53                      FT_F26Dot6      distance,
      54                      FT_Int          color );
      55  
      56    /* Point displacement along the freedom vector routine */
      57    typedef void
      58    (*TT_Move_Func)( TT_ExecContext  exc,
      59                     TT_GlyphZone    zone,
      60                     FT_UShort       point,
      61                     FT_F26Dot6      distance );
      62  
      63    /* Distance projection along one of the projection vectors */
      64    typedef FT_F26Dot6
      65    (*TT_Project_Func)( TT_ExecContext  exc,
      66                        FT_Pos          dx,
      67                        FT_Pos          dy );
      68  
      69    /* getting current ppem.  Take care of non-square pixels if necessary */
      70    typedef FT_Long
      71    (*TT_Cur_Ppem_Func)( TT_ExecContext  exc );
      72  
      73    /* reading a cvt value.  Take care of non-square pixels if necessary */
      74    typedef FT_F26Dot6
      75    (*TT_Get_CVT_Func)( TT_ExecContext  exc,
      76                        FT_ULong        idx );
      77  
      78    /* setting or moving a cvt value.  Take care of non-square pixels  */
      79    /* if necessary                                                    */
      80    typedef void
      81    (*TT_Set_CVT_Func)( TT_ExecContext  exc,
      82                        FT_ULong        idx,
      83                        FT_F26Dot6      value );
      84  
      85  
      86    /**************************************************************************
      87     *
      88     * This structure defines a call record, used to manage function calls.
      89     */
      90    typedef struct  TT_CallRec_
      91    {
      92      FT_Int   Caller_Range;
      93      FT_Long  Caller_IP;
      94      FT_Long  Cur_Count;
      95  
      96      TT_DefRecord  *Def; /* either FDEF or IDEF */
      97  
      98    } TT_CallRec, *TT_CallStack;
      99  
     100  
     101    /**************************************************************************
     102     *
     103     * The main structure for the interpreter which collects all necessary
     104     * variables and states.
     105     *
     106     * Members that are initialized by `TT_Load_Context` are marked with '!'.
     107     * Members that are initialized by `TT_Run_Context` are marked with '@'.
     108     */
     109    typedef struct  TT_ExecContextRec_
     110    {
     111      TT_Face            face;       /* ! */
     112      TT_Size            size;       /* ! */
     113      FT_Memory          memory;
     114  
     115      /* instructions state */
     116  
     117      FT_Error           error;      /* last execution error */
     118  
     119      FT_Long            top;        /* @ top of exec. stack */
     120  
     121      FT_Long            stackSize;  /* ! size of exec. stack */
     122      FT_Long*           stack;      /* ! current exec. stack */
     123  
     124      FT_Long            args;
     125      FT_Long            new_top;    /* new top after exec. */
     126  
     127      TT_GlyphZoneRec    zp0,        /* @! zone records */
     128                         zp1,        /* @!              */
     129                         zp2,        /* @!              */
     130                         pts,        /*  !              */
     131                         twilight;   /*  !              */
     132  
     133      FT_Long            pointSize;  /* ! in 26.6 format */
     134      FT_Size_Metrics    metrics;    /* !                */
     135      TT_Size_Metrics    tt_metrics; /* ! size metrics   */
     136  
     137      TT_GraphicsState   GS;         /* !@ current graphics state */
     138  
     139      FT_Int             iniRange;  /* initial code range number   */
     140      FT_Int             curRange;  /* current code range number   */
     141      FT_Byte*           code;      /* current code range          */
     142      FT_Long            IP;        /* current instruction pointer */
     143      FT_Long            codeSize;  /* size of current range       */
     144  
     145      FT_Byte            opcode;    /* current opcode              */
     146      FT_Int             length;    /* length of current opcode    */
     147  
     148      FT_Bool            step_ins;  /* true if the interpreter must */
     149                                    /* increment IP after ins. exec */
     150      FT_ULong           cvtSize;   /* ! */
     151      FT_Long*           cvt;       /* ! */
     152      FT_ULong           glyfCvtSize;
     153      FT_Long*           glyfCvt;   /* cvt working copy for glyph */
     154  
     155      FT_UInt            glyphSize; /* ! glyph instructions buffer size */
     156      FT_Byte*           glyphIns;  /* ! glyph instructions buffer      */
     157  
     158      FT_UInt            numFDefs;  /* ! number of function defs         */
     159      FT_UInt            maxFDefs;  /* ! maximum number of function defs */
     160      TT_DefArray        FDefs;     /*   table of FDefs entries          */
     161  
     162      FT_UInt            numIDefs;  /* ! number of instruction defs */
     163      FT_UInt            maxIDefs;  /* ! maximum number of ins defs */
     164      TT_DefArray        IDefs;     /*   table of IDefs entries     */
     165  
     166      FT_UInt            maxFunc;   /* ! maximum function index    */
     167      FT_UInt            maxIns;    /* ! maximum instruction index */
     168  
     169      FT_Int             callTop,    /* @ top of call stack during execution */
     170                         callSize;   /*   size of call stack                 */
     171      TT_CallStack       callStack;  /*   call stack                         */
     172  
     173      FT_UShort          maxPoints;    /* capacity of this context's `pts' */
     174      FT_Short           maxContours;  /* record, expressed in points and  */
     175                                       /* contours.                        */
     176  
     177      TT_CodeRangeTable  codeRangeTable;  /* ! table of valid code ranges */
     178                                          /*   useful for the debugger    */
     179  
     180      FT_UShort          storeSize;    /* ! size of current storage */
     181      FT_Long*           storage;      /* ! storage area            */
     182      FT_UShort          glyfStoreSize;
     183      FT_Long*           glyfStorage;  /* storage working copy for glyph */
     184  
     185      FT_F26Dot6         period;     /* values used for the */
     186      FT_F26Dot6         phase;      /* `SuperRounding'     */
     187      FT_F26Dot6         threshold;
     188  
     189      FT_Bool            instruction_trap; /* ! If `True', the interpreter   */
     190                                           /*   exits after each instruction */
     191  
     192      TT_GraphicsState   default_GS;       /* graphics state resulting from   */
     193                                           /* the prep program                */
     194      FT_Bool            is_composite;     /* true if the glyph is composite  */
     195      FT_Bool            pedantic_hinting; /* true if pedantic interpretation */
     196  
     197      /* latest interpreter additions */
     198  
     199      FT_Long            F_dot_P;    /* dot product of freedom and projection */
     200                                     /* vectors                               */
     201      TT_Round_Func      func_round; /* current rounding function             */
     202  
     203      TT_Project_Func    func_project,   /* current projection function */
     204                         func_dualproj,  /* current dual proj. function */
     205                         func_freeProj;  /* current freedom proj. func  */
     206  
     207      TT_Move_Func       func_move;      /* current point move function     */
     208      TT_Move_Func       func_move_orig; /* move original position function */
     209  
     210      TT_Cur_Ppem_Func   func_cur_ppem;  /* get current proj. ppem value  */
     211  
     212      TT_Get_CVT_Func    func_read_cvt;  /* read a cvt entry              */
     213      TT_Set_CVT_Func    func_write_cvt; /* write a cvt entry (in pixels) */
     214      TT_Set_CVT_Func    func_move_cvt;  /* incr a cvt entry (in pixels)  */
     215  
     216      FT_Bool            grayscale;      /* bi-level hinting and */
     217                                         /* grayscale rendering  */
     218  
     219  #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
     220      /*
     221       * FreeType supports ClearType-like hinting of TrueType fonts through
     222       * the version 40 interpreter.  This is achieved through several hacks
     223       * in the base (v35) interpreter, as detailed below.
     224       *
     225       * ClearType is an umbrella term for several rendering techniques
     226       * employed by Microsoft's various GUI and rendering toolkit
     227       * implementations, most importantly: subpixel rendering for using the
     228       * RGB subpixels of LCDs to approximately triple the perceived
     229       * resolution on the x-axis and subpixel hinting for positioning stems
     230       * on subpixel borders.  TrueType programming is explicit, i.e., fonts
     231       * must be programmed to take advantage of ClearType's possibilities.
     232       *
     233       * When ClearType was introduced, it seemed unlikely that all fonts
     234       * would be reprogrammed, so Microsoft decided to implement a backward
     235       * compatibility mode.  It employs several simple to complicated
     236       * assumptions and tricks, many of them font-dependent, that modify the
     237       * interpretation of the bytecode contained in these fonts to retrofit
     238       * them into a ClearType-y look.  The quality of the results varies.
     239       * Most (web)fonts that were released since then have come to rely on
     240       * these hacks to render correctly, even some of Microsoft's flagship
     241       * fonts (e.g., Calibri, Cambria, Segoe UI).
     242       *
     243       * FreeType's minimal subpixel hinting code (interpreter version 40)
     244       * employs a small list of font-agnostic hacks loosely based on the
     245       * public information available on Microsoft's compatibility mode[2].
     246       * The focus is on modern (web)fonts rather than legacy fonts that were
     247       * made for monochrome rendering.  It will not match ClearType rendering
     248       * exactly.  Unlike the `Infinality' code (interpreter version 38) that
     249       * came before, it will not try to toggle hacks for specific fonts for
     250       * performance and complexity reasons.  It will fall back to version 35
     251       * behavior for tricky fonts[1] or when monochrome rendering is
     252       * requested.
     253       *
     254       * Major hacks
     255       *
     256       * - Any point movement on the x axis is ignored (cf. `Direct_Move' and
     257       *   `Direct_Move_X').  This has the smallest code footprint and single
     258       *   biggest effect.  The ClearType way to increase resolution is
     259       *   supersampling the x axis, the FreeType way is ignoring instructions
     260       *   on the x axis, which gives the same result in the majority of
     261       *   cases.
     262       *
     263       * - Points are not moved post-IUP (neither on the x nor on the y axis),
     264       *   except the x component of diagonal moves post-IUP (cf.
     265       *   `Direct_Move', `Direct_Move_Y', `Move_Zp2_Point').  Post-IUP
     266       *   changes are commonly used to `fix' pixel patterns which has little
     267       *   use outside monochrome rendering.
     268       *
     269       * - SHPIX and DELTAP don't execute unless moving a composite on the
     270       *   y axis or moving a previously y touched point.  SHPIX additionally
     271       *   denies movement on the x axis (cf. `Ins_SHPIX' and `Ins_DELTAP').
     272       *   Both instructions are commonly used to `fix' pixel patterns for
     273       *   monochrome or Windows's GDI rendering but make little sense for
     274       *   FreeType rendering.  Both can distort the outline.  See [2] for
     275       *   details.
     276       *
     277       * - The hdmx table and modifications to phantom points are ignored.
     278       *   Bearings and advance widths remain unchanged (except rounding them
     279       *   outside the interpreter!), cf. `compute_glyph_metrics' and
     280       *   `TT_Hint_Glyph'.  Letting non-native-ClearType fonts modify spacing
     281       *   might mess up spacing.
     282       *
     283       * Minor hacks
     284       *
     285       * - FLIPRGON, FLIPRGOFF, and FLIPPT don't execute post-IUP.  This
     286       *   prevents dents in e.g. Arial-Regular's `D' and `G' glyphs at
     287       *   various sizes.
     288       *
     289       * (Post-IUP is the state after both IUP[x] and IUP[y] have been
     290       * executed.)
     291       *
     292       * The best results are achieved for fonts that were from the outset
     293       * designed with ClearType in mind, meaning they leave the x axis mostly
     294       * alone and don't mess with the `final' outline to produce more
     295       * pleasing pixel patterns.  The harder the designer tried to produce
     296       * very specific patterns (`superhinting') for pre-ClearType-displays,
     297       * the worse the results.
     298       *
     299       * Microsoft defines a way to turn off backward compatibility and
     300       * interpret instructions as before (called `native ClearType')[2][3].
     301       * The font designer then regains full control and is responsible for
     302       * making the font work correctly with ClearType without any
     303       * hand-holding by the interpreter or rasterizer[4].  The v40
     304       * interpreter assumes backward compatibility by default, which can be
     305       * turned off the same way by executing the following in the control
     306       * program (cf. `Ins_INSTCTRL').
     307       *
     308       *   #PUSH 4,3
     309       *   INSTCTRL[]
     310       *
     311       * [1] Tricky fonts as FreeType defines them rely on the bytecode
     312       *     interpreter to display correctly.  Hacks can interfere with them,
     313       *     so they get treated like native ClearType fonts (v40 with
     314       *     backward compatibility turned off).  Cf. `TT_RunIns'.
     315       *
     316       * [2] Proposed by Microsoft's Greg Hitchcock in
     317       *     https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx
     318       *
     319       * [3] Beat Stamm describes it in more detail:
     320       *     http://rastertragedy.com/RTRCh4.htm#Sec12.
     321       *
     322       * [4] The list of `native ClearType' fonts is small at the time of this
     323       *     writing; I found the following on a Windows 10 Update 1511
     324       *     installation: Constantia, Corbel, Sitka, Malgun Gothic, Microsoft
     325       *     JhengHei (Bold and UI Bold), Microsoft YaHei (Bold and UI Bold),
     326       *     SimSun, NSimSun, and Yu Gothic.
     327       *
     328       */
     329  
     330      /* Using v40 implies subpixel hinting, unless FT_RENDER_MODE_MONO has been
     331       * requested.  Used to detect interpreter */
     332      /* version switches.  `_lean' to differentiate from the Infinality */
     333      /* `subpixel_hinting', which is managed differently.               */
     334      FT_Bool            subpixel_hinting_lean;
     335  
     336      /* Long side of a LCD subpixel is vertical (e.g., screen is rotated). */
     337      /* `_lean' to differentiate from the Infinality `vertical_lcd', which */
     338      /* is managed differently.                                            */
     339      FT_Bool            vertical_lcd_lean;
     340  
     341      /* Default to backward compatibility mode in v40 interpreter.  If   */
     342      /* this is false, it implies the interpreter is in v35 or in native */
     343      /* ClearType mode.                                                  */
     344      FT_Bool            backward_compatibility;
     345  
     346      /* Useful for detecting and denying post-IUP trickery that is usually */
     347      /* used to fix pixel patterns (`superhinting').                       */
     348      FT_Bool            iupx_called;
     349      FT_Bool            iupy_called;
     350  
     351      /* ClearType hinting and grayscale rendering, as used by Universal */
     352      /* Windows Platform apps (Windows 8 and above).  Like the standard */
     353      /* colorful ClearType mode, it utilizes a vastly increased virtual */
     354      /* resolution on the x axis.  Different from bi-level hinting and  */
     355      /* grayscale rendering, the old mode from Win9x days that roughly  */
     356      /* adheres to the physical pixel grid on both axes.                */
     357      FT_Bool            grayscale_cleartype;
     358  #endif /* TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL */
     359  
     360      /* We maintain two counters (in addition to the instruction counter) */
     361      /* that act as loop detectors for LOOPCALL and jump opcodes with     */
     362      /* negative arguments.                                               */
     363      FT_ULong           loopcall_counter;
     364      FT_ULong           loopcall_counter_max;
     365      FT_ULong           neg_jump_counter;
     366      FT_ULong           neg_jump_counter_max;
     367  
     368    } TT_ExecContextRec;
     369  
     370  
     371    extern const TT_GraphicsState  tt_default_graphics_state;
     372  
     373  
     374  #ifdef TT_USE_BYTECODE_INTERPRETER
     375    FT_LOCAL( void )
     376    TT_Goto_CodeRange( TT_ExecContext  exec,
     377                       FT_Int          range,
     378                       FT_Long         IP );
     379  
     380    FT_LOCAL( void )
     381    TT_Set_CodeRange( TT_ExecContext  exec,
     382                      FT_Int          range,
     383                      void*           base,
     384                      FT_Long         length );
     385  
     386    FT_LOCAL( void )
     387    TT_Clear_CodeRange( TT_ExecContext  exec,
     388                        FT_Int          range );
     389  #endif /* TT_USE_BYTECODE_INTERPRETER */
     390  
     391  
     392    /**************************************************************************
     393     *
     394     * @Function:
     395     *   TT_New_Context
     396     *
     397     * @Description:
     398     *   Create a `TT_ExecContext`.  Note that there is now an execution
     399     *   context per `TT_Size` that is not shared among faces.
     400     *
     401     * @Input:
     402     *   driver ::
     403     *     A handle to the driver, used for memory allocation.
     404     *
     405     * @Return:
     406     *   A handle to a new empty execution context.
     407     *
     408     * @Note:
     409     *   Only the glyph loader and debugger should call this function.
     410     *   (And right now only the glyph loader uses it.)
     411     */
     412    FT_EXPORT( TT_ExecContext )
     413    TT_New_Context( TT_Driver  driver );
     414  
     415  
     416  #ifdef TT_USE_BYTECODE_INTERPRETER
     417    FT_LOCAL( void )
     418    TT_Done_Context( TT_ExecContext  exec );
     419  
     420    FT_LOCAL( FT_Error )
     421    TT_Load_Context( TT_ExecContext  exec,
     422                     TT_Face         face,
     423                     TT_Size         size );
     424  
     425    FT_LOCAL( void )
     426    TT_Save_Context( TT_ExecContext  exec,
     427                     TT_Size         ins );
     428  
     429    FT_LOCAL( FT_Error )
     430    TT_Run_Context( TT_ExecContext  exec );
     431  #endif /* TT_USE_BYTECODE_INTERPRETER */
     432  
     433  
     434    /**************************************************************************
     435     *
     436     * @Function:
     437     *   TT_RunIns
     438     *
     439     * @Description:
     440     *   Executes one or more instruction in the execution context.  This
     441     *   is the main function of the TrueType opcode interpreter.
     442     *
     443     * @Input:
     444     *   exec ::
     445     *     A handle to the target execution context.
     446     *
     447     * @Return:
     448     *   FreeType error code.  0 means success.
     449     *
     450     * @Note:
     451     *   Only the object manager and debugger should call this function.
     452     *
     453     *   This function is publicly exported because it is directly
     454     *   invoked by the TrueType debugger.
     455     */
     456    FT_EXPORT( FT_Error )
     457    TT_RunIns( void*  exec );
     458  
     459  
     460  FT_END_HEADER
     461  
     462  #endif /* TTINTERP_H_ */
     463  
     464  
     465  /* END */