1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* psobjs.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Auxiliary functions for PostScript fonts (body). */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Copyright 1996-2013 by */ 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This file is part of the FreeType project, and may only be used, */ 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* modified, and distributed under the terms of the FreeType project */ 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* this file you indicate that you have read the license and */ 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* understand and accept it fully. */ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/ft2build.h" 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/psaux.h" 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftdebug.h" 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftcalc.h" 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "psobjs.h" 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "psconv.h" 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "psauxerr.h" 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* messages during execution. */ 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_psobjs 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** PS_TABLE *****/ 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ps_table_new */ 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Initializes a PS_Table. */ 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <InOut> */ 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* table :: The address of the target table. */ 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* count :: The table size = the maximum number of elements. */ 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* memory :: The memory object to use for all subsequent */ 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* reallocations. */ 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FreeType error code. 0 means success. */ 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_table_new( PS_Table table, 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int count, 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory ) 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->memory = memory; 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_NEW_ARRAY( table->elements, count ) || 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_NEW_ARRAY( table->lengths, count ) ) 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->max_elems = count; 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->init = 0xDEADBEEFUL; 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->num_elems = 0; 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->block = 0; 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->capacity = 0; 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->cursor = 0; 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(PS_Table_FuncsRec*)&table->funcs = ps_table_funcs; 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( table->elements ); 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov shift_elements( PS_Table table, 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* old_base ) 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_PtrDist delta = table->block - old_base; 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte** offset = table->elements; 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte** limit = offset + table->max_elems; 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; offset < limit; offset++ ) 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( offset[0] ) 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset[0] += delta; 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov reallocate_t1_table( PS_Table table, 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Offset new_size ) 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = table->memory; 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* old_base = table->block; 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* allocate new base block */ 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ALLOC( table->block, new_size ) ) 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->block = old_base; 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* copy elements and shift offsets */ 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( old_base ) 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_COPY( table->block, old_base, table->capacity ); 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov shift_elements( table, old_base ); 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( old_base ); 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->capacity = new_size; 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ps_table_add */ 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Adds an object to a PS_Table, possibly growing its memory block. */ 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <InOut> */ 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* table :: The target table. */ 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* idx :: The index of the object in the table. */ 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* object :: The address of the object to copy in memory. */ 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* length :: The length in bytes of the source object. */ 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FreeType error code. 0 means success. An error is returned if a */ 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* reallocation fails. */ 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_table_add( PS_Table table, 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int idx, 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* object, 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_PtrDist length ) 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( idx < 0 || idx >= table->max_elems ) 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "ps_table_add: invalid index\n" )); 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( length < 0 ) 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "ps_table_add: invalid length\n" )); 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* grow the base block if needed */ 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table->cursor + length > table->capacity ) 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Offset new_size = table->capacity; 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_PtrDist in_offset; 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov in_offset = (FT_Byte*)object - table->block; 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( in_offset < 0 || (FT_Offset)in_offset >= table->capacity ) 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov in_offset = -1; 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( new_size < table->cursor + length ) 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* increase size by 25% and round up to the nearest multiple 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov of 1024 */ 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov new_size += ( new_size >> 2 ) + 1; 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov new_size = FT_PAD_CEIL( new_size, 1024 ); 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = reallocate_t1_table( table, new_size ); 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( in_offset >= 0 ) 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov object = table->block + in_offset; 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* add the object to the base block and adjust offset */ 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->elements[idx] = table->block + table->cursor; 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->lengths [idx] = length; 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_COPY( table->block + table->cursor, object, length ); 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->cursor += length; 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ps_table_done */ 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Finalizes a PS_TableRec (i.e., reallocate it to its current */ 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* cursor). */ 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <InOut> */ 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* table :: The target table. */ 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Note> */ 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This function does NOT release the heap's memory block. It is up */ 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* to the caller to clean it, or reference it in its own structures. */ 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_table_done( PS_Table table ) 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = table->memory; 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* old_base = table->block; 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* should never fail, because rec.cursor <= rec.size */ 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !old_base ) 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ALLOC( table->block, table->cursor ) ) 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_COPY( table->block, old_base, table->cursor ); 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov shift_elements( table, old_base ); 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->capacity = table->cursor; 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( old_base ); 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( error ); 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_table_release( PS_Table table ) 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = table->memory; 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( (FT_ULong)table->init == 0xDEADBEEFUL ) 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( table->block ); 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( table->elements ); 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( table->lengths ); 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->init = 0; 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** T1 PARSER *****/ 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first character must be already part of the comment */ 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov skip_comment( FT_Byte* *acur, 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit ) 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* cur = *acur; 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( cur < limit ) 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( IS_PS_NEWLINE( *cur ) ) 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *acur = cur; 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov skip_spaces( FT_Byte* *acur, 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit ) 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* cur = *acur; 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( cur < limit ) 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !IS_PS_SPACE( *cur ) ) 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *cur == '%' ) 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* According to the PLRM, a comment is equal to a space. */ 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov skip_comment( &cur, limit ); 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *acur = cur; 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define IS_OCTAL_DIGIT( c ) ( '0' <= (c) && (c) <= '7' ) 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first character must be `('; */ 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* *acur is positioned at the character after the closing `)' */ 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov skip_literal_string( FT_Byte* *acur, 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit ) 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* cur = *acur; 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int embed = 0; 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_ERR( Invalid_File_Format ); 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned int i; 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( cur < limit ) 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte c = *cur; 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++cur; 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( c == '\\' ) 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Red Book 3rd ed., section `Literal Text Strings', p. 29: */ 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* A backslash can introduce three different types */ 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* of escape sequences: */ 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - a special escaped char like \r, \n, etc. */ 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - a one-, two-, or three-digit octal number */ 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - none of the above in which case the backslash is ignored */ 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur == limit ) 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* error (or to be ignored?) */ 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( *cur ) 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* skip `special' escape */ 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 'n': 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 'r': 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 't': 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 'b': 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 'f': 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case '\\': 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case '(': 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ')': 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++cur; 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* skip octal escape or ignore backslash */ 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < 3 && cur < limit; ++i ) 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !IS_OCTAL_DIGIT( *cur ) ) 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++cur; 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( c == '(' ) 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov embed++; 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( c == ')' ) 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov embed--; 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( embed == 0 ) 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *acur = cur; 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first character must be `<' */ 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov skip_string( FT_Byte* *acur, 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit ) 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* cur = *acur; 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error err = FT_Err_Ok; 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( ++cur < limit ) 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* All whitespace characters are ignored. */ 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov skip_spaces( &cur, limit ); 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur >= limit ) 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !IS_PS_XDIGIT( *cur ) ) 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur < limit && *cur != '>' ) 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "skip_string: missing closing delimiter `>'\n" )); 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov err = FT_THROW( Invalid_File_Format ); 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *acur = cur; 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return err; 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first character must be the opening brace that */ 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* starts the procedure */ 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NB: [ and ] need not match: */ 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `/foo {[} def' is a valid PostScript fragment, */ 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* even within a Type1 font */ 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov skip_procedure( FT_Byte* *acur, 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit ) 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* cur; 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int embed = 0; 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( **acur == '{' ); 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( cur = *acur; cur < limit && error == FT_Err_Ok; ++cur ) 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( *cur ) 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case '{': 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++embed; 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case '}': 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov --embed; 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( embed == 0 ) 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++cur; 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto end; 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case '(': 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = skip_literal_string( &cur, limit ); 483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case '<': 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = skip_string( &cur, limit ); 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case '%': 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov skip_comment( &cur, limit ); 491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end: 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( embed != 0 ) 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *acur = cur; 500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***********************************************************************/ 506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* All exported parsing routines handle leading whitespace and stop at */ 508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the first character which isn't part of the just handled token. */ 509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***********************************************************************/ 511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_skip_PS_token( PS_Parser parser ) 515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Note: PostScript allows any non-delimiting, non-whitespace */ 517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* character in a name (PS Ref Manual, 3rd ed, p31). */ 518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* PostScript delimiters are (, ), <, >, [, ], {, }, /, and %. */ 519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* cur = parser->cursor; 521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit = parser->limit; 522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov skip_spaces( &cur, limit ); /* this also skips comments */ 526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur >= limit ) 527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* self-delimiting, single-character tokens */ 530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *cur == '[' || *cur == ']' ) 531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* skip balanced expressions (procedures and strings) */ 537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *cur == '{' ) /* {...} */ 539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = skip_procedure( &cur, limit ); 541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *cur == '(' ) /* (...) */ 545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = skip_literal_string( &cur, limit ); 547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *cur == '<' ) /* <...> */ 551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur + 1 < limit && *(cur + 1) == '<' ) /* << */ 553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = skip_string( &cur, limit ); 559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *cur == '>' ) 564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur >= limit || *cur != '>' ) /* >> */ 567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "ps_parser_skip_PS_token:" 569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " unexpected closing delimiter `>'\n" )); 570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *cur == '/' ) 578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* anything else */ 581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( cur < limit ) 582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* *cur might be invalid (e.g., ')' or '}'), but this */ 584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* is handled by the test `cur == parser->cursor' below */ 585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( IS_PS_DELIM( *cur ) ) 586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur < limit && cur == parser->cursor ) 593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "ps_parser_skip_PS_token:" 595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " current token is `%c' which is self-delimiting\n" 596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " " 597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " but invalid at this point\n", 598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *cur )); 599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->error = error; 604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->cursor = cur; 605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_skip_spaces( PS_Parser parser ) 610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov skip_spaces( &parser->cursor, parser->limit ); 612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `token' here means either something between balanced delimiters */ 616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* or the next token; the delimiters are not removed. */ 617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_to_token( PS_Parser parser, 620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Token token ) 621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* cur; 623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit; 624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int embed; 625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->type = T1_TOKEN_TYPE_NONE; 628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->start = 0; 629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->limit = 0; 630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first of all, skip leading whitespace */ 632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_skip_spaces( parser ); 633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = parser->cursor; 635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit = parser->limit; 636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur >= limit ) 638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( *cur ) 641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /************* check for literal string *****************/ 643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case '(': 644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->type = T1_TOKEN_TYPE_STRING; 645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->start = cur; 646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( skip_literal_string( &cur, limit ) == FT_Err_Ok ) 648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->limit = cur; 649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /************* check for programs/array *****************/ 652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case '{': 653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->type = T1_TOKEN_TYPE_ARRAY; 654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->start = cur; 655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( skip_procedure( &cur, limit ) == FT_Err_Ok ) 657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->limit = cur; 658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /************* check for table/array ********************/ 661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* XXX: in theory we should also look for "<<" */ 662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* since this is semantically equivalent to "["; */ 663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* in practice it doesn't matter (?) */ 664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case '[': 665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->type = T1_TOKEN_TYPE_ARRAY; 666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov embed = 1; 667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->start = cur++; 668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we need this to catch `[ ]' */ 670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->cursor = cur; 671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_skip_spaces( parser ); 672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = parser->cursor; 673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( cur < limit && !parser->error ) 675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* XXX: this is wrong because it does not */ 677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* skip comments, procedures, and strings */ 678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *cur == '[' ) 679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov embed++; 680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( *cur == ']' ) 681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov embed--; 683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( embed <= 0 ) 684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->limit = ++cur; 686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->cursor = cur; 691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_skip_PS_token( parser ); 692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we need this to catch `[XXX ]' */ 693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_skip_spaces ( parser ); 694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = parser->cursor; 695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ************ otherwise, it is any token **************/ 699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->start = cur; 701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->type = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY ); 702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_skip_PS_token( parser ); 703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = parser->cursor; 704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !parser->error ) 705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->limit = cur; 706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !token->limit ) 709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->start = 0; 711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token->type = T1_TOKEN_TYPE_NONE; 712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->cursor = cur; 715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NB: `tokens' can be NULL if we only want to count */ 719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the number of array elements */ 720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_to_token_array( PS_Parser parser, 723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Token tokens, 724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt max_tokens, 725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int* pnum_tokens ) 726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_TokenRec master; 728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pnum_tokens = -1; 731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this also handles leading whitespace */ 733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_to_token( parser, &master ); 734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( master.type == T1_TOKEN_TYPE_ARRAY ) 736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* old_cursor = parser->cursor; 738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* old_limit = parser->limit; 739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Token cur = tokens; 740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Token limit = cur + max_tokens; 741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* don't include outermost delimiters */ 744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->cursor = master.start + 1; 745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->limit = master.limit - 1; 746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( parser->cursor < parser->limit ) 748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_TokenRec token; 750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_to_token( parser, &token ); 753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !token.type ) 754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tokens != NULL && cur < limit ) 757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *cur = token; 758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pnum_tokens = (FT_Int)( cur - tokens ); 763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->cursor = old_cursor; 765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->limit = old_limit; 766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first character must be a delimiter or a part of a number */ 771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NB: `coords' can be NULL if we just want to skip the */ 772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* array; in this case we ignore `max_coords' */ 773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Int 775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_tocoordarray( FT_Byte* *acur, 776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit, 777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int max_coords, 778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Short* coords ) 779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* cur = *acur; 781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int count = 0; 782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte c, ender; 783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur >= limit ) 786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check for the beginning of an array; otherwise, only one number */ 789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* will be read */ 790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c = *cur; 791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ender = 0; 792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( c == '[' ) 794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ender = ']'; 795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( c == '{' ) 796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ender = '}'; 797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ender ) 799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now, read the coordinates */ 802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( cur < limit ) 803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Short dummy; 805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* old_cur; 806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* skip whitespace in front of data */ 809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov skip_spaces( &cur, limit ); 810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur >= limit ) 811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *cur == ender ) 814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old_cur = cur; 820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( coords != NULL && count >= max_coords ) 822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* call PS_Conv_ToFixed() even if coords == NULL */ 825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* to properly parse number at `cur' */ 826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *( coords != NULL ? &coords[count] : &dummy ) = 827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 ); 828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( old_cur == cur ) 830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = -1; 832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count++; 836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !ender ) 838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *acur = cur; 843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return count; 844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first character must be a delimiter or a part of a number */ 848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NB: `values' can be NULL if we just want to skip the */ 849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* array; in this case we ignore `max_values' */ 850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Int 852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_tofixedarray( FT_Byte* *acur, 853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit, 854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int max_values, 855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed* values, 856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int power_ten ) 857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* cur = *acur; 859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int count = 0; 860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte c, ender; 861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur >= limit ) 864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Check for the beginning of an array. Otherwise, only one number */ 867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* will be read. */ 868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c = *cur; 869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ender = 0; 870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( c == '[' ) 872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ender = ']'; 873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( c == '{' ) 874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ender = '}'; 875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ender ) 877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now, read the values */ 880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( cur < limit ) 881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed dummy; 883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* old_cur; 884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* skip whitespace in front of data */ 887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov skip_spaces( &cur, limit ); 888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur >= limit ) 889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *cur == ender ) 892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old_cur = cur; 898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( values != NULL && count >= max_values ) 900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* call PS_Conv_ToFixed() even if coords == NULL */ 903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* to properly parse number at `cur' */ 904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *( values != NULL ? &values[count] : &dummy ) = 905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PS_Conv_ToFixed( &cur, limit, power_ten ); 906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( old_cur == cur ) 908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = -1; 910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count++; 914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !ender ) 916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *acur = cur; 921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return count; 922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if 0 926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_String* 928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_tostring( FT_Byte** cursor, 929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit, 930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory ) 931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* cur = *cursor; 933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_PtrDist len = 0; 934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int count; 935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_String* result; 936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* XXX: some stupid fonts have a `Notice' or `Copyright' string */ 940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* that simply doesn't begin with an opening parenthesis, even */ 941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* though they have a closing one! E.g. "amuncial.pfb" */ 942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We must deal with these ill-fated cases there. Note that */ 944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* these fonts didn't work with the old Type 1 driver as the */ 945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* notice/copyright was not recognized as a valid string token */ 946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* and made the old token parser commit errors. */ 947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) ) 949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur + 1 >= limit ) 951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *cur == '(' ) 954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; /* skip the opening parenthesis, if there is one */ 955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *cursor = cur; 957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = 0; 958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* then, count its length */ 960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; cur < limit; cur++ ) 961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *cur == '(' ) 963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count++; 964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( *cur == ')' ) 966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count--; 968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( count < 0 ) 969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov len = cur - *cursor; 974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur >= limit || FT_ALLOC( result, len + 1 ) ) 975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now copy the string */ 978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_COPY( result, *cursor, len ); 979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result[len] = '\0'; 980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *cursor = cur; 981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* 0 */ 985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static int 988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_tobool( FT_Byte* *acur, 989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit ) 990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* cur = *acur; 992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool result = 0; 993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* return 1 if we find `true', 0 otherwise */ 996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur + 3 < limit && 997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur[0] == 't' && 998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur[1] == 'r' && 999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur[2] == 'u' && 1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur[3] == 'e' ) 1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = 1; 1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur += 5; 1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( cur + 4 < limit && 1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur[0] == 'f' && 1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur[1] == 'a' && 1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur[2] == 'l' && 1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur[3] == 's' && 1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur[4] == 'e' ) 1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = 0; 1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur += 6; 1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *acur = cur; 1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* load a simple field (i.e. non-table) into the current list of objects */ 1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_load_field( PS_Parser parser, 1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const T1_Field field, 1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void** objects, 1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt max_objects, 1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong* pflags ) 1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_TokenRec token; 1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* cur; 1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit; 1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt count; 1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt idx; 1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_FieldType type; 1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this also skips leading whitespace */ 1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_to_token( parser, &token ); 1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !token.type ) 1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = 1; 1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov idx = 0; 1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = token.start; 1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit = token.limit; 1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov type = field->type; 1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we must detect arrays in /FontBBox */ 1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( type == T1_FIELD_TYPE_BBOX ) 1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_TokenRec token2; 1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* old_cur = parser->cursor; 1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* old_limit = parser->limit; 1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* don't include delimiters */ 1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->cursor = token.start + 1; 1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->limit = token.limit - 1; 1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_to_token( parser, &token2 ); 1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->cursor = old_cur; 1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->limit = old_limit; 1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( token2.type == T1_TOKEN_TYPE_ARRAY ) 1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov type = T1_FIELD_TYPE_MM_BBOX; 1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto FieldArray; 1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( token.type == T1_TOKEN_TYPE_ARRAY ) 1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = max_objects; 1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FieldArray: 1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if this is an array and we have no blend, an error occurs */ 1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( max_objects == 0 ) 1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov idx = 1; 1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* don't include delimiters */ 1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit--; 1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; count > 0; count--, idx++ ) 1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* q = (FT_Byte*)objects[idx] + field->offset; 1092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long val; 1093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_String* string; 1094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov skip_spaces( &cur, limit ); 1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( type ) 1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case T1_FIELD_TYPE_BOOL: 1101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = ps_tobool( &cur, limit ); 1102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Store_Integer; 1103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case T1_FIELD_TYPE_FIXED: 1105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = PS_Conv_ToFixed( &cur, limit, 0 ); 1106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Store_Integer; 1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case T1_FIELD_TYPE_FIXED_1000: 1109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = PS_Conv_ToFixed( &cur, limit, 3 ); 1110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Store_Integer; 1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case T1_FIELD_TYPE_INTEGER: 1113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { FT_Bool ret = xyq_PS_Conv_ToInt( &cur, limit, &val ); /* XYQ 2007-10-10: abort if not a number*/ 1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ret) break; } 1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* fall through */ 1116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Store_Integer: 1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( field->size ) 1119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case (8 / FT_CHAR_BIT): 1121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_Byte*)q = (FT_Byte)val; 1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case (16 / FT_CHAR_BIT): 1125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_UShort*)q = (FT_UShort)val; 1126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case (32 / FT_CHAR_BIT): 1129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_UInt32*)q = (FT_UInt32)val; 1130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: /* for 64-bit systems */ 1133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_Long*)q = val; 1134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case T1_FIELD_TYPE_STRING: 1138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case T1_FIELD_TYPE_KEY: 1139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = parser->memory; 1141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt len = (FT_UInt)( limit - cur ); 1142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur >= limit ) 1145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we allow both a string or a name */ 1148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* for cases like /FontName (foo) def */ 1149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( token.type == T1_TOKEN_TYPE_KEY ) 1150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* don't include leading `/' */ 1152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov len--; 1153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 1154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( token.type == T1_TOKEN_TYPE_STRING ) 1156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* don't include delimiting parentheses */ 1158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* XXX we don't handle <<...>> here */ 1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* XXX should we convert octal escapes? */ 1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if so, what encoding should we use? */ 1161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov len -= 2; 1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "ps_parser_load_field:" 1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " expected a name or string\n" 1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " " 1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " but found token of type %d instead\n", 1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token.type )); 1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* for this to work (FT_String**)q must have been */ 1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* initialized to NULL */ 1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *(FT_String**)q != NULL ) 1178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n", 1180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov field->ident )); 1181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( *(FT_String**)q ); 1182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_String**)q = NULL; 1183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ALLOC( string, len + 1 ) ) 1186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_COPY( string, cur, len ); 1189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov string[len] = 0; 1190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_String**)q = string; 1192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case T1_FIELD_TYPE_BBOX: 1196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Add by Johnson, fix a Error #1: UNINITIALIZED READ. #testdoc 1282.pdf 1198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed temp[4] = {0,0,0,0}; 1199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BBox* bbox = (FT_BBox*)q; 1200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int result; 1201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = ps_tofixedarray( &cur, limit, 4, temp, 0 ); 1204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( result < 0 ) 1206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "ps_parser_load_field:" 1208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " expected four integers in bounding box\n" )); 1209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 1210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bbox->xMin = FT_RoundFix( temp[0] ); 1214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bbox->yMin = FT_RoundFix( temp[1] ); 1215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bbox->xMax = FT_RoundFix( temp[2] ); 1216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bbox->yMax = FT_RoundFix( temp[3] ); 1217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case T1_FIELD_TYPE_MM_BBOX: 1221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = parser->memory; 1223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed* temp; 1224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int result; 1225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt i; 1226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_NEW_ARRAY( temp, max_objects * 4 ) ) 1229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < 4; i++ ) 1232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = ps_tofixedarray( &cur, limit, max_objects, 1234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov temp + i * max_objects, 0 ); 1235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( result < 0 ) 1236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "ps_parser_load_field:" 1238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " expected %d integers in the %s subarray\n" 1239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " " 1240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " of /FontBBox in the /Blend dictionary\n", 1241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max_objects, 1242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i == 0 ? "first" 1243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov : ( i == 1 ? "second" 1244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov : ( i == 2 ? "third" 1245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov : "fourth" ) ) )); 1246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 1247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov skip_spaces( &cur, limit ); 1251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < max_objects; i++ ) 1254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BBox* bbox = (FT_BBox*)objects[i]; 1256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bbox->xMin = FT_RoundFix( temp[i ] ); 1259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bbox->yMin = FT_RoundFix( temp[i + max_objects] ); 1260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bbox->xMax = FT_RoundFix( temp[i + 2 * max_objects] ); 1261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bbox->yMax = FT_RoundFix( temp[i + 3 * max_objects] ); 1262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( temp ); 1265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 1269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* an error occurred */ 1270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if 0 /* obsolete -- keep for reference */ 1275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pflags ) 1276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pflags |= 1L << field->flag_bit; 1277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 1278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( pflags ); 1279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 1280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 1282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 1284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 1287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 1288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define T1_MAX_TABLE_ELEMENTS 32 1293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 1296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_load_field_table( PS_Parser parser, 1297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const T1_Field field, 1298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void** objects, 1299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt max_objects, 1300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong* pflags ) 1301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_TokenRec elements[T1_MAX_TABLE_ELEMENTS]; 1303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Token token; 1304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int num_elements; 1305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 1306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* old_cursor; 1307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* old_limit; 1308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_FieldRec fieldrec = *(T1_Field)field; 1309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fieldrec.type = T1_FIELD_TYPE_INTEGER; 1312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY || 1313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov field->type == T1_FIELD_TYPE_BBOX ) 1314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fieldrec.type = T1_FIELD_TYPE_FIXED; 1315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_to_token_array( parser, elements, 1317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_MAX_TABLE_ELEMENTS, &num_elements ); 1318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( num_elements < 0 ) 1319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_ERR( Ignore ); 1321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( (FT_UInt)num_elements > field->array_max ) 1324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_elements = field->array_max; 1325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old_cursor = parser->cursor; 1327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old_limit = parser->limit; 1328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we store the elements count if necessary; */ 1330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we further assume that `count_offset' can't be zero */ 1331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( field->type != T1_FIELD_TYPE_BBOX && field->count_offset != 0 ) 1332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) = 1333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Byte)num_elements; 1334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we now load each element, adjusting the field.offset on each one */ 1336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov token = elements; 1337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; num_elements > 0; num_elements--, token++ ) 1338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->cursor = token->start; 1340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->limit = token->limit; 1341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_load_field( parser, &fieldrec, objects, max_objects, 0 ); 1342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fieldrec.offset += fieldrec.size; 1343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if 0 /* obsolete -- keep for reference */ 1346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pflags ) 1347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pflags |= 1L << field->flag_bit; 1348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 1349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( pflags ); 1350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 1351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->cursor = old_cursor; 1353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->limit = old_limit; 1354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 1356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Long ) 1361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_to_int( PS_Parser parser ) 1362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_skip_spaces( parser ); 1364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return PS_Conv_ToInt( &parser->cursor, parser->limit ); 1365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first character must be `<' if `delimiters' is non-zero */ 1369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 1371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_to_bytes( PS_Parser parser, 1372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* bytes, 1373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Offset max_bytes, 1374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long* pnum_bytes, 1375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool delimiters ) 1376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 1378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* cur; 1379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_skip_spaces( parser ); 1382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = parser->cursor; 1383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur >= parser->limit ) 1385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( delimiters ) 1388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *cur != '<' ) 1390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "ps_parser_to_bytes: Missing starting delimiter `<'\n" )); 1392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 1393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 1397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pnum_bytes = PS_Conv_ASCIIHexDecode( &cur, 1400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->limit, 1401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bytes, 1402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max_bytes ); 1403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( delimiters ) 1405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur < parser->limit && *cur != '>' ) 1407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "ps_parser_to_bytes: Missing closing delimiter `>'\n" )); 1409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 1410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 1414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->cursor = cur; 1417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 1419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Fixed ) 1424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_to_fixed( PS_Parser parser, 1425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int power_ten ) 1426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_skip_spaces( parser ); 1428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return PS_Conv_ToFixed( &parser->cursor, parser->limit, power_ten ); 1429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Int ) 1433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_to_coord_array( PS_Parser parser, 1434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int max_coords, 1435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Short* coords ) 1436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_skip_spaces( parser ); 1438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return ps_tocoordarray( &parser->cursor, parser->limit, 1439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max_coords, coords ); 1440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Int ) 1444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_to_fixed_array( PS_Parser parser, 1445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int max_values, 1446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed* values, 1447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int power_ten ) 1448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_skip_spaces( parser ); 1450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return ps_tofixedarray( &parser->cursor, parser->limit, 1451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max_values, values, power_ten ); 1452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if 0 1456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_String* ) 1458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_ToString( PS_Parser parser ) 1459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return ps_tostring( &parser->cursor, parser->limit, parser->memory ); 1461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Bool ) 1465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_ToBool( PS_Parser parser ) 1466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return ps_tobool( &parser->cursor, parser->limit ); 1468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* 0 */ 1471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 1474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_init( PS_Parser parser, 1475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* base, 1476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit, 1477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory ) 1478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->error = FT_Err_Ok; 1480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->base = base; 1481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->limit = limit; 1482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->cursor = base; 1483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->memory = memory; 1484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->funcs = ps_parser_funcs; 1485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 1489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ps_parser_done( PS_Parser parser ) 1490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( parser ); 1492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** T1 BUILDER *****/ 1499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* t1_builder_init */ 1507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Initializes a given glyph builder. */ 1510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <InOut> */ 1512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* builder :: A pointer to the glyph builder to initialize. */ 1513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 1515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* face :: The current face object. */ 1516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* size :: The current size object. */ 1518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* glyph :: The current glyph object. */ 1520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* hinting :: Whether hinting should be applied. */ 1522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 1524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1_builder_init( T1_Builder builder, 1525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face face, 1526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size size, 1527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphSlot glyph, 1528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool hinting ) 1529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->parse_state = T1_Parse_Start; 1531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->load_points = 1; 1532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->face = face; 1534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->glyph = glyph; 1535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->memory = face->memory; 1536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( glyph ) 1538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader loader = glyph->internal->loader; 1540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->loader = loader; 1543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->base = &loader->base.outline; 1544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->current = &loader->current.outline; 1545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Rewind( loader ); 1546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->hints_globals = size->internal; 1548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->hints_funcs = 0; 1549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( hinting ) 1551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->hints_funcs = glyph->internal->glyph_hints; 1552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->pos_x = 0; 1555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->pos_y = 0; 1556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->left_bearing.x = 0; 1558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->left_bearing.y = 0; 1559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->advance.x = 0; 1560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->advance.y = 0; 1561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->funcs = t1_builder_funcs; 1563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* t1_builder_done */ 1570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Finalizes a given glyph builder. Its contents can still be used */ 1573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* after the call, but the function saves important information */ 1574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* within the corresponding glyph slot. */ 1575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 1577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* builder :: A pointer to the glyph builder to finalize. */ 1578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 1580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1_builder_done( T1_Builder builder ) 1581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphSlot glyph = builder->glyph; 1583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( glyph ) 1586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph->outline = *builder->base; 1587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check that there is enough space for `count' more points */ 1591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 1592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1_builder_check_points( T1_Builder builder, 1593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int count ) 1594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 ); 1596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* add a new point, do not check space */ 1600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 1601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1_builder_add_point( T1_Builder builder, 1602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pos x, 1603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pos y, 1604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte flag ) 1605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline* outline = builder->current; 1607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( builder->load_points ) 1610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* point = outline->points + outline->n_points; 1612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; 1613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov point->x = FIXED_TO_INT( x ); 1616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov point->y = FIXED_TO_INT( y ); 1617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); 1618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outline->n_points++; 1620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check space for a new on-curve point, then add it */ 1624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 1625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1_builder_add_point1( T1_Builder builder, 1626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pos x, 1627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pos y ) 1628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 1630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = t1_builder_check_points( builder, 1 ); 1633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 1634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1_builder_add_point( builder, x, y, 1 ); 1635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check space for a new contour, then add it */ 1641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 1642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1_builder_add_contour( T1_Builder builder ) 1643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline* outline = builder->current; 1645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 1646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this might happen in invalid fonts */ 1649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !outline ) 1650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "t1_builder_add_contour: no outline to add points to\n" )); 1652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_File_Format ); 1653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !builder->load_points ) 1656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outline->n_contours++; 1658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 1659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 ); 1662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 1663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( outline->n_contours > 0 ) 1665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outline->contours[outline->n_contours - 1] = 1666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (short)( outline->n_points - 1 ); 1667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outline->n_contours++; 1669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if a path was begun, add its first on-curve point */ 1676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 1677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1_builder_start_point( T1_Builder builder, 1678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pos x, 1679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pos y ) 1680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_ERR( Invalid_File_Format ); 1682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* test whether we are building a new contour */ 1685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( builder->parse_state == T1_Parse_Have_Path ) 1687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 1688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov builder->parse_state = T1_Parse_Have_Path; 1691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = t1_builder_add_contour( builder ); 1692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 1693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = t1_builder_add_point1( builder, x, y ); 1694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* close the current contour */ 1701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 1702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1_builder_close_contour( T1_Builder builder ) 1703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline* outline = builder->current; 1705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int first; 1706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !outline ) 1709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 1710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = outline->n_contours <= 1 1712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ? 0 : outline->contours[outline->n_contours - 2] + 1; 1713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We must not include the last point in the path if it */ 1715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* is located on the first point. */ 1716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( outline->n_points > 1 ) 1717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* p1 = outline->points + first; 1719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* p2 = outline->points + outline->n_points - 1; 1720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; 1721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `delete' last point only if it coincides with the first */ 1724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* point and it is not a control point (which can happen). */ 1725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p1->x == p2->x && p1->y == p2->y ) 1726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *control == FT_CURVE_TAG_ON ) 1727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outline->n_points--; 1728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( outline->n_contours > 0 ) 1731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Don't add contours only consisting of one point, i.e., */ 1733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check whether the first and the last point is the same. */ 1734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( first == outline->n_points - 1 ) 1735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outline->n_contours--; 1737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outline->n_points--; 1738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outline->contours[outline->n_contours - 1] = 1741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (short)( outline->n_points - 1 ); 1742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** OTHER *****/ 1750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 1755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1_decrypt( FT_Byte* buffer, 1756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Offset length, 1757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UShort seed ) 1758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PS_Conv_EexecDecode( &buffer, 1760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov buffer + length, 1761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov buffer, 1762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov length, 1763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &seed ); 1764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */ 1768