* New function `open_face_PS_from_sfnt_stream' to check and open a Type1 PS or CID-keyed font in an sfnt stream.

This commit is contained in:
Suzuki, Toshiya (鈴木俊哉) 2008-10-04 07:11:58 +00:00
parent bc2c498419
commit 1137d04f85
5 changed files with 163 additions and 123 deletions

View File

@ -1,3 +1,19 @@
2008-10-04 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
* 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 <mpsuzuki@hiroshima-u.ac.jp>
* src/base/ftobjs.c (ft_lookup_PS_in_sfnt): Set *is_sfnt_cid

View File

@ -1142,34 +1142,26 @@ typedef short ResourceIndex;
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,

View File

@ -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. */

View File

@ -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,

View File

@ -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 */
for ( ; numTables > 0 ; numTables -- )
{
FT_ULong tag = FT_NEXT_ULONG( p );
p += 4; /* skip checkSum */
*offset = FT_NEXT_ULONG( p );
*length = FT_NEXT_ULONG( p );
/* see Adobe TN# 5180 for binary header in CID table */
if ( tag == FT_MAKE_TAG( 'C', 'I', 'D', ' ' ) )
{
*offset += 22;
*length -= 22;
*is_sfnt_cid = TRUE;
return FT_Err_Ok;
}
/* see Apple's `The Type 1 GX Font Format' */
if ( tag == FT_MAKE_TAG( 'T', 'Y', 'P', '1' ) )
{
*offset += 24;
*length -= 24;
*is_sfnt_cid = FALSE;
return FT_Err_Ok;
}
}
*offset = 0;
*length = 0;
*is_sfnt_cid = TRUE;
/* TODO: support for sfnt-wrapped PS/CID in TTC format */
*is_sfnt_cid = FALSE;
return FT_Err_Invalid_Table;
/* 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;
if ( FT_READ_USHORT( numTables ) )
return error;
if ( FT_STREAM_SKIP( 2 * 3 ) ) /* skip binary search header */
return error;
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;
if ( face_index < 0 )
return FT_Err_Ok;
}
else if ( tag == FT_MAKE_TAG( 'T', 'Y', 'P', '1' ) )
{
pstable_index ++;
*offset += 24;
*length -= 24;
*is_sfnt_cid = FALSE;
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;
}
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,48 +1593,21 @@
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 );
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,