1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* cffparse.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* CFF token stream parser (body) */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Copyright 1996-2004, 2007-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 "cffparse.h" 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftstream.h" 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftdebug.h" 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cfferrs.h" 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cffpic.h" 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* messages during execution. */ 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_cffparse 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_parser_init( CFF_Parser parser, 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt code, 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* object, 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Library library) 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_ZERO( parser, sizeof ( *parser ) ); 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->top = parser->stack; 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->object_code = code; 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->object = object; 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->library = library; 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* read an integer */ 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Long 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_parse_integer( FT_Byte* start, 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit ) 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = start; 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int v = *p++; 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long val = 0; 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( v == 28 ) 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 2 > limit ) 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Bad; 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] ); 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2; 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( v == 29 ) 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 4 > limit ) 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Bad; 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) | 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( (FT_ULong)p[1] << 16 ) | 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( (FT_ULong)p[2] << 8 ) | 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_ULong)p[3] ); 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 4; 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( v < 247 ) 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = v - 139; 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( v < 251 ) 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 1 > limit ) 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Bad; 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = ( v - 247 ) * 256 + p[0] + 108; 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p++; 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 1 > limit ) 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Bad; 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = -( v - 251 ) * 256 - p[0] - 108; 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p++; 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return val; 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Bad: 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = 0; 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "!!!END OF DATA:!!!" )); 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const FT_Long power_tens[] = 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1L, 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 10L, 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 100L, 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1000L, 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 10000L, 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 100000L, 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1000000L, 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 10000000L, 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 100000000L, 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1000000000L 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* read a real */ 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Fixed 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_parse_real( FT_Byte* start, 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit, 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long power_ten, 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long* scaling ) 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = start; 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt nib; 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt phase; 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long result, number, exponent; 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int sign = 0, exponent_sign = 0, have_overflow = 0; 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long exponent_add, integer_length, fraction_length; 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( scaling ) 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *scaling = 0; 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = 0; 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov number = 0; 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov exponent = 0; 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov exponent_add = 0; 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov integer_length = 0; 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fraction_length = 0; 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* First of all, read the integer part. */ 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov phase = 4; 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (;;) 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If we entered this iteration with phase == 4, we need to */ 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* read a new byte. This also skips past the initial 0x1E. */ 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( phase ) 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p++; 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Make sure we don't read past the end. */ 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p >= limit ) 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Bad; 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Get the nibble. */ 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nib = ( p[0] >> phase ) & 0xF; 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov phase = 4 - phase; 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( nib == 0xE ) 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sign = 1; 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( nib > 9 ) 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Increase exponent if we can't add the digit. */ 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( number >= 0xCCCCCCCL ) 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov exponent_add++; 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Skip leading zeros. */ 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( nib || number ) 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov integer_length++; 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov number = number * 10 + nib; 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Read fraction part, if any. */ 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( nib == 0xa ) 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (;;) 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If we entered this iteration with phase == 4, we need */ 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* to read a new byte. */ 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( phase ) 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p++; 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Make sure we don't read past the end. */ 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p >= limit ) 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Bad; 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Get the nibble. */ 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nib = ( p[0] >> phase ) & 0xF; 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov phase = 4 - phase; 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( nib >= 10 ) 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Skip leading zeros if possible. */ 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !nib && !number ) 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov exponent_add--; 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Only add digit if we don't overflow. */ 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( number < 0xCCCCCCCL && fraction_length < 9 ) 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fraction_length++; 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov number = number * 10 + nib; 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Read exponent, if any. */ 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( nib == 12 ) 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov exponent_sign = 1; 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nib = 11; 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( nib == 11 ) 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (;;) 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If we entered this iteration with phase == 4, */ 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we need to read a new byte. */ 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( phase ) 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p++; 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Make sure we don't read past the end. */ 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p >= limit ) 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Bad; 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Get the nibble. */ 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nib = ( p[0] >> phase ) & 0xF; 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov phase = 4 - phase; 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( nib >= 10 ) 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Arbitrarily limit exponent. */ 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( exponent > 1000 ) 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov have_overflow = 1; 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov exponent = exponent * 10 + nib; 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( exponent_sign ) 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov exponent = -exponent; 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !number ) 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( have_overflow ) 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( exponent_sign ) 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Underflow; 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Overflow; 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We don't check `power_ten' and `exponent_add'. */ 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov exponent += power_ten + exponent_add; 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( scaling ) 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Only use `fraction_length'. */ 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fraction_length += integer_length; 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov exponent += integer_length; 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( fraction_length <= 5 ) 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( number > 0x7FFFL ) 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = FT_DivFix( number, 10 ); 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *scaling = exponent - fraction_length + 1; 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( exponent > 0 ) 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long new_fraction_length, shift; 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Make `scaling' as small as possible. */ 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov new_fraction_length = FT_MIN( exponent, 5 ); 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov shift = new_fraction_length - fraction_length; 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( shift > 0 ) 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov exponent -= new_fraction_length; 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov number *= power_tens[shift]; 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( number > 0x7FFFL ) 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov number /= 10; 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov exponent += 1; 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov exponent -= fraction_length; 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov exponent -= fraction_length; 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = (FT_Long)( (FT_ULong)number << 16 ); 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *scaling = exponent; 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL ) 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = FT_DivFix( number, power_tens[fraction_length - 4] ); 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *scaling = exponent - 4; 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = FT_DivFix( number, power_tens[fraction_length - 5] ); 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *scaling = exponent - 5; 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov integer_length += exponent; 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fraction_length -= exponent; 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( integer_length > 5 ) 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Overflow; 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( integer_length < -5 ) 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Underflow; 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Remove non-significant digits. */ 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( integer_length < 0 ) 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov number /= power_tens[-integer_length]; 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fraction_length += integer_length; 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this can only happen if exponent was non-zero */ 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( fraction_length == 10 ) 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov number /= 10; 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fraction_length -= 1; 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Convert into 16.16 format. */ 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( fraction_length > 0 ) 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( number / power_tens[fraction_length] ) > 0x7FFFL ) 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = FT_DivFix( number, power_tens[fraction_length] ); 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov number *= power_tens[-fraction_length]; 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( number > 0x7FFFL ) 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Overflow; 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = (FT_Long)( (FT_ULong)number << 16 ); 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( sign ) 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = -result; 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Overflow: 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = 0x7FFFFFFFL; 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "!!!OVERFLOW:!!!" )); 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Underflow: 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = 0; 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "!!!UNDERFLOW:!!!" )); 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Bad: 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = 0; 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "!!!END OF DATA:!!!" )); 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* read a number, either integer or real */ 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Long 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_parse_num( FT_Byte** d ) 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 ) 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov : cff_parse_integer( d[0], d[1] ); 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* read a floating point number, either integer or real */ 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Fixed 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov do_fixed( FT_Byte** d, 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long scaling ) 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( **d == 30 ) 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cff_parse_real( d[0], d[1], scaling, NULL ); 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long val = cff_parse_integer( d[0], d[1] ); 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( scaling ) 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val *= power_tens[scaling]; 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( val > 0x7FFF ) 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = 0x7FFFFFFFL; 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Overflow; 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( val < -0x7FFF ) 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = -0x7FFFFFFFL; 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Overflow; 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (FT_Long)( (FT_ULong)val << 16 ); 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Overflow: 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "!!!OVERFLOW:!!!" )); 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return val; 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* read a floating point number, either integer or real */ 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Fixed 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_parse_fixed( FT_Byte** d ) 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return do_fixed( d, 0 ); 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* read a floating point number, either integer or real, */ 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* but return `10^scaling' times the number read in */ 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Fixed 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_parse_fixed_scaled( FT_Byte** d, 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long scaling ) 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return do_fixed( d, scaling ); 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* read a floating point number, either integer or real, */ 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* and return it as precise as possible -- `scaling' returns */ 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the scaling factor (as a power of 10) */ 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Fixed 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_parse_fixed_dynamic( FT_Byte** d, 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long* scaling ) 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( scaling ); 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( **d == 30 ) 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cff_parse_real( d[0], d[1], 0, scaling ); 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long number; 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int integer_length; 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov number = cff_parse_integer( d[0], d[1] ); 483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( number > 0x7FFFL ) 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( integer_length = 5; integer_length < 10; integer_length++ ) 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( number < power_tens[integer_length] ) 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL ) 491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *scaling = integer_length - 4; 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_DivFix( number, power_tens[integer_length - 4] ); 494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *scaling = integer_length - 5; 498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_DivFix( number, power_tens[integer_length - 5] ); 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *scaling = 0; 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (FT_Long)( (FT_ULong)number << 16 ); 505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_parse_font_matrix( CFF_Parser parser ) 512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; 514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Matrix* matrix = &dict->font_matrix; 515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* offset = &dict->font_offset; 516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong* upm = &dict->units_per_em; 517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte** data = parser->stack; 518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_ERR( Stack_Underflow ); 519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->top >= parser->stack + 6 ) 522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long scaling; 524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->has_font_matrix = TRUE; 529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We expect a well-formed font matrix, this is, the matrix elements */ 531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `xx' and `yy' are of approximately the same magnitude. To avoid */ 532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* loss of precision, we use the magnitude of element `xx' to scale */ 533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* all other elements. The scaling factor is then contained in the */ 534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `units_per_em' value. */ 535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->xx = cff_parse_fixed_dynamic( data++, &scaling ); 537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov scaling = -scaling; 539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( scaling < 0 || scaling > 9 ) 541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Return default matrix in case of unlikely values. */ 543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "cff_parse_font_matrix:" 545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " strange scaling value for xx element (%d),\n" 546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " " 547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " using default matrix\n", scaling )); 548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->xx = 0x10000L; 550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->yx = 0; 551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->xy = 0; 552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->yy = 0x10000L; 553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset->x = 0; 554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset->y = 0; 555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *upm = 1; 556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->yx = cff_parse_fixed_scaled( data++, scaling ); 561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->xy = cff_parse_fixed_scaled( data++, scaling ); 562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->yy = cff_parse_fixed_scaled( data++, scaling ); 563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset->x = cff_parse_fixed_scaled( data++, scaling ); 564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset->y = cff_parse_fixed_scaled( data, scaling ); 565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *upm = power_tens[scaling]; 567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( " [%f %f %f %f %f %f]\n", 569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (double)matrix->xx / *upm / 65536, 570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (double)matrix->xy / *upm / 65536, 571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (double)matrix->yx / *upm / 65536, 572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (double)matrix->yy / *upm / 65536, 573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (double)offset->x / *upm / 65536, 574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (double)offset->y / *upm / 65536 )); 575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_parse_font_bbox( CFF_Parser parser ) 584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; 586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BBox* bbox = &dict->font_bbox; 587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte** data = parser->stack; 588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_ERR( Stack_Underflow ); 592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->top >= parser->stack + 4 ) 594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) ); 596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) ); 597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) ); 598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bbox->yMax = FT_RoundFix( cff_parse_fixed( data ) ); 599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( " [%d %d %d %d]\n", 602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bbox->xMin / 65536, 603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bbox->yMin / 65536, 604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bbox->xMax / 65536, 605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bbox->yMax / 65536 )); 606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_parse_private_dict( CFF_Parser parser ) 614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; 616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte** data = parser->stack; 617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_ERR( Stack_Underflow ); 621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->top >= parser->stack + 2 ) 623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->private_size = cff_parse_num( data++ ); 625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->private_offset = cff_parse_num( data ); 626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( " %lu %lu\n", 627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->private_size, dict->private_offset )); 628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_parse_cid_ros( CFF_Parser parser ) 638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; 640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte** data = parser->stack; 641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_ERR( Stack_Underflow ); 645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->top >= parser->stack + 3 ) 647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->cid_registry = (FT_UInt)cff_parse_num( data++ ); 649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->cid_ordering = (FT_UInt)cff_parse_num( data++ ); 650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( **data == 30 ) 651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" )); 652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->cid_supplement = cff_parse_num( data ); 653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dict->cid_supplement < 0 ) 654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n", 655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->cid_supplement )); 656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( " %d %d %d\n", 659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->cid_registry, 660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->cid_ordering, 661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->cid_supplement )); 662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD_NUM( code, name, id ) \ 669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_FIELD( code, name, id, cff_kind_num ) 670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD_FIXED( code, name, id ) \ 671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_FIELD( code, name, id, cff_kind_fixed ) 672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD_FIXED_1000( code, name, id ) \ 673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_FIELD( code, name, id, cff_kind_fixed_thousand ) 674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD_STRING( code, name, id ) \ 675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_FIELD( code, name, id, cff_kind_string ) 676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD_BOOL( code, name, id ) \ 677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_FIELD( code, name, id, cff_kind_bool ) 678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFFCODE_TOPDICT 0x1000 680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFFCODE_PRIVATE 0x2000 681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_CONFIG_OPTION_PIC 684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef CFF_FIELD 687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef CFF_FIELD_DELTA 688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_DEBUG_LEVEL_TRACE 691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD_CALLBACK( code, name, id ) \ 694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { \ 695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_kind_callback, \ 696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov code | CFFCODE, \ 697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, 0, \ 698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_parse_ ## name, \ 699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, 0 \ 700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }, 701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD( code, name, id, kind ) \ 703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { \ 704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov kind, \ 705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov code | CFFCODE, \ 706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FIELD_OFFSET( name ), \ 707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FIELD_SIZE( name ), \ 708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, 0, 0 \ 709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }, 710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD_DELTA( code, name, max, id ) \ 712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { \ 713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_kind_delta, \ 714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov code | CFFCODE, \ 715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FIELD_OFFSET( name ), \ 716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FIELD_SIZE_DELTA( name ), \ 717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, \ 718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max, \ 719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FIELD_OFFSET( num_ ## name ) \ 720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }, 721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const CFF_Field_Handler cff_field_handlers[] = 723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cfftoken.h" 726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 0, 0, 0, 0, 0, 0, 0 } 728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* FT_DEBUG_LEVEL_TRACE */ 732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD_CALLBACK( code, name, id ) \ 736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { \ 737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_kind_callback, \ 738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov code | CFFCODE, \ 739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, 0, \ 740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_parse_ ## name, \ 741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, 0, \ 742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov id \ 743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }, 744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD( code, name, id, kind ) \ 746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { \ 747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov kind, \ 748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov code | CFFCODE, \ 749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FIELD_OFFSET( name ), \ 750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FIELD_SIZE( name ), \ 751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, 0, 0, \ 752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov id \ 753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }, 754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD_DELTA( code, name, max, id ) \ 756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { \ 757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_kind_delta, \ 758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov code | CFFCODE, \ 759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FIELD_OFFSET( name ), \ 760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FIELD_SIZE_DELTA( name ), \ 761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, \ 762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max, \ 763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FIELD_OFFSET( num_ ## name ), \ 764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov id \ 765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }, 766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const CFF_Field_Handler cff_field_handlers[] = 768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cfftoken.h" 771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 0, 0, 0, 0, 0, 0, 0, 0 } 773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_DEBUG_LEVEL_TRACE */ 777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* FT_CONFIG_OPTION_PIC */ 780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void 783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Destroy_Class_cff_field_handlers( FT_Library library, 784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Field_Handler* clazz ) 785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = library->memory; 787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz ) 790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( clazz ); 791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error 795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Create_Class_cff_field_handlers( FT_Library library, 796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Field_Handler** output_class ) 797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Field_Handler* clazz = NULL; 799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = library->memory; 801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i = 0; 803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef CFF_FIELD 806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD( code, name, id, kind ) i++; 807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef CFF_FIELD_DELTA 808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD_DELTA( code, name, max, id ) i++; 809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef CFF_FIELD_CALLBACK 810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD_CALLBACK( code, name, id ) i++; 811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cfftoken.h" 813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i++; /* { 0, 0, 0, 0, 0, 0, 0 } */ 815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ALLOC( clazz, sizeof ( CFF_Field_Handler ) * i ) ) 817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i = 0; 820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_DEBUG_LEVEL_TRACE 823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef CFF_FIELD_CALLBACK 826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD_CALLBACK( code_, name_, id_ ) \ 827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].kind = cff_kind_callback; \ 828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].code = code_ | CFFCODE; \ 829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].offset = 0; \ 830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].size = 0; \ 831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].reader = cff_parse_ ## name_; \ 832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].array_max = 0; \ 833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].count_offset = 0; \ 834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i++; 835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef CFF_FIELD 837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD( code_, name_, id_, kind_ ) \ 838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].kind = kind_; \ 839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].code = code_ | CFFCODE; \ 840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ 841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].size = FT_FIELD_SIZE( name_ ); \ 842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].reader = 0; \ 843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].array_max = 0; \ 844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].count_offset = 0; \ 845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i++; \ 846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef CFF_FIELD_DELTA 848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD_DELTA( code_, name_, max_, id_ ) \ 849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].kind = cff_kind_delta; \ 850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].code = code_ | CFFCODE; \ 851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ 852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \ 853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].reader = 0; \ 854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].array_max = max_; \ 855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \ 856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i++; 857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cfftoken.h" 859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].kind = 0; 861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].code = 0; 862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].offset = 0; 863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].size = 0; 864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].reader = 0; 865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].array_max = 0; 866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].count_offset = 0; 867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* FT_DEBUG_LEVEL_TRACE */ 870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef CFF_FIELD_CALLBACK 873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD_CALLBACK( code_, name_, id_ ) \ 874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].kind = cff_kind_callback; \ 875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].code = code_ | CFFCODE; \ 876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].offset = 0; \ 877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].size = 0; \ 878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].reader = cff_parse_ ## name_; \ 879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].array_max = 0; \ 880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].count_offset = 0; \ 881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].id = id_; \ 882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i++; 883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef CFF_FIELD 885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD( code_, name_, id_, kind_ ) \ 886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].kind = kind_; \ 887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].code = code_ | CFFCODE; \ 888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ 889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].size = FT_FIELD_SIZE( name_ ); \ 890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].reader = 0; \ 891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].array_max = 0; \ 892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].count_offset = 0; \ 893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].id = id_; \ 894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i++; \ 895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef CFF_FIELD_DELTA 897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_FIELD_DELTA( code_, name_, max_, id_ ) \ 898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].kind = cff_kind_delta; \ 899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].code = code_ | CFFCODE; \ 900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ 901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \ 902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].reader = 0; \ 903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].array_max = max_; \ 904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \ 905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].id = id_; \ 906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i++; 907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cfftoken.h" 909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].kind = 0; 911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].code = 0; 912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].offset = 0; 913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].size = 0; 914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].reader = 0; 915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].array_max = 0; 916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].count_offset = 0; 917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i].id = 0; 918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_DEBUG_LEVEL_TRACE */ 921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *output_class = clazz; 924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_CONFIG_OPTION_PIC */ 930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_parser_run( CFF_Parser parser, 934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* start, 935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit ) 936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = start; 938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Library library = parser->library; 940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( library ); 941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->top = parser->stack; 944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->start = start; 945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->limit = limit; 946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->cursor = start; 947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( p < limit ) 949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt v = *p; 951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( v >= 27 && v != 31 ) 954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* it's a number; we will push its position on the stack */ 956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH ) 957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Stack_Overflow; 958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *parser->top ++ = p; 960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now, skip it */ 962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( v == 30 ) 963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* skip real number */ 965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p++; 966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (;;) 967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* An unterminated floating point number at the */ 969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* end of a dictionary is invalid but harmless. */ 970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p >= limit ) 971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v = p[0] >> 4; 973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( v == 15 ) 974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v = p[0] & 0xF; 976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( v == 15 ) 977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p++; 979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( v == 28 ) 982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2; 983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( v == 29 ) 984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 4; 985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( v > 246 ) 986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 1; 987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This is not a number, hence it's an operator. Compute its code */ 991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* and look for it in our current list. */ 992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt code; 994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt num_args = (FT_UInt) 995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( parser->top - parser->stack ); 996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const CFF_Field_Handler* field; 997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *parser->top = p; 1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov code = v; 1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( v == 12 ) 1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* two byte operator */ 1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p++; 1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p >= limit ) 1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Syntax_Error; 1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov code = 0x100 | p[0]; 1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov code = code | parser->object_code; 1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( field = CFF_FIELD_HANDLERS_GET; field->kind; field++ ) 1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( field->code == (FT_Int)code ) 1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we found our field's handler; read it */ 1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long val; 1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* q = (FT_Byte*)parser->object + field->offset; 1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_TRACE 1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( " %s", field->id )); 1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check that we have enough arguments -- except for */ 1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* delta encoded arrays, which can be empty */ 1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( field->kind != cff_kind_delta && num_args < 1 ) 1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Stack_Underflow; 1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( field->kind ) 1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cff_kind_bool: 1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cff_kind_string: 1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cff_kind_num: 1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = cff_parse_num( parser->stack ); 1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Store_Number; 1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cff_kind_fixed: 1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = cff_parse_fixed( parser->stack ); 1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Store_Number; 1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cff_kind_fixed_thousand: 1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = cff_parse_fixed_scaled( parser->stack, 3 ); 1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Store_Number: 1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( field->size ) 1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case (8 / FT_CHAR_BIT): 1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_Byte*)q = (FT_Byte)val; 1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case (16 / FT_CHAR_BIT): 1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_Short*)q = (FT_Short)val; 1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case (32 / FT_CHAR_BIT): 1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_Int32*)q = (FT_Int)val; 1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: /* for 64-bit systems */ 1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_Long*)q = val; 1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_TRACE 1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( field->kind ) 1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cff_kind_bool: 1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( " %s\n", val ? "true" : "false" )); 1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cff_kind_string: 1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( " %ld (SID)\n", val )); 1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cff_kind_num: 1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( " %ld\n", val )); 1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cff_kind_fixed: 1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( " %f\n", (double)val / 65536 )); 1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cff_kind_fixed_thousand: 1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( " %f\n", (double)val / 65536 / 1000 )); 1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ; /* never reached */ 1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cff_kind_delta: 1094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* qcount = (FT_Byte*)parser->object + 1096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov field->count_offset; 1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte** data = parser->stack; 1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( num_args > field->array_max ) 1102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_args = field->array_max; 1103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( " [" )); 1105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* store count */ 1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *qcount = (FT_Byte)num_args; 1108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = 0; 1110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( num_args > 0 ) 1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val += cff_parse_num( data++ ); 1113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( field->size ) 1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case (8 / FT_CHAR_BIT): 1116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_Byte*)q = (FT_Byte)val; 1117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case (16 / FT_CHAR_BIT): 1120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_Short*)q = (FT_Short)val; 1121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case (32 / FT_CHAR_BIT): 1124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_Int32*)q = (FT_Int)val; 1125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: /* for 64-bit systems */ 1128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_Long*)q = val; 1129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( " %ld", val )); 1132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov q += field->size; 1134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_args--; 1135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "]\n" )); 1138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: /* callback */ 1142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = field->reader( parser ); 1143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Found; 1147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this is an unknown operator, or it is unsupported; */ 1151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we will ignore it for now. */ 1152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Found: 1154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* clear stack */ 1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->top = parser->stack; 1156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p++; 1158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 1161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Stack_Overflow: 1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Argument ); 1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Stack_Underflow: 1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Argument ); 1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Syntax_Error: 1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Argument ); 1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */ 1178