diff options
author | Suzuki, Toshiya (鈴木俊哉) <mpsuzuki@hiroshima-u.ac.jp> | 2008-09-19 17:46:01 +0000 |
---|---|---|
committer | Suzuki, Toshiya (鈴木俊哉) <mpsuzuki@hiroshima-u.ac.jp> | 2008-09-19 17:46:01 +0000 |
commit | 3afbee82fef0333f44e0d29d5ef48ecde535069d (patch) | |
tree | ad15a543b3900d3db50a421a50dcb1b304e478ec /builds | |
parent | dec8e7b97dd10e72890f785c98c9cd8fae8185b6 (diff) |
* ftmac.c: Import sfnt-wrapped Type1/CID font support
Diffstat (limited to 'builds')
-rw-r--r-- | builds/mac/ftmac.c | 107 |
1 files changed, 96 insertions, 11 deletions
diff --git a/builds/mac/ftmac.c b/builds/mac/ftmac.c index ef45dca9..24844344 100644 --- a/builds/mac/ftmac.c +++ b/builds/mac/ftmac.c @@ -1208,6 +1208,59 @@ typedef short ResourceIndex; } + /* Look up `TYP1' or `CID ' table from sfnt table directory. */ + /* offset & length must exclude the binary header in tables. */ + + /* For proper support, PS Type1 and CID-keyed font drivers */ + /* should recognize sfnt-wrapped format. Here, yet TrueType */ + /* font driver is not loaded, we must parse by ourselves. */ + /* We only care the name of table and offset. */ + + static FT_Error + ft_lookup_PS_in_sfnt( FT_Byte* sfnt, + 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 ); + + + 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 "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; + return FT_Err_Invalid_Table; + } + + /* Create a new FT_Face from an SFNT resource, specified by res ID. */ static FT_Error FT_New_Face_From_SFNT( FT_Library library, @@ -1220,7 +1273,7 @@ typedef short ResourceIndex; size_t sfnt_size; FT_Error error = FT_Err_Ok; FT_Memory memory = library->memory; - int is_cff; + int is_cff, is_sfnt_ps; sfnt = GetResource( FT_MAKE_TAG( 's', 'f', 'n', 't' ), sfnt_id ); @@ -1239,17 +1292,49 @@ typedef short ResourceIndex; HUnlock( sfnt ); ReleaseResource( sfnt ); - is_cff = sfnt_size > 4 && sfnt_data[0] == 'O' && - sfnt_data[1] == 'T' && - sfnt_data[2] == 'T' && - sfnt_data[3] == 'O'; + is_cff = sfnt_size > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 ); + is_sfnt_ps = sfnt_size > 4 && !ft_memcmp( sfnt_data, "typ1", 4 ); - return open_face_from_buffer( library, - sfnt_data, - sfnt_size, - face_index, - is_cff ? "cff" : "truetype", - aface ); + 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, + is_sfnt_cid ? "cid" : "type1", + aface ); + if ( !error ) + { + FT_FREE( sfnt_data ); + goto Exit; + } + } + Try_OpenType: + error = open_face_from_buffer( library, + sfnt_data, + sfnt_size, + face_index, + is_cff ? "cff" : "truetype", + aface ); + Exit: + return error; } |