tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ttinterp.h (18268B)


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