ref: 1137d04f85079ff3b96b148ebcfed39690fdb09e
parent: bc2c49841908f8716c1adae3cbdcad647f8d5301
author: Suzuki, Toshiya (鈴木俊哉) <[email protected]>
date: Sat Oct 4 03:11:58 EDT 2008
* New function `open_face_PS_from_sfnt_stream' to check and open a Type1 PS or CID-keyed font in an sfnt stream.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2008-10-04 suzuki toshiya <[email protected]>
+
+ * src/base/ftobjs.c (ft_lookup_PS_in_sfnt): Replaced by...
+ (ft_lookup_PS_in_sfnt_stream): This.
+ (open_face_PS_from_sfnt_stream): New function. It checks
+ whether the stream is sfnt-wrapped Type1 PS font or sfnt-
+ wrapped CID-keyed font, then try to open a face for given
+ face_index.
+ (Mac_Read_sfnt_Resource): Replace the combination of
+ `ft_lookup_PS_in_sfnt' and `open_face_from_buffer' by
+ `open_face_PS_from_sfnt_stream'.
+ * src/base/ftmac.c (FT_New_Face_From_SFNT): Ditto.
+ * builds/mac/ftmac.c (FT_New_Face_From_SFNT): Ditto.
+ * src/base/ftbase.h: Remove `ft_lookup_PS_in_sfnt' and add
+ `open_face_PS_from_sfnt_stream'.
+
2008-10-03 suzuki toshiya <[email protected]>
* src/base/ftobjs.c (ft_lookup_PS_in_sfnt): Set *is_sfnt_cid
--- a/builds/mac/ftmac.c
+++ b/builds/mac/ftmac.c
@@ -1142,34 +1142,26 @@
if ( is_sfnt_ps )
{
- FT_ULong offset, length;
- FT_Bool is_sfnt_cid;
- FT_Byte* sfnt_ps;
+ FT_Stream stream;
- error = ft_lookup_PS_in_sfnt( sfnt_data,
- &offset,
- &length,
- &is_sfnt_cid );
- if ( error )
+ if ( FT_NEW( stream ) )
goto Try_OpenType;
-
- if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) )
- return error;
- ft_memcpy( sfnt_ps, sfnt_data + offset, length );
-
- error = open_face_from_buffer( library,
- sfnt_ps,
- length,
- face_index,
- is_sfnt_cid ? "cid" : "type1",
- aface );
- if ( !error )
+ FT_Stream_OpenMemory( stream, sfnt_data, sfnt_size );
+ if ( !open_face_PS_from_sfnt_stream( library,
+ stream,
+ face_index,
+ 0, NULL,
+ aface ) )
{
+ FT_Stream_Close( stream );
+ FT_FREE( stream );
FT_FREE( sfnt_data );
goto Exit;
}
+
+ FT_FREE( stream );
}
Try_OpenType:
error = open_face_from_buffer( library,
--- a/src/base/ftbase.h
+++ b/src/base/ftbase.h
@@ -27,14 +27,16 @@
FT_BEGIN_HEADER
- /* Check whether the sfnt image in the buffer is sfnt-wrapped PS Type1 */
- /* or sfnt-wrapped CID-keyed font. */
+ /* Assume the stream is sfnt-wrapped PS Type1 or sfnt-wrapped CID-keyed */
+ /* font, and try to load a face specified by the face_index. */
FT_LOCAL_DEF( FT_Error )
- ft_lookup_PS_in_sfnt( FT_Byte* sfnt,
- FT_ULong* offset,
- FT_ULong* length,
- FT_Bool* is_sfnt_cid );
-
+ open_face_PS_from_sfnt_stream( FT_Library library,
+ FT_Stream stream,
+ FT_Long face_index,
+ FT_Int num_params,
+ FT_Parameter *params,
+ FT_Face *aface );
+
/* Create a new FT_Face given a buffer and a driver name. */
/* From ftmac.c. */
--- a/src/base/ftmac.c
+++ b/src/base/ftmac.c
@@ -761,36 +761,27 @@
if ( is_sfnt_ps )
{
- FT_ULong offset, length;
- FT_Bool is_sfnt_cid;
- FT_Byte* sfnt_ps;
+ FT_Stream stream;
- error = ft_lookup_PS_in_sfnt( sfnt_data,
- &offset,
- &length,
- &is_sfnt_cid );
- if ( error )
+ if ( FT_NEW( stream ) )
goto Try_OpenType;
-
- if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) )
- return error;
- ft_memcpy( sfnt_ps, sfnt_data + offset, length );
-
- error = open_face_from_buffer( library,
- sfnt_ps,
- length,
- face_index,
- is_sfnt_cid ? "cid" : "type1",
- aface );
- if ( !error )
+ FT_Stream_OpenMemory( stream, sfnt_data, sfnt_size );
+ if ( !open_face_PS_from_sfnt_stream( library,
+ stream,
+ face_index,
+ 0, NULL,
+ aface ) )
{
+ FT_Stream_Close( stream );
+ FT_FREE( stream );
FT_FREE( sfnt_data );
goto Exit;
}
- }
+ FT_FREE( stream );
+ }
Try_OpenType:
error = open_face_from_buffer( library,
sfnt_data,
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -1323,50 +1323,117 @@
/* ourselves. We are only interested in the name of the table and */
/* the offset. */
- FT_LOCAL_DEF( FT_Error )
- ft_lookup_PS_in_sfnt( FT_Byte* sfnt,
- FT_ULong* offset,
- FT_ULong* length,
- FT_Bool* is_sfnt_cid )
+ static FT_Error
+ ft_lookup_PS_in_sfnt_stream( FT_Stream stream,
+ FT_Long face_index,
+ FT_ULong* offset,
+ FT_ULong* length,
+ FT_Bool* is_sfnt_cid )
{
- FT_Byte* p = sfnt + 4; /* skip version `typ1' */
- FT_UShort numTables = FT_NEXT_USHORT( p );
+ FT_Error error;
+ FT_UShort numTables;
+ FT_Long pstable_index;
+ FT_ULong tag;
+ int i;
- p += 2 * 3; /* skip binary search header */
+ *offset = 0;
+ *length = 0;
+ *is_sfnt_cid = TRUE;
+ /* TODO: support for sfnt-wrapped PS/CID in TTC format */
+ *is_sfnt_cid = FALSE;
- for ( ; numTables > 0 ; numTables -- )
- {
- FT_ULong tag = FT_NEXT_ULONG( p );
+ /* version check for 'typ1' (should be ignored?) */
+ if ( FT_READ_ULONG( tag ) )
+ return error;
+ if ( tag != FT_MAKE_TAG( 't', 'y', 'p', '1' ) )
+ return FT_Err_Unknown_File_Format;
- p += 4; /* skip checkSum */
- *offset = FT_NEXT_ULONG( p );
- *length = FT_NEXT_ULONG( p );
+ if ( FT_READ_USHORT( numTables ) )
+ return error;
+ if ( FT_STREAM_SKIP( 2 * 3 ) ) /* skip binary search header */
+ return error;
- /* see Adobe TN# 5180 for binary header in CID table */
+
+ pstable_index = -1;
+ *is_sfnt_cid = FALSE;
+ for ( i = 0; i < numTables; i ++ )
+ {
+ if ( FT_READ_ULONG( tag ) || FT_STREAM_SKIP( 4 ) ||
+ FT_READ_ULONG( *offset ) || FT_READ_ULONG( *length ) )
+ return error;
+
if ( tag == FT_MAKE_TAG( 'C', 'I', 'D', ' ' ) )
{
+ pstable_index ++;
*offset += 22;
*length -= 22;
*is_sfnt_cid = TRUE;
- return FT_Err_Ok;
+ if ( face_index < 0 )
+ return FT_Err_Ok;
}
-
- /* see Apple's `The Type 1 GX Font Format' */
- if ( tag == FT_MAKE_TAG( 'T', 'Y', 'P', '1' ) )
+ else if ( tag == FT_MAKE_TAG( 'T', 'Y', 'P', '1' ) )
{
+ pstable_index ++;
*offset += 24;
*length -= 24;
*is_sfnt_cid = FALSE;
- return FT_Err_Ok;
+ if ( face_index < 0 )
+ return FT_Err_Ok;
}
+ if ( face_index >= 0 && pstable_index == face_index )
+ return FT_Err_Ok;
}
+ return FT_Err_Table_Missing;
+ }
- *offset = 0;
- *length = 0;
- *is_sfnt_cid = FALSE;
- return FT_Err_Invalid_Table;
+
+ FT_LOCAL_DEF( FT_Error )
+ open_face_PS_from_sfnt_stream( FT_Library library,
+ FT_Stream stream,
+ FT_Long face_index,
+ FT_Int num_params,
+ FT_Parameter *params,
+ FT_Face *aface )
+ {
+ FT_Error error;
+ FT_Memory memory = library->memory;
+ FT_ULong offset, length;
+ FT_Long pos;
+ FT_Bool is_sfnt_cid;
+ FT_Byte* sfnt_ps;
+
+
+ pos = FT_Stream_Pos( stream );
+
+ error = ft_lookup_PS_in_sfnt_stream( stream,
+ face_index,
+ &offset,
+ &length,
+ &is_sfnt_cid );
+ if ( error )
+ return error;
+
+ if ( FT_Stream_Seek( stream, pos + offset ) )
+ goto Exit;
+
+ if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) )
+ goto Exit;
+
+ error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length );
+ if ( error )
+ goto Exit;
+
+ error = open_face_from_buffer( library,
+ sfnt_ps,
+ length,
+ face_index < 0 ? face_index : 0,
+ is_sfnt_cid ? "cid" : "type1",
+ aface );
+ Exit:
+ FT_Stream_Seek( stream, pos );
+ return error;
}
@@ -1508,7 +1575,6 @@
FT_Long flag_offset;
FT_Long rlen;
int is_cff;
- int is_sfnt_ps;
FT_Long face_index_in_resource = 0;
@@ -1527,6 +1593,14 @@
if ( rlen == -1 )
return FT_Err_Cannot_Open_Resource;
+ error = open_face_PS_from_sfnt_stream( library,
+ stream,
+ face_index,
+ 0, NULL,
+ aface );
+ if ( !error )
+ goto Exit;
+
if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) )
return error;
error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen );
@@ -1533,42 +1607,7 @@
if ( error )
goto Exit;
- is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );
- is_sfnt_ps = rlen > 4 && !ft_memcmp( sfnt_data, "typ1", 4 );
-
- if ( is_sfnt_ps )
- {
- FT_ULong offset, length;
- FT_Bool is_sfnt_cid;
- FT_Byte* sfnt_ps;
-
-
- error = ft_lookup_PS_in_sfnt( sfnt_data,
- &offset,
- &length,
- &is_sfnt_cid );
- if ( error )
- goto Try_OpenType;
-
-
- if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) )
- return error;
- ft_memcpy( sfnt_ps, sfnt_data + offset, length );
-
- error = open_face_from_buffer( library,
- sfnt_ps,
- length,
- face_index_in_resource,
- is_sfnt_cid ? "cid" : "type1",
- aface );
- if ( !error )
- {
- FT_FREE( sfnt_data );
- goto Exit;
- }
- }
-
- Try_OpenType:
+ is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );
error = open_face_from_buffer( library,
sfnt_data,
rlen,