|
|
|
@ -47,6 +47,12 @@ |
|
|
|
|
/*************************************************************************/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define STARTDATA "StartData" |
|
|
|
|
#define STARTDATA_LEN ( sizeof ( STARTDATA ) - 1 ) |
|
|
|
|
#define SFNTS "/sfnts" |
|
|
|
|
#define SFNTS_LEN ( sizeof ( SFNTS ) - 1 ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_LOCAL_DEF( FT_Error ) |
|
|
|
|
cid_parser_new( CID_Parser* parser, |
|
|
|
|
FT_Stream stream, |
|
|
|
@ -85,9 +91,29 @@ |
|
|
|
|
/* 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; |
|
|
|
|
/*
|
|
|
|
|
* 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 ) |
|
|
|
@ -96,40 +122,48 @@ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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'; |
|
|
|
|
/* ensure that we do not compare with data beyond the buffer */ |
|
|
|
|
p[read_len] = '\0'; |
|
|
|
|
|
|
|
|
|
limit = p + read_len - 10; |
|
|
|
|
limit = p + read_len - SFNTS_LEN; |
|
|
|
|
|
|
|
|
|
for ( p = buffer; p < limit; p++ ) |
|
|
|
|
{ |
|
|
|
|
if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 ) |
|
|
|
|
if ( p[0] == 'S' && |
|
|
|
|
ft_strncmp( (char*)p, STARTDATA, STARTDATA_LEN ) == 0 ) |
|
|
|
|
{ |
|
|
|
|
/* save offset of binary data after `StartData' */ |
|
|
|
|
offset += (FT_ULong)( p - buffer + 10 ); |
|
|
|
|
offset += (FT_ULong)( p - buffer ) + STARTDATA_LEN; |
|
|
|
|
goto Found; |
|
|
|
|
} |
|
|
|
|
else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 ) |
|
|
|
|
else if ( p[1] == 's' && |
|
|
|
|
ft_strncmp( (char*)p, SFNTS, SFNTS_LEN ) == 0 ) |
|
|
|
|
{ |
|
|
|
|
offset += (FT_ULong)( p - buffer + 7 ); |
|
|
|
|
offset += (FT_ULong)( p - buffer ) + SFNTS_LEN; |
|
|
|
|
goto Found; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
FT_MEM_MOVE( buffer, p, 10 ); |
|
|
|
|
read_len = 256; |
|
|
|
|
p = buffer + 10; |
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -165,7 +199,7 @@ |
|
|
|
|
limit = parser->root.limit; |
|
|
|
|
cur = parser->root.cursor; |
|
|
|
|
|
|
|
|
|
while ( cur < limit ) |
|
|
|
|
while ( cur < limit - SFNTS_LEN ) |
|
|
|
|
{ |
|
|
|
|
if ( parser->root.error ) |
|
|
|
|
{ |
|
|
|
@ -173,7 +207,9 @@ |
|
|
|
|
goto Exit; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) |
|
|
|
|
if ( cur[0] == 'S' && |
|
|
|
|
cur < limit - STARTDATA_LEN && |
|
|
|
|
ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 ) |
|
|
|
|
{ |
|
|
|
|
if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) |
|
|
|
|
{ |
|
|
|
@ -191,7 +227,8 @@ |
|
|
|
|
|
|
|
|
|
goto Exit; |
|
|
|
|
} |
|
|
|
|
else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 ) |
|
|
|
|
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 ); |
|
|
|
@ -216,6 +253,12 @@ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#undef STARTDATA |
|
|
|
|
#undef STARTDATA_LEN |
|
|
|
|
#undef SFNTS |
|
|
|
|
#undef SFNTS_LEN |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_LOCAL_DEF( void ) |
|
|
|
|
cid_parser_done( CID_Parser* parser ) |
|
|
|
|
{ |
|
|
|
|