cidparse.c revision bebc7b11c52c00e8edfaf2ba38ca25d135404a1c
1/***************************************************************************/ 2/* */ 3/* cidparse.c */ 4/* */ 5/* CID-keyed Type1 parser (body). */ 6/* */ 7/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ 8/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9/* */ 10/* This file is part of the FreeType project, and may only be used, */ 11/* modified, and distributed under the terms of the FreeType project */ 12/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13/* this file you indicate that you have read the license and */ 14/* understand and accept it fully. */ 15/* */ 16/***************************************************************************/ 17 18 19#include <ft2build.h> 20#include FT_INTERNAL_DEBUG_H 21#include FT_INTERNAL_CALC_H 22#include FT_INTERNAL_OBJECTS_H 23#include FT_INTERNAL_STREAM_H 24 25#include "cidparse.h" 26 27#include "ciderrs.h" 28 29 30 /*************************************************************************/ 31 /* */ 32 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 33 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 34 /* messages during execution. */ 35 /* */ 36#undef FT_COMPONENT 37#define FT_COMPONENT trace_cidparse 38 39 40 /*************************************************************************/ 41 /*************************************************************************/ 42 /*************************************************************************/ 43 /***** *****/ 44 /***** INPUT STREAM PARSER *****/ 45 /***** *****/ 46 /*************************************************************************/ 47 /*************************************************************************/ 48 /*************************************************************************/ 49 50 51 FT_LOCAL_DEF( FT_Error ) 52 cid_parser_new( CID_Parser* parser, 53 FT_Stream stream, 54 FT_Memory memory, 55 PSAux_Service psaux ) 56 { 57 FT_Error error; 58 FT_ULong base_offset, offset, ps_len; 59 FT_Byte *cur, *limit; 60 FT_Byte *arg1, *arg2; 61 62 63 FT_MEM_ZERO( parser, sizeof ( *parser ) ); 64 psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); 65 66 parser->stream = stream; 67 68 base_offset = FT_STREAM_POS(); 69 70 /* first of all, check the font format in the header */ 71 if ( FT_FRAME_ENTER( 31 ) ) 72 goto Exit; 73 74 if ( ft_strncmp( (char *)stream->cursor, 75 "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) ) 76 { 77 FT_TRACE2(( "[not a valid CID-keyed font]\n" )); 78 error = CID_Err_Unknown_File_Format; 79 } 80 81 FT_FRAME_EXIT(); 82 if ( error ) 83 goto Exit; 84 85 Again: 86 /* now, read the rest of the file until we find */ 87 /* `StartData' or `/sfnts' */ 88 { 89 FT_Byte buffer[256 + 10]; 90 FT_Int read_len = 256 + 10; 91 FT_Byte* p = buffer; 92 93 94 for ( offset = (FT_ULong)FT_STREAM_POS(); ; offset += 256 ) 95 { 96 FT_Int stream_len; 97 98 99 stream_len = stream->size - FT_STREAM_POS(); 100 if ( stream_len == 0 ) 101 goto Exit; 102 103 read_len = FT_MIN( read_len, stream_len ); 104 if ( FT_STREAM_READ( p, read_len ) ) 105 goto Exit; 106 107 if ( read_len < 256 ) 108 p[read_len] = '\0'; 109 110 limit = p + read_len - 10; 111 112 for ( p = buffer; p < limit; p++ ) 113 { 114 if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 ) 115 { 116 /* save offset of binary data after `StartData' */ 117 offset += p - buffer + 10; 118 goto Found; 119 } 120 else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 ) 121 { 122 offset += p - buffer + 7; 123 goto Found; 124 } 125 } 126 127 FT_MEM_MOVE( buffer, p, 10 ); 128 read_len = 256; 129 p = buffer + 10; 130 } 131 } 132 133 Found: 134 /* We have found the start of the binary data or the `/sfnts' token. */ 135 /* Now rewind and extract the frame corresponding to this PostScript */ 136 /* section. */ 137 138 ps_len = offset - base_offset; 139 if ( FT_STREAM_SEEK( base_offset ) || 140 FT_FRAME_EXTRACT( ps_len, parser->postscript ) ) 141 goto Exit; 142 143 parser->data_offset = offset; 144 parser->postscript_len = ps_len; 145 parser->root.base = parser->postscript; 146 parser->root.cursor = parser->postscript; 147 parser->root.limit = parser->root.cursor + ps_len; 148 parser->num_dict = -1; 149 150 /* Finally, we check whether `StartData' or `/sfnts' was real -- */ 151 /* it could be in a comment or string. We also get the arguments */ 152 /* of `StartData' to find out whether the data is represented in */ 153 /* binary or hex format. */ 154 155 arg1 = parser->root.cursor; 156 cid_parser_skip_PS_token( parser ); 157 cid_parser_skip_spaces ( parser ); 158 arg2 = parser->root.cursor; 159 cid_parser_skip_PS_token( parser ); 160 cid_parser_skip_spaces ( parser ); 161 162 limit = parser->root.limit; 163 cur = parser->root.cursor; 164 165 while ( cur < limit ) 166 { 167 if ( parser->root.error ) 168 { 169 error = parser->root.error; 170 goto Exit; 171 } 172 173 if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) 174 { 175 if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) 176 parser->binary_length = ft_atol( (const char *)arg2 ); 177 178 limit = parser->root.limit; 179 cur = parser->root.cursor; 180 goto Exit; 181 } 182 else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 ) 183 { 184 FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" )); 185 error = CID_Err_Unknown_File_Format; 186 goto Exit; 187 } 188 189 cid_parser_skip_PS_token( parser ); 190 cid_parser_skip_spaces ( parser ); 191 arg1 = arg2; 192 arg2 = cur; 193 cur = parser->root.cursor; 194 } 195 196 /* we haven't found the correct `StartData'; go back and continue */ 197 /* searching */ 198 FT_FRAME_RELEASE( parser->postscript ); 199 if ( !FT_STREAM_SEEK( offset ) ) 200 goto Again; 201 202 Exit: 203 return error; 204 } 205 206 207 FT_LOCAL_DEF( void ) 208 cid_parser_done( CID_Parser* parser ) 209 { 210 /* always free the private dictionary */ 211 if ( parser->postscript ) 212 { 213 FT_Stream stream = parser->stream; 214 215 216 FT_FRAME_RELEASE( parser->postscript ); 217 } 218 parser->root.funcs.done( &parser->root ); 219 } 220 221 222/* END */ 223