cid_parser_new( CID_Parser* parser, FT_Stream stream, FT_Memory memory, PSAux_Service psaux ) { FT_Error error; FT_ULong base_offset, offset, ps_len; FT_Byte *cur, *limit; FT_Byte *arg1, *arg2; FT_MEM_ZERO( parser, sizeof ( *parser ) ); psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); parser->stream = stream; base_offset = FT_STREAM_POS(); /* first of all, check the font format in the header */ if ( FT_FRAME_ENTER( 31 ) ) goto Exit; if ( ft_strncmp( (char *)stream->cursor, "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) ) { FT_TRACE2(( " not a CID-keyed font\n" )); error = FT_THROW( Unknown_File_Format ); } FT_FRAME_EXIT(); if ( error ) goto Exit; Again: /* now, read the rest of the file until we find */ /* `StartData' or `/sfnts' */ { FT_Byte buffer[256 + 10]; FT_ULong read_len = 256 + 10; FT_Byte* p = buffer; for ( offset = FT_STREAM_POS(); ; offset += 256 ) { FT_ULong stream_len; stream_len = stream->size - FT_STREAM_POS(); if ( stream_len == 0 ) { FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } read_len = FT_MIN( read_len, stream_len ); if ( FT_STREAM_READ( p, read_len ) ) goto Exit; if ( read_len < 256 ) p[read_len] = '\0'; limit = p + read_len - 10; for ( p = buffer; p < limit; p++ ) { if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 ) { /* save offset of binary data after `StartData' */ offset += (FT_ULong)( p - buffer + 10 ); goto Found; } else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 ) { offset += (FT_ULong)( p - buffer + 7 ); goto Found; } } FT_MEM_MOVE( buffer, p, 10 ); read_len = 256; p = buffer + 10; } } Found: /* We have found the start of the binary data or the `/sfnts' token. */ /* Now rewind and extract the frame corresponding to this PostScript */ /* section. */ ps_len = offset - base_offset; if ( FT_STREAM_SEEK( base_offset ) || FT_FRAME_EXTRACT( ps_len, parser->postscript ) ) goto Exit; parser->data_offset = offset; parser->postscript_len = ps_len; parser->root.base = parser->postscript; parser->root.cursor = parser->postscript; parser->root.limit = parser->root.cursor + ps_len; parser->num_dict = -1; /* Finally, we check whether `StartData' or `/sfnts' was real -- */ /* it could be in a comment or string. We also get the arguments */ /* of `StartData' to find out whether the data is represented in */ /* binary or hex format. */ arg1 = parser->root.cursor; cid_parser_skip_PS_token( parser ); cid_parser_skip_spaces ( parser ); arg2 = parser->root.cursor; cid_parser_skip_PS_token( parser ); cid_parser_skip_spaces ( parser ); limit = parser->root.limit; cur = parser->root.cursor; while ( cur < limit ) { if ( parser->root.error ) { error = parser->root.error; goto Exit; } if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) { if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) { FT_Long tmp = ft_atol( (const char *)arg2 ); if ( tmp < 0 ) { FT_ERROR(( "cid_parser_new: invalid length of hex data\n" )); error = FT_THROW( Invalid_File_Format ); } else parser->binary_length = (FT_ULong)tmp; } goto Exit; } else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 ) { FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" )); error = FT_THROW( Unknown_File_Format ); goto Exit; } cid_parser_skip_PS_token( parser ); cid_parser_skip_spaces ( parser ); arg1 = arg2; arg2 = cur; cur = parser->root.cursor; } /* we haven't found the correct `StartData'; go back and continue */ /* searching */ FT_FRAME_RELEASE( parser->postscript ); if ( !FT_STREAM_SEEK( offset ) ) goto Again; Exit: return error; }
cid_parser_new( CID_Parser* parser, FT_Stream stream, FT_Memory memory, PSAux_Service psaux ) { FT_Error error; FT_ULong base_offset, offset, ps_len; FT_Byte buffer[256 + 10]; FT_Int buff_len; FT_Byte *cur, *limit; FT_Byte *arg1, *arg2; FT_MEM_ZERO( parser, sizeof ( *parser ) ); psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); parser->stream = stream; base_offset = FT_STREAM_POS(); /* first of all, check the font format in the header */ if ( FT_FRAME_ENTER( 31 ) ) goto Exit; if ( ft_strncmp( (char *)stream->cursor, "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) ) { FT_TRACE2(( "[not a valid CID-keyed font]\n" )); error = CID_Err_Unknown_File_Format; } FT_FRAME_EXIT(); if ( error ) goto Exit; Again: /* now, read the rest of the file until we find a `StartData' */ buff_len = 256; for (;;) { FT_Byte* p; FT_ULong top_position; /* fill input buffer */ limit = buffer + 256; buff_len -= 256; if ( buff_len > 0 ) FT_MEM_MOVE( buffer, limit, buff_len ); p = buffer + buff_len; if ( FT_STREAM_READ( p, 256 + 10 - buff_len ) ) goto Exit; top_position = FT_STREAM_POS() - buff_len; buff_len = 256 + 10; /* look for `StartData' */ for ( p = buffer; p < limit; p++ ) { if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 ) { /* save offset of binary data after `StartData' */ offset = (FT_ULong)( top_position - ( limit - p ) + 10 ); goto Found; } } } Found: /* we have found the start of the binary data. We will now */ /* rewind and extract the frame corresponding to the PostScript */ /* section */ ps_len = offset - base_offset; if ( FT_STREAM_SEEK( base_offset ) || FT_FRAME_EXTRACT( ps_len, parser->postscript ) ) goto Exit; parser->data_offset = offset; parser->postscript_len = ps_len; parser->root.base = parser->postscript; parser->root.cursor = parser->postscript; parser->root.limit = parser->root.cursor + ps_len; parser->num_dict = -1; /* Finally, we check whether `StartData' was real -- it could be */ /* in a comment or string. We also get its arguments to find out */ /* whether the data is represented in binary or hex format. */ arg1 = parser->root.cursor; cid_parser_skip_PS_token( parser ); cid_parser_skip_spaces ( parser ); arg2 = parser->root.cursor; cid_parser_skip_PS_token( parser ); cid_parser_skip_spaces ( parser ); limit = parser->root.limit; cur = parser->root.cursor; while ( cur < limit ) { if ( parser->root.error ) break; if ( *cur == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) { if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) parser->binary_length = ft_atol( (const char *)arg2 ); limit = parser->root.limit; cur = parser->root.cursor; goto Exit; } cid_parser_skip_PS_token( parser ); cid_parser_skip_spaces ( parser ); arg1 = arg2; arg2 = cur; cur = parser->root.cursor; } /* we haven't found the correct `StartData'; go back and continue */ /* searching */ FT_FRAME_RELEASE( parser->postscript ); if ( !FT_STREAM_SEEK( offset ) ) goto Again; Exit: return error; }
cid_parser_new( CID_Parser* parser, FT_Stream stream, FT_Memory memory, PSAux_Service psaux ) { FT_Error error; FT_ULong base_offset, offset, ps_len; FT_Byte *cur, *limit; FT_Byte *arg1, *arg2; FT_ZERO( parser ); psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); parser->stream = stream; base_offset = FT_STREAM_POS(); /* first of all, check the font format in the header */ if ( FT_FRAME_ENTER( 31 ) ) goto Exit; if ( ft_strncmp( (char *)stream->cursor, "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) ) { FT_TRACE2(( " not a CID-keyed font\n" )); error = FT_THROW( Unknown_File_Format ); } FT_FRAME_EXIT(); if ( error ) goto Exit; Again: /* now, read the rest of the file until we find */ /* `StartData' or `/sfnts' */ { /* * The algorithm is as follows (omitting the case with less than 256 * bytes to fill for simplicity). * * 1. Fill the buffer with 256 + STARTDATA_LEN bytes. * * 2. Search for the STARTDATA and SFNTS strings at positions * buffer[0], buffer[1], ..., * buffer[255 + STARTDATA_LEN - SFNTS_LEN]. * * 3. Move the last STARTDATA_LEN bytes to buffer[0]. * * 4. Fill the buffer with 256 bytes, starting at STARTDATA_LEN. * * 5. Repeat with step 2. * */ FT_Byte buffer[256 + STARTDATA_LEN + 1]; /* values for the first loop */ FT_ULong read_len = 256 + STARTDATA_LEN; FT_ULong read_offset = 0; FT_Byte* p = buffer; for ( offset = FT_STREAM_POS(); ; offset += 256 ) { FT_ULong stream_len; stream_len = stream->size - FT_STREAM_POS(); read_len = FT_MIN( read_len, stream_len ); if ( FT_STREAM_READ( p, read_len ) ) goto Exit; /* ensure that we do not compare with data beyond the buffer */ p[read_len] = '\0'; limit = p + read_len - SFNTS_LEN; for ( p = buffer; p < limit; p++ ) { if ( p[0] == 'S' && ft_strncmp( (char*)p, STARTDATA, STARTDATA_LEN ) == 0 ) { /* save offset of binary data after `StartData' */ offset += (FT_ULong)( p - buffer ) + STARTDATA_LEN + 1; goto Found; } else if ( p[1] == 's' && ft_strncmp( (char*)p, SFNTS, SFNTS_LEN ) == 0 ) { offset += (FT_ULong)( p - buffer ) + SFNTS_LEN + 1; goto Found; } } if ( read_offset + read_len < STARTDATA_LEN ) { FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } FT_MEM_MOVE( buffer, buffer + read_offset + read_len - STARTDATA_LEN, STARTDATA_LEN ); /* values for the next loop */ read_len = 256; read_offset = STARTDATA_LEN; p = buffer + read_offset; } } Found: /* We have found the start of the binary data or the `/sfnts' token. */ /* Now rewind and extract the frame corresponding to this PostScript */ /* section. */ ps_len = offset - base_offset; if ( FT_STREAM_SEEK( base_offset ) || FT_FRAME_EXTRACT( ps_len, parser->postscript ) ) goto Exit; parser->data_offset = offset; parser->postscript_len = ps_len; parser->root.base = parser->postscript; parser->root.cursor = parser->postscript; parser->root.limit = parser->root.cursor + ps_len; parser->num_dict = -1; /* Finally, we check whether `StartData' or `/sfnts' was real -- */ /* it could be in a comment or string. We also get the arguments */ /* of `StartData' to find out whether the data is represented in */ /* binary or hex format. */ arg1 = parser->root.cursor; cid_parser_skip_PS_token( parser ); cid_parser_skip_spaces ( parser ); arg2 = parser->root.cursor; cid_parser_skip_PS_token( parser ); cid_parser_skip_spaces ( parser ); limit = parser->root.limit; cur = parser->root.cursor; while ( cur <= limit - SFNTS_LEN ) { if ( parser->root.error ) { error = parser->root.error; goto Exit; } if ( cur[0] == 'S' && cur <= limit - STARTDATA_LEN && ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 ) { if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) { FT_Long tmp = ft_strtol( (const char *)arg2, NULL, 10 ); if ( tmp < 0 ) { FT_ERROR(( "cid_parser_new: invalid length of hex data\n" )); error = FT_THROW( Invalid_File_Format ); } else parser->binary_length = (FT_ULong)tmp; } goto Exit; } else if ( cur[1] == 's' && ft_strncmp( (char*)cur, SFNTS, SFNTS_LEN ) == 0 ) { FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" )); error = FT_THROW( Unknown_File_Format ); goto Exit; } cid_parser_skip_PS_token( parser ); cid_parser_skip_spaces ( parser ); arg1 = arg2; arg2 = cur; cur = parser->root.cursor; } /* we haven't found the correct `StartData'; go back and continue */ /* searching */ FT_FRAME_RELEASE( parser->postscript ); if ( !FT_STREAM_SEEK( offset ) ) goto Again; Exit: return error; }