PageRenderTime 81ms CodeModel.GetById 17ms app.highlight 54ms RepoModel.GetById 1ms app.codeStats 1ms

/src/compiler/android-ndk/jni/freetype/src/truetype/ttinterp.c

http://ftk.googlecode.com/
C | 1713 lines | 923 code | 314 blank | 476 comment | 45 complexity | a38ffc3ad46931423aa26ed21fd0579a MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/***************************************************************************/
   2/*                                                                         */
   3/*  ttinterp.c                                                             */
   4/*                                                                         */
   5/*    TrueType bytecode interpreter (body).                                */
   6/*                                                                         */
   7/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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#include <ft2build.h>
  20#include FT_INTERNAL_DEBUG_H
  21#include FT_INTERNAL_CALC_H
  22#include FT_TRIGONOMETRY_H
  23#include FT_SYSTEM_H
  24
  25#include "ttinterp.h"
  26
  27#include "tterrors.h"
  28
  29
  30#ifdef TT_USE_BYTECODE_INTERPRETER
  31
  32
  33#define TT_MULFIX           FT_MulFix
  34#define TT_MULDIV           FT_MulDiv
  35#define TT_MULDIV_NO_ROUND  FT_MulDiv_No_Round
  36
  37
  38  /*************************************************************************/
  39  /*                                                                       */
  40  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  41  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  42  /* messages during execution.                                            */
  43  /*                                                                       */
  44#undef  FT_COMPONENT
  45#define FT_COMPONENT  trace_ttinterp
  46
  47  /*************************************************************************/
  48  /*                                                                       */
  49  /* In order to detect infinite loops in the code, we set up a counter    */
  50  /* within the run loop.  A single stroke of interpretation is now        */
  51  /* limited to a maximal number of opcodes defined below.                 */
  52  /*                                                                       */
  53#define MAX_RUNNABLE_OPCODES  1000000L
  54
  55
  56  /*************************************************************************/
  57  /*                                                                       */
  58  /* There are two kinds of implementations:                               */
  59  /*                                                                       */
  60  /* a. static implementation                                              */
  61  /*                                                                       */
  62  /*    The current execution context is a static variable, which fields   */
  63  /*    are accessed directly by the interpreter during execution.  The    */
  64  /*    context is named `cur'.                                            */
  65  /*                                                                       */
  66  /*    This version is non-reentrant, of course.                          */
  67  /*                                                                       */
  68  /* b. indirect implementation                                            */
  69  /*                                                                       */
  70  /*    The current execution context is passed to _each_ function as its  */
  71  /*    first argument, and each field is thus accessed indirectly.        */
  72  /*                                                                       */
  73  /*    This version is fully re-entrant.                                  */
  74  /*                                                                       */
  75  /* The idea is that an indirect implementation may be slower to execute  */
  76  /* on low-end processors that are used in some systems (like 386s or     */
  77  /* even 486s).                                                           */
  78  /*                                                                       */
  79  /* As a consequence, the indirect implementation is now the default, as  */
  80  /* its performance costs can be considered negligible in our context.    */
  81  /* Note, however, that we kept the same source with macros because:      */
  82  /*                                                                       */
  83  /* - The code is kept very close in design to the Pascal code used for   */
  84  /*   development.                                                        */
  85  /*                                                                       */
  86  /* - It's much more readable that way!                                   */
  87  /*                                                                       */
  88  /* - It's still open to experimentation and tuning.                      */
  89  /*                                                                       */
  90  /*************************************************************************/
  91
  92
  93#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER     /* indirect implementation */
  94
  95#define CUR  (*exc)                             /* see ttobjs.h */
  96
  97  /*************************************************************************/
  98  /*                                                                       */
  99  /* This macro is used whenever `exec' is unused in a function, to avoid  */
 100  /* stupid warnings from pedantic compilers.                              */
 101  /*                                                                       */
 102#define FT_UNUSED_EXEC  FT_UNUSED( exc )
 103
 104#else                                           /* static implementation */
 105
 106#define CUR  cur
 107
 108#define FT_UNUSED_EXEC  int  __dummy = __dummy
 109
 110  static
 111  TT_ExecContextRec  cur;   /* static exec. context variable */
 112
 113  /* apparently, we have a _lot_ of direct indexing when accessing  */
 114  /* the static `cur', which makes the code bigger (due to all the  */
 115  /* four bytes addresses).                                         */
 116
 117#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */
 118
 119
 120  /*************************************************************************/
 121  /*                                                                       */
 122  /* The instruction argument stack.                                       */
 123  /*                                                                       */
 124#define INS_ARG  EXEC_OP_ FT_Long*  args    /* see ttobjs.h for EXEC_OP_ */
 125
 126
 127  /*************************************************************************/
 128  /*                                                                       */
 129  /* This macro is used whenever `args' is unused in a function, to avoid  */
 130  /* stupid warnings from pedantic compilers.                              */
 131  /*                                                                       */
 132#define FT_UNUSED_ARG  FT_UNUSED_EXEC; FT_UNUSED( args )
 133
 134
 135  /*************************************************************************/
 136  /*                                                                       */
 137  /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to        */
 138  /* increase readability of the code.                                     */
 139  /*                                                                       */
 140  /*************************************************************************/
 141
 142
 143#define SKIP_Code() \
 144          SkipCode( EXEC_ARG )
 145
 146#define GET_ShortIns() \
 147          GetShortIns( EXEC_ARG )
 148
 149#define NORMalize( x, y, v ) \
 150          Normalize( EXEC_ARG_ x, y, v )
 151
 152#define SET_SuperRound( scale, flags ) \
 153          SetSuperRound( EXEC_ARG_ scale, flags )
 154
 155#define ROUND_None( d, c ) \
 156          Round_None( EXEC_ARG_ d, c )
 157
 158#define INS_Goto_CodeRange( range, ip ) \
 159          Ins_Goto_CodeRange( EXEC_ARG_ range, ip )
 160
 161#define CUR_Func_move( z, p, d ) \
 162          CUR.func_move( EXEC_ARG_ z, p, d )
 163
 164#define CUR_Func_move_orig( z, p, d ) \
 165          CUR.func_move_orig( EXEC_ARG_ z, p, d )
 166
 167#define CUR_Func_round( d, c ) \
 168          CUR.func_round( EXEC_ARG_ d, c )
 169
 170#define CUR_Func_read_cvt( index ) \
 171          CUR.func_read_cvt( EXEC_ARG_ index )
 172
 173#define CUR_Func_write_cvt( index, val ) \
 174          CUR.func_write_cvt( EXEC_ARG_ index, val )
 175
 176#define CUR_Func_move_cvt( index, val ) \
 177          CUR.func_move_cvt( EXEC_ARG_ index, val )
 178
 179#define CURRENT_Ratio() \
 180          Current_Ratio( EXEC_ARG )
 181
 182#define CURRENT_Ppem() \
 183          Current_Ppem( EXEC_ARG )
 184
 185#define CUR_Ppem() \
 186          Cur_PPEM( EXEC_ARG )
 187
 188#define INS_SxVTL( a, b, c, d ) \
 189          Ins_SxVTL( EXEC_ARG_ a, b, c, d )
 190
 191#define COMPUTE_Funcs() \
 192          Compute_Funcs( EXEC_ARG )
 193
 194#define COMPUTE_Round( a ) \
 195          Compute_Round( EXEC_ARG_ a )
 196
 197#define COMPUTE_Point_Displacement( a, b, c, d ) \
 198          Compute_Point_Displacement( EXEC_ARG_ a, b, c, d )
 199
 200#define MOVE_Zp2_Point( a, b, c, t ) \
 201          Move_Zp2_Point( EXEC_ARG_ a, b, c, t )
 202
 203
 204#define CUR_Func_project( v1, v2 )  \
 205          CUR.func_project( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
 206
 207#define CUR_Func_dualproj( v1, v2 )  \
 208          CUR.func_dualproj( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
 209
 210#define CUR_fast_project( v ) \
 211          CUR.func_project( EXEC_ARG_ (v)->x, (v)->y )
 212
 213#define CUR_fast_dualproj( v ) \
 214          CUR.func_dualproj( EXEC_ARG_ (v)->x, (v)->y )
 215
 216
 217  /*************************************************************************/
 218  /*                                                                       */
 219  /* Instruction dispatch function, as used by the interpreter.            */
 220  /*                                                                       */
 221  typedef void  (*TInstruction_Function)( INS_ARG );
 222
 223
 224  /*************************************************************************/
 225  /*                                                                       */
 226  /* A simple bounds-checking macro.                                       */
 227  /*                                                                       */
 228#define BOUNDS( x, n )  ( (FT_UInt)(x) >= (FT_UInt)(n) )
 229
 230#undef  SUCCESS
 231#define SUCCESS  0
 232
 233#undef  FAILURE
 234#define FAILURE  1
 235
 236#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 237#define GUESS_VECTOR( V )                                         \
 238  if ( CUR.face->unpatented_hinting )                             \
 239  {                                                               \
 240    CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); \
 241    CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); \
 242  }
 243#else
 244#define GUESS_VECTOR( V )
 245#endif
 246
 247  /*************************************************************************/
 248  /*                                                                       */
 249  /*                        CODERANGE FUNCTIONS                            */
 250  /*                                                                       */
 251  /*************************************************************************/
 252
 253
 254  /*************************************************************************/
 255  /*                                                                       */
 256  /* <Function>                                                            */
 257  /*    TT_Goto_CodeRange                                                  */
 258  /*                                                                       */
 259  /* <Description>                                                         */
 260  /*    Switches to a new code range (updates the code related elements in */
 261  /*    `exec', and `IP').                                                 */
 262  /*                                                                       */
 263  /* <Input>                                                               */
 264  /*    range :: The new execution code range.                             */
 265  /*                                                                       */
 266  /*    IP    :: The new IP in the new code range.                         */
 267  /*                                                                       */
 268  /* <InOut>                                                               */
 269  /*    exec  :: The target execution context.                             */
 270  /*                                                                       */
 271  /* <Return>                                                              */
 272  /*    FreeType error code.  0 means success.                             */
 273  /*                                                                       */
 274  FT_LOCAL_DEF( FT_Error )
 275  TT_Goto_CodeRange( TT_ExecContext  exec,
 276                     FT_Int          range,
 277                     FT_Long         IP )
 278  {
 279    TT_CodeRange*  coderange;
 280
 281
 282    FT_ASSERT( range >= 1 && range <= 3 );
 283
 284    coderange = &exec->codeRangeTable[range - 1];
 285
 286    FT_ASSERT( coderange->base != NULL );
 287
 288    /* NOTE: Because the last instruction of a program may be a CALL */
 289    /*       which will return to the first byte *after* the code    */
 290    /*       range, we test for IP <= Size instead of IP < Size.     */
 291    /*                                                               */
 292    FT_ASSERT( (FT_ULong)IP <= coderange->size );
 293
 294    exec->code     = coderange->base;
 295    exec->codeSize = coderange->size;
 296    exec->IP       = IP;
 297    exec->curRange = range;
 298
 299    return TT_Err_Ok;
 300  }
 301
 302
 303  /*************************************************************************/
 304  /*                                                                       */
 305  /* <Function>                                                            */
 306  /*    TT_Set_CodeRange                                                   */
 307  /*                                                                       */
 308  /* <Description>                                                         */
 309  /*    Sets a code range.                                                 */
 310  /*                                                                       */
 311  /* <Input>                                                               */
 312  /*    range  :: The code range index.                                    */
 313  /*                                                                       */
 314  /*    base   :: The new code base.                                       */
 315  /*                                                                       */
 316  /*    length :: The range size in bytes.                                 */
 317  /*                                                                       */
 318  /* <InOut>                                                               */
 319  /*    exec   :: The target execution context.                            */
 320  /*                                                                       */
 321  /* <Return>                                                              */
 322  /*    FreeType error code.  0 means success.                             */
 323  /*                                                                       */
 324  FT_LOCAL_DEF( FT_Error )
 325  TT_Set_CodeRange( TT_ExecContext  exec,
 326                    FT_Int          range,
 327                    void*           base,
 328                    FT_Long         length )
 329  {
 330    FT_ASSERT( range >= 1 && range <= 3 );
 331
 332    exec->codeRangeTable[range - 1].base = (FT_Byte*)base;
 333    exec->codeRangeTable[range - 1].size = length;
 334
 335    return TT_Err_Ok;
 336  }
 337
 338
 339  /*************************************************************************/
 340  /*                                                                       */
 341  /* <Function>                                                            */
 342  /*    TT_Clear_CodeRange                                                 */
 343  /*                                                                       */
 344  /* <Description>                                                         */
 345  /*    Clears a code range.                                               */
 346  /*                                                                       */
 347  /* <Input>                                                               */
 348  /*    range :: The code range index.                                     */
 349  /*                                                                       */
 350  /* <InOut>                                                               */
 351  /*    exec  :: The target execution context.                             */
 352  /*                                                                       */
 353  /* <Return>                                                              */
 354  /*    FreeType error code.  0 means success.                             */
 355  /*                                                                       */
 356  /* <Note>                                                                */
 357  /*    Does not set the Error variable.                                   */
 358  /*                                                                       */
 359  FT_LOCAL_DEF( FT_Error )
 360  TT_Clear_CodeRange( TT_ExecContext  exec,
 361                      FT_Int          range )
 362  {
 363    FT_ASSERT( range >= 1 && range <= 3 );
 364
 365    exec->codeRangeTable[range - 1].base = NULL;
 366    exec->codeRangeTable[range - 1].size = 0;
 367
 368    return TT_Err_Ok;
 369  }
 370
 371
 372  /*************************************************************************/
 373  /*                                                                       */
 374  /*                   EXECUTION CONTEXT ROUTINES                          */
 375  /*                                                                       */
 376  /*************************************************************************/
 377
 378
 379  /*************************************************************************/
 380  /*                                                                       */
 381  /* <Function>                                                            */
 382  /*    TT_Done_Context                                                    */
 383  /*                                                                       */
 384  /* <Description>                                                         */
 385  /*    Destroys a given context.                                          */
 386  /*                                                                       */
 387  /* <Input>                                                               */
 388  /*    exec   :: A handle to the target execution context.                */
 389  /*                                                                       */
 390  /*    memory :: A handle to the parent memory object.                    */
 391  /*                                                                       */
 392  /* <Return>                                                              */
 393  /*    FreeType error code.  0 means success.                             */
 394  /*                                                                       */
 395  /* <Note>                                                                */
 396  /*    Only the glyph loader and debugger should call this function.      */
 397  /*                                                                       */
 398  FT_LOCAL_DEF( FT_Error )
 399  TT_Done_Context( TT_ExecContext  exec )
 400  {
 401    FT_Memory  memory = exec->memory;
 402
 403
 404    /* points zone */
 405    exec->maxPoints   = 0;
 406    exec->maxContours = 0;
 407
 408    /* free stack */
 409    FT_FREE( exec->stack );
 410    exec->stackSize = 0;
 411
 412    /* free call stack */
 413    FT_FREE( exec->callStack );
 414    exec->callSize = 0;
 415    exec->callTop  = 0;
 416
 417    /* free glyph code range */
 418    FT_FREE( exec->glyphIns );
 419    exec->glyphSize = 0;
 420
 421    exec->size = NULL;
 422    exec->face = NULL;
 423
 424    FT_FREE( exec );
 425
 426    return TT_Err_Ok;
 427  }
 428
 429
 430  /*************************************************************************/
 431  /*                                                                       */
 432  /* <Function>                                                            */
 433  /*    Init_Context                                                       */
 434  /*                                                                       */
 435  /* <Description>                                                         */
 436  /*    Initializes a context object.                                      */
 437  /*                                                                       */
 438  /* <Input>                                                               */
 439  /*    memory :: A handle to the parent memory object.                    */
 440  /*                                                                       */
 441  /* <InOut>                                                               */
 442  /*    exec   :: A handle to the target execution context.                */
 443  /*                                                                       */
 444  /* <Return>                                                              */
 445  /*    FreeType error code.  0 means success.                             */
 446  /*                                                                       */
 447  static FT_Error
 448  Init_Context( TT_ExecContext  exec,
 449                FT_Memory       memory )
 450  {
 451    FT_Error  error;
 452
 453
 454    FT_TRACE1(( "Init_Context: new object at 0x%08p\n", exec ));
 455
 456    exec->memory   = memory;
 457    exec->callSize = 32;
 458
 459    if ( FT_NEW_ARRAY( exec->callStack, exec->callSize ) )
 460      goto Fail_Memory;
 461
 462    /* all values in the context are set to 0 already, but this is */
 463    /* here as a remainder                                         */
 464    exec->maxPoints   = 0;
 465    exec->maxContours = 0;
 466
 467    exec->stackSize = 0;
 468    exec->glyphSize = 0;
 469
 470    exec->stack     = NULL;
 471    exec->glyphIns  = NULL;
 472
 473    exec->face = NULL;
 474    exec->size = NULL;
 475
 476    return TT_Err_Ok;
 477
 478  Fail_Memory:
 479    FT_ERROR(( "Init_Context: not enough memory for 0x%08lx\n",
 480               (FT_Long)exec ));
 481    TT_Done_Context( exec );
 482
 483    return error;
 484 }
 485
 486
 487  /*************************************************************************/
 488  /*                                                                       */
 489  /* <Function>                                                            */
 490  /*    Update_Max                                                         */
 491  /*                                                                       */
 492  /* <Description>                                                         */
 493  /*    Checks the size of a buffer and reallocates it if necessary.       */
 494  /*                                                                       */
 495  /* <Input>                                                               */
 496  /*    memory     :: A handle to the parent memory object.                */
 497  /*                                                                       */
 498  /*    multiplier :: The size in bytes of each element in the buffer.     */
 499  /*                                                                       */
 500  /*    new_max    :: The new capacity (size) of the buffer.               */
 501  /*                                                                       */
 502  /* <InOut>                                                               */
 503  /*    size       :: The address of the buffer's current size expressed   */
 504  /*                  in elements.                                         */
 505  /*                                                                       */
 506  /*    buff       :: The address of the buffer base pointer.              */
 507  /*                                                                       */
 508  /* <Return>                                                              */
 509  /*    FreeType error code.  0 means success.                             */
 510  /*                                                                       */
 511  static FT_Error
 512  Update_Max( FT_Memory  memory,
 513              FT_ULong*  size,
 514              FT_Long    multiplier,
 515              void*      _pbuff,
 516              FT_ULong   new_max )
 517  {
 518    FT_Error  error;
 519    void**    pbuff = (void**)_pbuff;
 520
 521
 522    if ( *size < new_max )
 523    {
 524      if ( FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) )
 525        return error;
 526      *size = new_max;
 527    }
 528
 529    return TT_Err_Ok;
 530  }
 531
 532
 533  /*************************************************************************/
 534  /*                                                                       */
 535  /* <Function>                                                            */
 536  /*    TT_Load_Context                                                    */
 537  /*                                                                       */
 538  /* <Description>                                                         */
 539  /*    Prepare an execution context for glyph hinting.                    */
 540  /*                                                                       */
 541  /* <Input>                                                               */
 542  /*    face :: A handle to the source face object.                        */
 543  /*                                                                       */
 544  /*    size :: A handle to the source size object.                        */
 545  /*                                                                       */
 546  /* <InOut>                                                               */
 547  /*    exec :: A handle to the target execution context.                  */
 548  /*                                                                       */
 549  /* <Return>                                                              */
 550  /*    FreeType error code.  0 means success.                             */
 551  /*                                                                       */
 552  /* <Note>                                                                */
 553  /*    Only the glyph loader and debugger should call this function.      */
 554  /*                                                                       */
 555  FT_LOCAL_DEF( FT_Error )
 556  TT_Load_Context( TT_ExecContext  exec,
 557                   TT_Face         face,
 558                   TT_Size         size )
 559  {
 560    FT_Int          i;
 561    FT_ULong        tmp;
 562    TT_MaxProfile*  maxp;
 563    FT_Error        error;
 564
 565
 566    exec->face = face;
 567    maxp       = &face->max_profile;
 568    exec->size = size;
 569
 570    if ( size )
 571    {
 572      exec->numFDefs   = size->num_function_defs;
 573      exec->maxFDefs   = size->max_function_defs;
 574      exec->numIDefs   = size->num_instruction_defs;
 575      exec->maxIDefs   = size->max_instruction_defs;
 576      exec->FDefs      = size->function_defs;
 577      exec->IDefs      = size->instruction_defs;
 578      exec->tt_metrics = size->ttmetrics;
 579      exec->metrics    = size->metrics;
 580
 581      exec->maxFunc    = size->max_func;
 582      exec->maxIns     = size->max_ins;
 583
 584      for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
 585        exec->codeRangeTable[i] = size->codeRangeTable[i];
 586
 587      /* set graphics state */
 588      exec->GS = size->GS;
 589
 590      exec->cvtSize = size->cvt_size;
 591      exec->cvt     = size->cvt;
 592
 593      exec->storeSize = size->storage_size;
 594      exec->storage   = size->storage;
 595
 596      exec->twilight  = size->twilight;
 597    }
 598
 599    /* XXX: We reserve a little more elements on the stack to deal safely */
 600    /*      with broken fonts like arialbs, courbs, timesbs, etc.         */
 601    tmp = exec->stackSize;
 602    error = Update_Max( exec->memory,
 603                        &tmp,
 604                        sizeof ( FT_F26Dot6 ),
 605                        (void*)&exec->stack,
 606                        maxp->maxStackElements + 32 );
 607    exec->stackSize = (FT_UInt)tmp;
 608    if ( error )
 609      return error;
 610
 611    tmp = exec->glyphSize;
 612    error = Update_Max( exec->memory,
 613                        &tmp,
 614                        sizeof ( FT_Byte ),
 615                        (void*)&exec->glyphIns,
 616                        maxp->maxSizeOfInstructions );
 617    exec->glyphSize = (FT_UShort)tmp;
 618    if ( error )
 619      return error;
 620
 621    exec->pts.n_points   = 0;
 622    exec->pts.n_contours = 0;
 623
 624    exec->zp1 = exec->pts;
 625    exec->zp2 = exec->pts;
 626    exec->zp0 = exec->pts;
 627
 628    exec->instruction_trap = FALSE;
 629
 630    return TT_Err_Ok;
 631  }
 632
 633
 634  /*************************************************************************/
 635  /*                                                                       */
 636  /* <Function>                                                            */
 637  /*    TT_Save_Context                                                    */
 638  /*                                                                       */
 639  /* <Description>                                                         */
 640  /*    Saves the code ranges in a `size' object.                          */
 641  /*                                                                       */
 642  /* <Input>                                                               */
 643  /*    exec :: A handle to the source execution context.                  */
 644  /*                                                                       */
 645  /* <InOut>                                                               */
 646  /*    size :: A handle to the target size object.                        */
 647  /*                                                                       */
 648  /* <Return>                                                              */
 649  /*    FreeType error code.  0 means success.                             */
 650  /*                                                                       */
 651  /* <Note>                                                                */
 652  /*    Only the glyph loader and debugger should call this function.      */
 653  /*                                                                       */
 654  FT_LOCAL_DEF( FT_Error )
 655  TT_Save_Context( TT_ExecContext  exec,
 656                   TT_Size         size )
 657  {
 658    FT_Int  i;
 659
 660
 661    /* XXXX: Will probably disappear soon with all the code range */
 662    /*       management, which is now rather obsolete.            */
 663    /*                                                            */
 664    size->num_function_defs    = exec->numFDefs;
 665    size->num_instruction_defs = exec->numIDefs;
 666
 667    size->max_func = exec->maxFunc;
 668    size->max_ins  = exec->maxIns;
 669
 670    for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
 671      size->codeRangeTable[i] = exec->codeRangeTable[i];
 672
 673    return TT_Err_Ok;
 674  }
 675
 676
 677  /*************************************************************************/
 678  /*                                                                       */
 679  /* <Function>                                                            */
 680  /*    TT_Run_Context                                                     */
 681  /*                                                                       */
 682  /* <Description>                                                         */
 683  /*    Executes one or more instructions in the execution context.        */
 684  /*                                                                       */
 685  /* <Input>                                                               */
 686  /*    debug :: A Boolean flag.  If set, the function sets some internal  */
 687  /*             variables and returns immediately, otherwise TT_RunIns()  */
 688  /*             is called.                                                */
 689  /*                                                                       */
 690  /*             This is commented out currently.                          */
 691  /*                                                                       */
 692  /* <Input>                                                               */
 693  /*    exec  :: A handle to the target execution context.                 */
 694  /*                                                                       */
 695  /* <Return>                                                              */
 696  /*    TrueType error code.  0 means success.                             */
 697  /*                                                                       */
 698  /* <Note>                                                                */
 699  /*    Only the glyph loader and debugger should call this function.      */
 700  /*                                                                       */
 701  FT_LOCAL_DEF( FT_Error )
 702  TT_Run_Context( TT_ExecContext  exec,
 703                  FT_Bool         debug )
 704  {
 705    FT_Error  error;
 706
 707
 708    if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0  ) )
 709           != TT_Err_Ok )
 710      return error;
 711
 712    exec->zp0 = exec->pts;
 713    exec->zp1 = exec->pts;
 714    exec->zp2 = exec->pts;
 715
 716    exec->GS.gep0 = 1;
 717    exec->GS.gep1 = 1;
 718    exec->GS.gep2 = 1;
 719
 720    exec->GS.projVector.x = 0x4000;
 721    exec->GS.projVector.y = 0x0000;
 722
 723    exec->GS.freeVector = exec->GS.projVector;
 724    exec->GS.dualVector = exec->GS.projVector;
 725
 726#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 727    exec->GS.both_x_axis = TRUE;
 728#endif
 729
 730    exec->GS.round_state = 1;
 731    exec->GS.loop        = 1;
 732
 733    /* some glyphs leave something on the stack. so we clean it */
 734    /* before a new execution.                                  */
 735    exec->top     = 0;
 736    exec->callTop = 0;
 737
 738#if 1
 739    FT_UNUSED( debug );
 740
 741    return exec->face->interpreter( exec );
 742#else
 743    if ( !debug )
 744      return TT_RunIns( exec );
 745    else
 746      return TT_Err_Ok;
 747#endif
 748  }
 749
 750
 751  /* The default value for `scan_control' is documented as FALSE in the */
 752  /* TrueType specification.  This is confusing since it implies a      */
 753  /* Boolean value.  However, this is not the case, thus both the       */
 754  /* default values of our `scan_type' and `scan_control' fields (which */
 755  /* the documentation's `scan_control' variable is split into) are     */
 756  /* zero.                                                              */
 757
 758  const TT_GraphicsState  tt_default_graphics_state =
 759  {
 760    0, 0, 0,
 761    { 0x4000, 0 },
 762    { 0x4000, 0 },
 763    { 0x4000, 0 },
 764
 765#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 766    TRUE,
 767#endif
 768
 769    1, 64, 1,
 770    TRUE, 68, 0, 0, 9, 3,
 771    0, FALSE, 0, 1, 1, 1
 772  };
 773
 774
 775  /* documentation is in ttinterp.h */
 776
 777  FT_EXPORT_DEF( TT_ExecContext )
 778  TT_New_Context( TT_Driver  driver )
 779  {
 780    TT_ExecContext  exec;
 781    FT_Memory       memory;
 782
 783
 784    memory = driver->root.root.memory;
 785    exec   = driver->context;
 786
 787    if ( !driver->context )
 788    {
 789      FT_Error  error;
 790
 791
 792      /* allocate object */
 793      if ( FT_NEW( exec ) )
 794        goto Fail;
 795
 796      /* initialize it; in case of error this deallocates `exec' too */
 797      error = Init_Context( exec, memory );
 798      if ( error )
 799        goto Fail;
 800
 801      /* store it into the driver */
 802      driver->context = exec;
 803    }
 804
 805    return driver->context;
 806
 807  Fail:
 808    return NULL;
 809  }
 810
 811
 812  /*************************************************************************/
 813  /*                                                                       */
 814  /* Before an opcode is executed, the interpreter verifies that there are */
 815  /* enough arguments on the stack, with the help of the `Pop_Push_Count'  */
 816  /* table.                                                                */
 817  /*                                                                       */
 818  /* For each opcode, the first column gives the number of arguments that  */
 819  /* are popped from the stack; the second one gives the number of those   */
 820  /* that are pushed in result.                                            */
 821  /*                                                                       */
 822  /* Opcodes which have a varying number of parameters in the data stream  */
 823  /* (NPUSHB, NPUSHW) are handled specially; they have a negative value in */
 824  /* the `opcode_length' table, and the value in `Pop_Push_Count' is set   */
 825  /* to zero.                                                              */
 826  /*                                                                       */
 827  /*************************************************************************/
 828
 829
 830#undef  PACK
 831#define PACK( x, y )  ( ( x << 4 ) | y )
 832
 833
 834  static
 835  const FT_Byte  Pop_Push_Count[256] =
 836  {
 837    /* opcodes are gathered in groups of 16 */
 838    /* please keep the spaces as they are   */
 839
 840    /*  SVTCA  y  */  PACK( 0, 0 ),
 841    /*  SVTCA  x  */  PACK( 0, 0 ),
 842    /*  SPvTCA y  */  PACK( 0, 0 ),
 843    /*  SPvTCA x  */  PACK( 0, 0 ),
 844    /*  SFvTCA y  */  PACK( 0, 0 ),
 845    /*  SFvTCA x  */  PACK( 0, 0 ),
 846    /*  SPvTL //  */  PACK( 2, 0 ),
 847    /*  SPvTL +   */  PACK( 2, 0 ),
 848    /*  SFvTL //  */  PACK( 2, 0 ),
 849    /*  SFvTL +   */  PACK( 2, 0 ),
 850    /*  SPvFS     */  PACK( 2, 0 ),
 851    /*  SFvFS     */  PACK( 2, 0 ),
 852    /*  GPV       */  PACK( 0, 2 ),
 853    /*  GFV       */  PACK( 0, 2 ),
 854    /*  SFvTPv    */  PACK( 0, 0 ),
 855    /*  ISECT     */  PACK( 5, 0 ),
 856
 857    /*  SRP0      */  PACK( 1, 0 ),
 858    /*  SRP1      */  PACK( 1, 0 ),
 859    /*  SRP2      */  PACK( 1, 0 ),
 860    /*  SZP0      */  PACK( 1, 0 ),
 861    /*  SZP1      */  PACK( 1, 0 ),
 862    /*  SZP2      */  PACK( 1, 0 ),
 863    /*  SZPS      */  PACK( 1, 0 ),
 864    /*  SLOOP     */  PACK( 1, 0 ),
 865    /*  RTG       */  PACK( 0, 0 ),
 866    /*  RTHG      */  PACK( 0, 0 ),
 867    /*  SMD       */  PACK( 1, 0 ),
 868    /*  ELSE      */  PACK( 0, 0 ),
 869    /*  JMPR      */  PACK( 1, 0 ),
 870    /*  SCvTCi    */  PACK( 1, 0 ),
 871    /*  SSwCi     */  PACK( 1, 0 ),
 872    /*  SSW       */  PACK( 1, 0 ),
 873
 874    /*  DUP       */  PACK( 1, 2 ),
 875    /*  POP       */  PACK( 1, 0 ),
 876    /*  CLEAR     */  PACK( 0, 0 ),
 877    /*  SWAP      */  PACK( 2, 2 ),
 878    /*  DEPTH     */  PACK( 0, 1 ),
 879    /*  CINDEX    */  PACK( 1, 1 ),
 880    /*  MINDEX    */  PACK( 1, 0 ),
 881    /*  AlignPTS  */  PACK( 2, 0 ),
 882    /*  INS_$28   */  PACK( 0, 0 ),
 883    /*  UTP       */  PACK( 1, 0 ),
 884    /*  LOOPCALL  */  PACK( 2, 0 ),
 885    /*  CALL      */  PACK( 1, 0 ),
 886    /*  FDEF      */  PACK( 1, 0 ),
 887    /*  ENDF      */  PACK( 0, 0 ),
 888    /*  MDAP[0]   */  PACK( 1, 0 ),
 889    /*  MDAP[1]   */  PACK( 1, 0 ),
 890
 891    /*  IUP[0]    */  PACK( 0, 0 ),
 892    /*  IUP[1]    */  PACK( 0, 0 ),
 893    /*  SHP[0]    */  PACK( 0, 0 ),
 894    /*  SHP[1]    */  PACK( 0, 0 ),
 895    /*  SHC[0]    */  PACK( 1, 0 ),
 896    /*  SHC[1]    */  PACK( 1, 0 ),
 897    /*  SHZ[0]    */  PACK( 1, 0 ),
 898    /*  SHZ[1]    */  PACK( 1, 0 ),
 899    /*  SHPIX     */  PACK( 1, 0 ),
 900    /*  IP        */  PACK( 0, 0 ),
 901    /*  MSIRP[0]  */  PACK( 2, 0 ),
 902    /*  MSIRP[1]  */  PACK( 2, 0 ),
 903    /*  AlignRP   */  PACK( 0, 0 ),
 904    /*  RTDG      */  PACK( 0, 0 ),
 905    /*  MIAP[0]   */  PACK( 2, 0 ),
 906    /*  MIAP[1]   */  PACK( 2, 0 ),
 907
 908    /*  NPushB    */  PACK( 0, 0 ),
 909    /*  NPushW    */  PACK( 0, 0 ),
 910    /*  WS        */  PACK( 2, 0 ),
 911    /*  RS        */  PACK( 1, 1 ),
 912    /*  WCvtP     */  PACK( 2, 0 ),
 913    /*  RCvt      */  PACK( 1, 1 ),
 914    /*  GC[0]     */  PACK( 1, 1 ),
 915    /*  GC[1]     */  PACK( 1, 1 ),
 916    /*  SCFS      */  PACK( 2, 0 ),
 917    /*  MD[0]     */  PACK( 2, 1 ),
 918    /*  MD[1]     */  PACK( 2, 1 ),
 919    /*  MPPEM     */  PACK( 0, 1 ),
 920    /*  MPS       */  PACK( 0, 1 ),
 921    /*  FlipON    */  PACK( 0, 0 ),
 922    /*  FlipOFF   */  PACK( 0, 0 ),
 923    /*  DEBUG     */  PACK( 1, 0 ),
 924
 925    /*  LT        */  PACK( 2, 1 ),
 926    /*  LTEQ      */  PACK( 2, 1 ),
 927    /*  GT        */  PACK( 2, 1 ),
 928    /*  GTEQ      */  PACK( 2, 1 ),
 929    /*  EQ        */  PACK( 2, 1 ),
 930    /*  NEQ       */  PACK( 2, 1 ),
 931    /*  ODD       */  PACK( 1, 1 ),
 932    /*  EVEN      */  PACK( 1, 1 ),
 933    /*  IF        */  PACK( 1, 0 ),
 934    /*  EIF       */  PACK( 0, 0 ),
 935    /*  AND       */  PACK( 2, 1 ),
 936    /*  OR        */  PACK( 2, 1 ),
 937    /*  NOT       */  PACK( 1, 1 ),
 938    /*  DeltaP1   */  PACK( 1, 0 ),
 939    /*  SDB       */  PACK( 1, 0 ),
 940    /*  SDS       */  PACK( 1, 0 ),
 941
 942    /*  ADD       */  PACK( 2, 1 ),
 943    /*  SUB       */  PACK( 2, 1 ),
 944    /*  DIV       */  PACK( 2, 1 ),
 945    /*  MUL       */  PACK( 2, 1 ),
 946    /*  ABS       */  PACK( 1, 1 ),
 947    /*  NEG       */  PACK( 1, 1 ),
 948    /*  FLOOR     */  PACK( 1, 1 ),
 949    /*  CEILING   */  PACK( 1, 1 ),
 950    /*  ROUND[0]  */  PACK( 1, 1 ),
 951    /*  ROUND[1]  */  PACK( 1, 1 ),
 952    /*  ROUND[2]  */  PACK( 1, 1 ),
 953    /*  ROUND[3]  */  PACK( 1, 1 ),
 954    /*  NROUND[0] */  PACK( 1, 1 ),
 955    /*  NROUND[1] */  PACK( 1, 1 ),
 956    /*  NROUND[2] */  PACK( 1, 1 ),
 957    /*  NROUND[3] */  PACK( 1, 1 ),
 958
 959    /*  WCvtF     */  PACK( 2, 0 ),
 960    /*  DeltaP2   */  PACK( 1, 0 ),
 961    /*  DeltaP3   */  PACK( 1, 0 ),
 962    /*  DeltaCn[0] */ PACK( 1, 0 ),
 963    /*  DeltaCn[1] */ PACK( 1, 0 ),
 964    /*  DeltaCn[2] */ PACK( 1, 0 ),
 965    /*  SROUND    */  PACK( 1, 0 ),
 966    /*  S45Round  */  PACK( 1, 0 ),
 967    /*  JROT      */  PACK( 2, 0 ),
 968    /*  JROF      */  PACK( 2, 0 ),
 969    /*  ROFF      */  PACK( 0, 0 ),
 970    /*  INS_$7B   */  PACK( 0, 0 ),
 971    /*  RUTG      */  PACK( 0, 0 ),
 972    /*  RDTG      */  PACK( 0, 0 ),
 973    /*  SANGW     */  PACK( 1, 0 ),
 974    /*  AA        */  PACK( 1, 0 ),
 975
 976    /*  FlipPT    */  PACK( 0, 0 ),
 977    /*  FlipRgON  */  PACK( 2, 0 ),
 978    /*  FlipRgOFF */  PACK( 2, 0 ),
 979    /*  INS_$83   */  PACK( 0, 0 ),
 980    /*  INS_$84   */  PACK( 0, 0 ),
 981    /*  ScanCTRL  */  PACK( 1, 0 ),
 982    /*  SDVPTL[0] */  PACK( 2, 0 ),
 983    /*  SDVPTL[1] */  PACK( 2, 0 ),
 984    /*  GetINFO   */  PACK( 1, 1 ),
 985    /*  IDEF      */  PACK( 1, 0 ),
 986    /*  ROLL      */  PACK( 3, 3 ),
 987    /*  MAX       */  PACK( 2, 1 ),
 988    /*  MIN       */  PACK( 2, 1 ),
 989    /*  ScanTYPE  */  PACK( 1, 0 ),
 990    /*  InstCTRL  */  PACK( 2, 0 ),
 991    /*  INS_$8F   */  PACK( 0, 0 ),
 992
 993    /*  INS_$90  */   PACK( 0, 0 ),
 994    /*  INS_$91  */   PACK( 0, 0 ),
 995    /*  INS_$92  */   PACK( 0, 0 ),
 996    /*  INS_$93  */   PACK( 0, 0 ),
 997    /*  INS_$94  */   PACK( 0, 0 ),
 998    /*  INS_$95  */   PACK( 0, 0 ),
 999    /*  INS_$96  */   PACK( 0, 0 ),
1000    /*  INS_$97  */   PACK( 0, 0 ),
1001    /*  INS_$98  */   PACK( 0, 0 ),
1002    /*  INS_$99  */   PACK( 0, 0 ),
1003    /*  INS_$9A  */   PACK( 0, 0 ),
1004    /*  INS_$9B  */   PACK( 0, 0 ),
1005    /*  INS_$9C  */   PACK( 0, 0 ),
1006    /*  INS_$9D  */   PACK( 0, 0 ),
1007    /*  INS_$9E  */   PACK( 0, 0 ),
1008    /*  INS_$9F  */   PACK( 0, 0 ),
1009
1010    /*  INS_$A0  */   PACK( 0, 0 ),
1011    /*  INS_$A1  */   PACK( 0, 0 ),
1012    /*  INS_$A2  */   PACK( 0, 0 ),
1013    /*  INS_$A3  */   PACK( 0, 0 ),
1014    /*  INS_$A4  */   PACK( 0, 0 ),
1015    /*  INS_$A5  */   PACK( 0, 0 ),
1016    /*  INS_$A6  */   PACK( 0, 0 ),
1017    /*  INS_$A7  */   PACK( 0, 0 ),
1018    /*  INS_$A8  */   PACK( 0, 0 ),
1019    /*  INS_$A9  */   PACK( 0, 0 ),
1020    /*  INS_$AA  */   PACK( 0, 0 ),
1021    /*  INS_$AB  */   PACK( 0, 0 ),
1022    /*  INS_$AC  */   PACK( 0, 0 ),
1023    /*  INS_$AD  */   PACK( 0, 0 ),
1024    /*  INS_$AE  */   PACK( 0, 0 ),
1025    /*  INS_$AF  */   PACK( 0, 0 ),
1026
1027    /*  PushB[0]  */  PACK( 0, 1 ),
1028    /*  PushB[1]  */  PACK( 0, 2 ),
1029    /*  PushB[2]  */  PACK( 0, 3 ),
1030    /*  PushB[3]  */  PACK( 0, 4 ),
1031    /*  PushB[4]  */  PACK( 0, 5 ),
1032    /*  PushB[5]  */  PACK( 0, 6 ),
1033    /*  PushB[6]  */  PACK( 0, 7 ),
1034    /*  PushB[7]  */  PACK( 0, 8 ),
1035    /*  PushW[0]  */  PACK( 0, 1 ),
1036    /*  PushW[1]  */  PACK( 0, 2 ),
1037    /*  PushW[2]  */  PACK( 0, 3 ),
1038    /*  PushW[3]  */  PACK( 0, 4 ),
1039    /*  PushW[4]  */  PACK( 0, 5 ),
1040    /*  PushW[5]  */  PACK( 0, 6 ),
1041    /*  PushW[6]  */  PACK( 0, 7 ),
1042    /*  PushW[7]  */  PACK( 0, 8 ),
1043
1044    /*  MDRP[00]  */  PACK( 1, 0 ),
1045    /*  MDRP[01]  */  PACK( 1, 0 ),
1046    /*  MDRP[02]  */  PACK( 1, 0 ),
1047    /*  MDRP[03]  */  PACK( 1, 0 ),
1048    /*  MDRP[04]  */  PACK( 1, 0 ),
1049    /*  MDRP[05]  */  PACK( 1, 0 ),
1050    /*  MDRP[06]  */  PACK( 1, 0 ),
1051    /*  MDRP[07]  */  PACK( 1, 0 ),
1052    /*  MDRP[08]  */  PACK( 1, 0 ),
1053    /*  MDRP[09]  */  PACK( 1, 0 ),
1054    /*  MDRP[10]  */  PACK( 1, 0 ),
1055    /*  MDRP[11]  */  PACK( 1, 0 ),
1056    /*  MDRP[12]  */  PACK( 1, 0 ),
1057    /*  MDRP[13]  */  PACK( 1, 0 ),
1058    /*  MDRP[14]  */  PACK( 1, 0 ),
1059    /*  MDRP[15]  */  PACK( 1, 0 ),
1060
1061    /*  MDRP[16]  */  PACK( 1, 0 ),
1062    /*  MDRP[17]  */  PACK( 1, 0 ),
1063    /*  MDRP[18]  */  PACK( 1, 0 ),
1064    /*  MDRP[19]  */  PACK( 1, 0 ),
1065    /*  MDRP[20]  */  PACK( 1, 0 ),
1066    /*  MDRP[21]  */  PACK( 1, 0 ),
1067    /*  MDRP[22]  */  PACK( 1, 0 ),
1068    /*  MDRP[23]  */  PACK( 1, 0 ),
1069    /*  MDRP[24]  */  PACK( 1, 0 ),
1070    /*  MDRP[25]  */  PACK( 1, 0 ),
1071    /*  MDRP[26]  */  PACK( 1, 0 ),
1072    /*  MDRP[27]  */  PACK( 1, 0 ),
1073    /*  MDRP[28]  */  PACK( 1, 0 ),
1074    /*  MDRP[29]  */  PACK( 1, 0 ),
1075    /*  MDRP[30]  */  PACK( 1, 0 ),
1076    /*  MDRP[31]  */  PACK( 1, 0 ),
1077
1078    /*  MIRP[00]  */  PACK( 2, 0 ),
1079    /*  MIRP[01]  */  PACK( 2, 0 ),
1080    /*  MIRP[02]  */  PACK( 2, 0 ),
1081    /*  MIRP[03]  */  PACK( 2, 0 ),
1082    /*  MIRP[04]  */  PACK( 2, 0 ),
1083    /*  MIRP[05]  */  PACK( 2, 0 ),
1084    /*  MIRP[06]  */  PACK( 2, 0 ),
1085    /*  MIRP[07]  */  PACK( 2, 0 ),
1086    /*  MIRP[08]  */  PACK( 2, 0 ),
1087    /*  MIRP[09]  */  PACK( 2, 0 ),
1088    /*  MIRP[10]  */  PACK( 2, 0 ),
1089    /*  MIRP[11]  */  PACK( 2, 0 ),
1090    /*  MIRP[12]  */  PACK( 2, 0 ),
1091    /*  MIRP[13]  */  PACK( 2, 0 ),
1092    /*  MIRP[14]  */  PACK( 2, 0 ),
1093    /*  MIRP[15]  */  PACK( 2, 0 ),
1094
1095    /*  MIRP[16]  */  PACK( 2, 0 ),
1096    /*  MIRP[17]  */  PACK( 2, 0 ),
1097    /*  MIRP[18]  */  PACK( 2, 0 ),
1098    /*  MIRP[19]  */  PACK( 2, 0 ),
1099    /*  MIRP[20]  */  PACK( 2, 0 ),
1100    /*  MIRP[21]  */  PACK( 2, 0 ),
1101    /*  MIRP[22]  */  PACK( 2, 0 ),
1102    /*  MIRP[23]  */  PACK( 2, 0 ),
1103    /*  MIRP[24]  */  PACK( 2, 0 ),
1104    /*  MIRP[25]  */  PACK( 2, 0 ),
1105    /*  MIRP[26]  */  PACK( 2, 0 ),
1106    /*  MIRP[27]  */  PACK( 2, 0 ),
1107    /*  MIRP[28]  */  PACK( 2, 0 ),
1108    /*  MIRP[29]  */  PACK( 2, 0 ),
1109    /*  MIRP[30]  */  PACK( 2, 0 ),
1110    /*  MIRP[31]  */  PACK( 2, 0 )
1111  };
1112
1113
1114  static
1115  const FT_Char  opcode_length[256] =
1116  {
1117    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1118    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1119    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1120    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1121
1122   -1,-2, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1123    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1124    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1125    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1126
1127    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1128    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1129    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1130    2, 3, 4, 5,  6, 7, 8, 9,  3, 5, 7, 9, 11,13,15,17,
1131
1132    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1133    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1134    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1135    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1
1136  };
1137
1138#undef PACK
1139
1140#if 1
1141
1142  static FT_Int32
1143  TT_MulFix14( FT_Int32  a,
1144               FT_Int    b )
1145  {
1146    FT_Int32   sign;
1147    FT_UInt32  ah, al, mid, lo, hi;
1148
1149
1150    sign = a ^ b;
1151
1152    if ( a < 0 )
1153      a = -a;
1154    if ( b < 0 )
1155      b = -b;
1156
1157    ah = (FT_UInt32)( ( a >> 16 ) & 0xFFFFU );
1158    al = (FT_UInt32)( a & 0xFFFFU );
1159
1160    lo    = al * b;
1161    mid   = ah * b;
1162    hi    = mid >> 16;
1163    mid   = ( mid << 16 ) + ( 1 << 13 ); /* rounding */
1164    lo   += mid;
1165    if ( lo < mid )
1166      hi += 1;
1167
1168    mid = ( lo >> 14 ) | ( hi << 18 );
1169
1170    return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid;
1171  }
1172
1173#else
1174
1175  /* compute (a*b)/2^14 with maximal accuracy and rounding */
1176  static FT_Int32
1177  TT_MulFix14( FT_Int32  a,
1178               FT_Int    b )
1179  {
1180    FT_Int32   m, s, hi;
1181    FT_UInt32  l, lo;
1182
1183
1184    /* compute ax*bx as 64-bit value */
1185    l  = (FT_UInt32)( ( a & 0xFFFFU ) * b );
1186    m  = ( a >> 16 ) * b;
1187
1188    lo = l + (FT_UInt32)( m << 16 );
1189    hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l );
1190
1191    /* divide the result by 2^14 with rounding */
1192    s   = hi >> 31;
1193    l   = lo + (FT_UInt32)s;
1194    hi += s + ( l < lo );
1195    lo  = l;
1196
1197    l   = lo + 0x2000U;
1198    hi += l < lo;
1199
1200    return ( hi << 18 ) | ( l >> 14 );
1201  }
1202#endif
1203
1204
1205  /* compute (ax*bx+ay*by)/2^14 with maximal accuracy and rounding */
1206  static FT_Int32
1207  TT_DotFix14( FT_Int32  ax,
1208               FT_Int32  ay,
1209               FT_Int    bx,
1210               FT_Int    by )
1211  {
1212    FT_Int32   m, s, hi1, hi2, hi;
1213    FT_UInt32  l, lo1, lo2, lo;
1214
1215
1216    /* compute ax*bx as 64-bit value */
1217    l = (FT_UInt32)( ( ax & 0xFFFFU ) * bx );
1218    m = ( ax >> 16 ) * bx;
1219
1220    lo1 = l + (FT_UInt32)( m << 16 );
1221    hi1 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo1 < l );
1222
1223    /* compute ay*by as 64-bit value */
1224    l = (FT_UInt32)( ( ay & 0xFFFFU ) * by );
1225    m = ( ay >> 16 ) * by;
1226
1227    lo2 = l + (FT_UInt32)( m << 16 );
1228    hi2 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo2 < l );
1229
1230    /* add them */
1231    lo = lo1 + lo2;
1232    hi = hi1 + hi2 + ( lo < lo1 );
1233
1234    /* divide the result by 2^14 with rounding */
1235    s   = hi >> 31;
1236    l   = lo + (FT_UInt32)s;
1237    hi += s + ( l < lo );
1238    lo  = l;
1239
1240    l   = lo + 0x2000U;
1241    hi += ( l < lo );
1242
1243    return ( hi << 18 ) | ( l >> 14 );
1244  }
1245
1246
1247  /* return length of given vector */
1248
1249#if 0
1250
1251  static FT_Int32
1252  TT_VecLen( FT_Int32  x,
1253             FT_Int32  y )
1254  {
1255    FT_Int32   m, hi1, hi2, hi;
1256    FT_UInt32  l, lo1, lo2, lo;
1257
1258
1259    /* compute x*x as 64-bit value */
1260    lo = (FT_UInt32)( x & 0xFFFFU );
1261    hi = x >> 16;
1262
1263    l  = lo * lo;
1264    m  = hi * lo;
1265    hi = hi * hi;
1266
1267    lo1 = l + (FT_UInt32)( m << 17 );
1268    hi1 = hi + ( m >> 15 ) + ( lo1 < l );
1269
1270    /* compute y*y as 64-bit value */
1271    lo = (FT_UInt32)( y & 0xFFFFU );
1272    hi = y >> 16;
1273
1274    l  = lo * lo;
1275    m  = hi * lo;
1276    hi = hi * hi;
1277
1278    lo2 = l + (FT_UInt32)( m << 17 );
1279    hi2 = hi + ( m >> 15 ) + ( lo2 < l );
1280
1281    /* add them to get 'x*x+y*y' as 64-bit value */
1282    lo = lo1 + lo2;
1283    hi = hi1 + hi2 + ( lo < lo1 );
1284
1285    /* compute the square root of this value */
1286    {
1287      FT_UInt32  root, rem, test_div;
1288      FT_Int     count;
1289
1290
1291      root = 0;
1292
1293      {
1294        rem   = 0;
1295        count = 32;
1296        do
1297        {
1298          rem      = ( rem << 2 ) | ( (FT_UInt32)hi >> 30 );
1299          hi       = (  hi << 2 ) | (            lo >> 30 );
1300          lo     <<= 2;
1301          root   <<= 1;
1302          test_div = ( root

Large files files are truncated, but you can click here to view the full file