35#define FT_COMPONENT cidparse
49#define STARTDATA "StartData"
50#define STARTDATA_LEN ( sizeof ( STARTDATA ) - 1 )
52#define SFNTS_LEN ( sizeof ( SFNTS ) - 1 )
55 FT_LOCAL_DEF( FT_Error )
56 cid_parser_new( CID_Parser* parser,
62 FT_ULong base_offset, offset, ps_len;
68 psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );
70 parser->stream = stream;
72 base_offset = FT_STREAM_POS();
75 if ( FT_FRAME_ENTER( 31 ) )
77 FT_TRACE2((
" not a CID-keyed font\n" ));
78 error = FT_THROW( Unknown_File_Format );
82 if ( ft_strncmp( (
char *)stream->cursor,
83 "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) )
85 FT_TRACE2((
" not a CID-keyed font\n" ));
86 error = FT_THROW( Unknown_File_Format );
93 if ( !stream->read ) {
95 offset = stream->size;
119 FT_Byte buffer[256 + STARTDATA_LEN + 1];
122 FT_ULong read_len = 256 + STARTDATA_LEN;
123 FT_ULong read_offset = 0;
133 stream_len = stream->size - FT_STREAM_POS();
135 read_len = FT_MIN( read_len, stream_len );
136 if ( read_len && FT_STREAM_READ( p, read_len ) )
142 limit = p + read_len - SFNTS_LEN;
144 for ( p = buffer; p < limit; p++ )
147 ft_strncmp( (
char*)p, STARTDATA, STARTDATA_LEN ) == 0 )
150 offset = FT_STREAM_POS() - read_len - read_offset
151 + (FT_ULong)( p - buffer ) + STARTDATA_LEN + 1;
153 else if ( p[1] ==
's' &&
154 ft_strncmp( (
char*)p, SFNTS, SFNTS_LEN ) == 0 )
156 offset = FT_STREAM_POS() - read_len - read_offset
157 + (FT_ULong)( p - buffer ) + SFNTS_LEN + 1;
161 if ( read_offset + read_len <= STARTDATA_LEN )
166 FT_TRACE2((
"cid_parser_new: no `StartData` keyword found\n" ));
167 error = FT_THROW( Invalid_File_Format );
172 buffer + read_offset + read_len - STARTDATA_LEN,
177 read_offset = STARTDATA_LEN;
178 p = buffer + read_offset;
187 ps_len = offset - base_offset;
188 if ( FT_STREAM_SEEK( base_offset ) ||
189 FT_FRAME_EXTRACT( ps_len, parser->postscript ) )
192 parser->data_offset = offset;
193 parser->postscript_len = ps_len;
194 parser->root.base = parser->postscript;
195 parser->root.cursor = parser->postscript;
196 parser->root.limit = parser->root.cursor + ps_len;
197 parser->num_dict = FT_UINT_MAX;
204 arg1 = parser->root.cursor;
205 cid_parser_skip_PS_token( parser );
206 cid_parser_skip_spaces ( parser );
207 arg2 = parser->root.cursor;
208 cid_parser_skip_PS_token( parser );
209 cid_parser_skip_spaces ( parser );
211 limit = parser->root.limit;
212 cur = parser->root.cursor;
214 while ( cur <= limit - SFNTS_LEN )
216 if ( parser->root.error )
218 error = parser->root.error;
222 if ( cur[0] ==
'S' &&
223 cur <= limit - STARTDATA_LEN &&
224 ft_strncmp( (
char*)cur, STARTDATA, STARTDATA_LEN ) == 0 )
226 T1_TokenRec type_token;
227 FT_Long binary_length;
228 FT_ULong found_offset;
231 parser->root.cursor = arg1;
232 cid_parser_to_token( parser, &type_token );
233 if ( type_token.limit - type_token.start == 5 &&
234 ft_memcmp( (
char*)type_token.start,
"(Hex)", 5 ) == 0 )
236 parser->root.cursor = arg2;
237 binary_length = cid_parser_to_int( parser );
238 if ( binary_length < 0 )
240 FT_ERROR((
"cid_parser_new: invalid length of hex data\n" ));
241 error = FT_THROW( Invalid_File_Format );
244 parser->binary_length = (FT_ULong)binary_length;
248 found_offset = (FT_ULong)( cur - parser->postscript )
250 if ( found_offset != offset )
252 FT_FRAME_RELEASE( parser->postscript );
254 ps_len = found_offset - base_offset;
255 if ( FT_STREAM_SEEK( base_offset ) ||
256 FT_FRAME_EXTRACT( ps_len, parser->postscript ) )
259 parser->data_offset = found_offset;
260 parser->postscript_len = ps_len;
261 parser->root.base = parser->postscript;
262 parser->root.cursor = parser->postscript;
263 parser->root.limit = parser->root.cursor + ps_len;
267 else if ( cur[1] ==
's' &&
268 ft_strncmp( (
char*)cur, SFNTS, SFNTS_LEN ) == 0 )
270 FT_TRACE2((
"cid_parser_new: cannot handle Type 11 fonts\n" ));
271 error = FT_THROW( Unknown_File_Format );
275 cid_parser_skip_PS_token( parser );
276 cid_parser_skip_spaces ( parser );
279 cur = parser->root.cursor;
282 FT_TRACE2((
"cid_parser_new: no `StartData` token found\n" ));
283 error = FT_THROW( Invalid_File_Format );
297 cid_parser_done( CID_Parser* parser )
300 if ( parser->postscript )
302 FT_Stream stream = parser->stream;
305 FT_FRAME_RELEASE( parser->postscript );
307 parser->root.funcs.done( &parser->root );