Home | History | Annotate | Download | only in cff
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  cf2stack.c                                                             */
      4 /*                                                                         */
      5 /*    Adobe's code for emulating a CFF stack (body).                       */
      6 /*                                                                         */
      7 /*  Copyright 2007-2013 Adobe Systems Incorporated.                        */
      8 /*                                                                         */
      9 /*  This software, and all works of authorship, whether in source or       */
     10 /*  object code form as indicated by the copyright notice(s) included      */
     11 /*  herein (collectively, the "Work") is made available, and may only be   */
     12 /*  used, modified, and distributed under the FreeType Project License,    */
     13 /*  LICENSE.TXT.  Additionally, subject to the terms and conditions of the */
     14 /*  FreeType Project License, each contributor to the Work hereby grants   */
     15 /*  to any individual or legal entity exercising permissions granted by    */
     16 /*  the FreeType Project License and this section (hereafter, "You" or     */
     17 /*  "Your") a perpetual, worldwide, non-exclusive, no-charge,              */
     18 /*  royalty-free, irrevocable (except as stated in this section) patent    */
     19 /*  license to make, have made, use, offer to sell, sell, import, and      */
     20 /*  otherwise transfer the Work, where such license applies only to those  */
     21 /*  patent claims licensable by such contributor that are necessarily      */
     22 /*  infringed by their contribution(s) alone or by combination of their    */
     23 /*  contribution(s) with the Work to which such contribution(s) was        */
     24 /*  submitted.  If You institute patent litigation against any entity      */
     25 /*  (including a cross-claim or counterclaim in a lawsuit) alleging that   */
     26 /*  the Work or a contribution incorporated within the Work constitutes    */
     27 /*  direct or contributory patent infringement, then any patent licenses   */
     28 /*  granted to You under this License for that Work shall terminate as of  */
     29 /*  the date such litigation is filed.                                     */
     30 /*                                                                         */
     31 /*  By using, modifying, or distributing the Work you indicate that you    */
     32 /*  have read and understood the terms and conditions of the               */
     33 /*  FreeType Project License as well as those provided in this section,    */
     34 /*  and you accept them fully.                                             */
     35 /*                                                                         */
     36 /***************************************************************************/
     37 
     38 
     39 #include "cf2ft.h"
     40 #include FT_INTERNAL_DEBUG_H
     41 
     42 #include "cf2glue.h"
     43 #include "cf2font.h"
     44 #include "cf2stack.h"
     45 
     46 #include "cf2error.h"
     47 
     48 
     49   /* Allocate and initialize an instance of CF2_Stack.       */
     50   /* Note: This function returns NULL on error (does not set */
     51   /* `error').                                               */
     52   FT_LOCAL_DEF( CF2_Stack )
     53   cf2_stack_init( FT_Memory  memory,
     54                   FT_Error*  e )
     55   {
     56     FT_Error  error = FT_Err_Ok;     /* for FT_QNEW */
     57 
     58     CF2_Stack  stack = NULL;
     59 
     60 
     61     if ( !FT_QNEW( stack ) )
     62     {
     63       /* initialize the structure; FT_QNEW zeroes it */
     64       stack->memory = memory;
     65       stack->error  = e;
     66       stack->top    = &stack->buffer[0]; /* empty stack */
     67     }
     68 
     69     return stack;
     70   }
     71 
     72 
     73   FT_LOCAL_DEF( void )
     74   cf2_stack_free( CF2_Stack  stack )
     75   {
     76     if ( stack )
     77     {
     78       FT_Memory  memory = stack->memory;
     79 
     80 
     81       /* free the main structure */
     82       FT_FREE( stack );
     83     }
     84   }
     85 
     86 
     87   FT_LOCAL_DEF( CF2_UInt )
     88   cf2_stack_count( CF2_Stack  stack )
     89   {
     90     return (CF2_UInt)( stack->top - &stack->buffer[0] );
     91   }
     92 
     93 
     94   FT_LOCAL_DEF( void )
     95   cf2_stack_pushInt( CF2_Stack  stack,
     96                      CF2_Int    val )
     97   {
     98     if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] )
     99     {
    100       CF2_SET_ERROR( stack->error, Stack_Overflow );
    101       return;     /* stack overflow */
    102     }
    103 
    104     stack->top->u.i  = val;
    105     stack->top->type = CF2_NumberInt;
    106     ++stack->top;
    107   }
    108 
    109 
    110   FT_LOCAL_DEF( void )
    111   cf2_stack_pushFixed( CF2_Stack  stack,
    112                        CF2_Fixed  val )
    113   {
    114     if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] )
    115     {
    116       CF2_SET_ERROR( stack->error, Stack_Overflow );
    117       return;     /* stack overflow */
    118     }
    119 
    120     stack->top->u.r  = val;
    121     stack->top->type = CF2_NumberFixed;
    122     ++stack->top;
    123   }
    124 
    125 
    126   /* this function is only allowed to pop an integer type */
    127   FT_LOCAL_DEF( CF2_Int )
    128   cf2_stack_popInt( CF2_Stack  stack )
    129   {
    130     if ( stack->top == &stack->buffer[0] )
    131     {
    132       CF2_SET_ERROR( stack->error, Stack_Underflow );
    133       return 0;   /* underflow */
    134     }
    135     if ( stack->top[-1].type != CF2_NumberInt )
    136     {
    137       CF2_SET_ERROR( stack->error, Syntax_Error );
    138       return 0;   /* type mismatch */
    139     }
    140 
    141     --stack->top;
    142 
    143     return stack->top->u.i;
    144   }
    145 
    146 
    147   /* Note: type mismatch is silently cast */
    148   /* TODO: check this */
    149   FT_LOCAL_DEF( CF2_Fixed )
    150   cf2_stack_popFixed( CF2_Stack  stack )
    151   {
    152     if ( stack->top == &stack->buffer[0] )
    153     {
    154       CF2_SET_ERROR( stack->error, Stack_Underflow );
    155       return cf2_intToFixed( 0 );    /* underflow */
    156     }
    157 
    158     --stack->top;
    159 
    160     switch ( stack->top->type )
    161     {
    162     case CF2_NumberInt:
    163       return cf2_intToFixed( stack->top->u.i );
    164     case CF2_NumberFrac:
    165       return cf2_fracToFixed( stack->top->u.f );
    166     default:
    167       return stack->top->u.r;
    168     }
    169   }
    170 
    171 
    172   /* Note: type mismatch is silently cast */
    173   /* TODO: check this */
    174   FT_LOCAL_DEF( CF2_Fixed )
    175   cf2_stack_getReal( CF2_Stack  stack,
    176                      CF2_UInt   idx )
    177   {
    178     FT_ASSERT( cf2_stack_count( stack ) <= CF2_OPERAND_STACK_SIZE );
    179 
    180     if ( idx >= cf2_stack_count( stack ) )
    181     {
    182       CF2_SET_ERROR( stack->error, Stack_Overflow );
    183       return cf2_intToFixed( 0 );    /* bounds error */
    184     }
    185 
    186     switch ( stack->buffer[idx].type )
    187     {
    188     case CF2_NumberInt:
    189       return cf2_intToFixed( stack->buffer[idx].u.i );
    190     case CF2_NumberFrac:
    191       return cf2_fracToFixed( stack->buffer[idx].u.f );
    192     default:
    193       return stack->buffer[idx].u.r;
    194     }
    195   }
    196 
    197 
    198   FT_LOCAL_DEF( void )
    199   cf2_stack_clear( CF2_Stack  stack )
    200   {
    201     stack->top = &stack->buffer[0];
    202   }
    203 
    204 
    205 /* END */
    206