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