* ftmac.c: Import sfnt-wrapped Type1/CID font support
This commit is contained in:
parent
dec8e7b97d
commit
3afbee82fe
@ -1,3 +1,9 @@
|
||||
2008-09-19 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
|
||||
|
||||
* src/base/ftmac.c: Import sfnt-wrapped Type1 and sfnt-wrapped
|
||||
CID-keyed font support.
|
||||
* builds/mac/ftmac.c: Ditto.
|
||||
|
||||
2008-09-19 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
|
||||
|
||||
* src/base/ftobjs.c (Mac_Read_sfnt_Resource): Fix double free bug
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
107
src/base/ftmac.c
107
src/base/ftmac.c
@ -829,6 +829,59 @@
|
||||
}
|
||||
|
||||
|
||||
/* 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,
|
||||
@ -841,7 +894,7 @@
|
||||
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 );
|
||||
@ -858,17 +911,49 @@
|
||||
ft_memcpy( sfnt_data, *sfnt, sfnt_size );
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user