summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Arnold <darnold@adobe.com>2016-10-18 21:20:19 -0700
committerDave Arnold <darnold@adobe.com>2016-10-18 21:20:19 -0700
commit54d9993505557af909d92291e1db549a2d4643e8 (patch)
tree9ce11ccbc27bb306519bd20d068f8bb7ea23368a
parent4c39089a4d4901950110067024663d7a8a833bb2 (diff)
downloadfreetype2-54d9993505557af909d92291e1db549a2d4643e8.tar.gz
Corrections to parse fonts following 1.8 spec.
INDEX count for CFF2 is 32 bits, while CFF is 16 bits This means INDEX header size is either 5 or 3 bytes. CFF2 header size is 5 bytes, while CFF is 4 bytes. In CFF2, offSize field is length of the Top DICT data and is 16 bits. Blend operator has changed from 31 to 23.
-rw-r--r--src/cff/cffload.c63
-rw-r--r--src/cff/cfftoken.h2
-rw-r--r--src/cff/cfftypes.h4
3 files changed, 45 insertions, 24 deletions
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index 1342368e6..112a02107 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -225,19 +225,33 @@
static FT_Error
cff_index_init( CFF_Index idx,
FT_Stream stream,
- FT_Bool load )
+ FT_Bool load,
+ FT_Bool cff2 )
{
FT_Error error;
FT_Memory memory = stream->memory;
- FT_UShort count;
+ FT_UInt count;
FT_MEM_ZERO( idx, sizeof ( *idx ) );
idx->stream = stream;
idx->start = FT_STREAM_POS();
- if ( !FT_READ_USHORT( count ) &&
- count > 0 )
+
+ if ( cff2 )
+ {
+ if ( FT_READ_ULONG( count ) )
+ goto Exit;
+ idx->hdr_size = 5;
+ }
+ else
+ {
+ if ( FT_READ_USHORT( count ) )
+ goto Exit;
+ idx->hdr_size = 3;
+ }
+
+ if ( count > 0 )
{
FT_Byte offsize;
FT_ULong size;
@@ -258,7 +272,7 @@
idx->off_size = offsize;
size = (FT_ULong)( count + 1 ) * offsize;
- idx->data_offset = idx->start + 3 + size;
+ idx->data_offset = idx->start + idx->hdr_size + size;
if ( FT_STREAM_SKIP( size - offsize ) )
goto Exit;
@@ -335,7 +349,7 @@
data_size = (FT_ULong)( idx->count + 1 ) * offsize;
if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||
- FT_STREAM_SEEK( idx->start + 3 ) ||
+ FT_STREAM_SEEK( idx->start + idx->hdr_size ) ||
FT_FRAME_ENTER( data_size ) )
goto Exit;
@@ -493,7 +507,7 @@
FT_ULong pos = element * idx->off_size;
- if ( FT_STREAM_SEEK( idx->start + 3 + pos ) )
+ if ( FT_STREAM_SEEK( idx->start + idx->hdr_size + pos ) )
goto Exit;
off1 = cff_index_read_offset( idx, &error );
@@ -1478,6 +1492,7 @@
FT_ULong dict_len;
CFF_FontRecDict top = &font->font_dict;
CFF_Private priv = &font->private_dict;
+ FT_Bool cff2 = (code == CFF2_CODE_TOPDICT );
cff_parser_init( &parser,
@@ -1582,7 +1597,7 @@
priv->local_subrs_offset ) )
goto Exit;
- error = cff_index_init( &font->local_subrs_index, stream, 1 );
+ error = cff_index_init( &font->local_subrs_index, stream, 1, cff2 );
if ( error )
goto Exit;
@@ -1622,11 +1637,10 @@
#undef FT_STRUCTURE
#define FT_STRUCTURE CFF_FontRec
- FT_FRAME_START( 4 ),
+ FT_FRAME_START( 3 ),
FT_FRAME_BYTE( version_major ),
FT_FRAME_BYTE( version_minor ),
FT_FRAME_BYTE( header_size ),
- FT_FRAME_BYTE( absolute_offsize ),
FT_FRAME_END
};
@@ -1653,16 +1667,21 @@
/* check format */
if ( font->version_major != ( cff2 ? 2 : 1 ) ||
- font->header_size < 4 ||
- ( !cff2 && font->absolute_offsize > 4 ) )
+ font->header_size < 4 )
{
FT_TRACE2(( " not a CFF font header\n" ));
error = FT_THROW( Unknown_File_Format );
goto Exit;
}
+ if ( cff2 )
+ {
+ if ( FT_READ_USHORT( font->top_dict_length ) )
+ goto Exit;
+ }
+
/* skip the rest of the header */
- if ( FT_STREAM_SKIP( font->header_size - 4 ) )
+ if ( FT_STREAM_SEEK( base_offset + font->header_size ) )
goto Exit;
if ( cff2 )
@@ -1674,28 +1693,28 @@
/* length of data, but leave count at zero as an indicator */
FT_ZERO( &font->font_dict_index );
font->font_dict_index.data_offset = FT_STREAM_POS();
- font->font_dict_index.data_size = font->absolute_offsize;
+ font->font_dict_index.data_size = font->top_dict_length;
/* skip the top dict data for now, we'll parse it later */
- if ( FT_STREAM_SKIP( font->absolute_offsize ) )
+ if ( FT_STREAM_SKIP( font->top_dict_length ) )
goto Exit;
/* next, read the global subrs index */
if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
- stream, 1 ) ) )
+ stream, 1, cff2 ) ) )
goto Exit;
}
else
{
/* for CFF, read the name, top dict, string and global subrs index */
if ( FT_SET_ERROR( cff_index_init( &font->name_index,
- stream, 0 ) ) ||
+ stream, 0, cff2 ) ) ||
FT_SET_ERROR( cff_index_init( &font->font_dict_index,
- stream, 0 ) ) ||
+ stream, 0, cff2 ) ) ||
FT_SET_ERROR( cff_index_init( &string_index,
- stream, 1 ) ) ||
+ stream, 1, cff2 ) ) ||
FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
- stream, 1 ) ) ||
+ stream, 1, cff2 ) ) ||
FT_SET_ERROR( cff_index_get_pointers( &string_index,
&font->strings,
&font->string_pool,
@@ -1755,7 +1774,7 @@
if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
goto Exit;
- error = cff_index_init( &font->charstrings_index, stream, 0 );
+ error = cff_index_init( &font->charstrings_index, stream, 0, cff2 );
if ( error )
goto Exit;
@@ -1773,7 +1792,7 @@
if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
goto Exit;
- error = cff_index_init( &fd_index, stream, 0 );
+ error = cff_index_init( &fd_index, stream, 0, cff2 );
if ( error )
goto Exit;
diff --git a/src/cff/cfftoken.h b/src/cff/cfftoken.h
index c6712daf7..a1b8ae664 100644
--- a/src/cff/cfftoken.h
+++ b/src/cff/cfftoken.h
@@ -144,7 +144,7 @@
CFF_FIELD_NUM ( 0x111, language_group, "LanguageGroup" )
CFF_FIELD_FIXED ( 0x112, expansion_factor, "ExpansionFactor" )
CFF_FIELD_NUM ( 22, vsindex, "vsindex" )
- CFF_FIELD_BLEND ( 31, "blend" )
+ CFF_FIELD_BLEND ( 23, "blend" )
CFF_FIELD_NUM ( 19, local_subrs_offset, "Subrs" )
diff --git a/src/cff/cfftypes.h b/src/cff/cfftypes.h
index 379c1d056..c6ed4df19 100644
--- a/src/cff/cfftypes.h
+++ b/src/cff/cfftypes.h
@@ -64,6 +64,7 @@ FT_BEGIN_HEADER
{
FT_Stream stream;
FT_ULong start;
+ FT_UInt hdr_size;
FT_UInt count;
FT_Byte off_size;
FT_ULong data_offset;
@@ -272,7 +273,8 @@ FT_BEGIN_HEADER
FT_Byte version_major;
FT_Byte version_minor;
FT_Byte header_size;
- FT_Byte absolute_offsize; /* cff2_top_dict_length */
+
+ FT_UInt top_dict_length; /* cff2 only */
FT_Bool cff2;