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