forked from minhngoc25a/freetype2
* src/raster/ftraster.c (Insert_Y_Turn): Fix overflow test.
* include/freetype/config/ftoption.h [FT_CONFIG_OPTION_MAC_FONTS]: New macro. * src/base/ftobjs.c: Use it to control mac font support on non-mac platforms. Implement partial support of Mac fonts on non-Mac platforms. * src/base/ftobjs.c (memory_stream_close, new_memory_stream, open_face_from_buffer, Mac_Read_POST_Resource, Mac_Read_sfnt_Resource, IsMacResource, IsMacBinary, load_mac_face) [!FT_MACINTOSH]: New functions. (FT_Open_Face) [!FT_MACINTOSH]: Use load_mac_face. * src/base/ftobjs.c (FT_Load_Glyph): Scale linear advance width only if FT_FACE_FLAG_SCALABLE is set (otherwise we have a division by zero since FNT and friends don't define `face->units_per_EM').
This commit is contained in:
parent
4f107450e2
commit
51daa4feb1
27
ChangeLog
27
ChangeLog
|
@ -1,3 +1,30 @@
|
|||
2003-05-18 Yong Sun <sunyong@njstar.com>
|
||||
|
||||
* src/raster/ftraster.c (Insert_Y_Turn): Fix overflow test.
|
||||
|
||||
2003-05-18 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* include/freetype/config/ftoption.h [FT_CONFIG_OPTION_MAC_FONTS]:
|
||||
New macro.
|
||||
* src/base/ftobjs.c: Use it to control mac font support on non-mac
|
||||
platforms.
|
||||
|
||||
2003-05-17 George Williams <gww@silcom.com>
|
||||
|
||||
Implement partial support of Mac fonts on non-Mac platforms.
|
||||
|
||||
* src/base/ftobjs.c (memory_stream_close, new_memory_stream,
|
||||
open_face_from_buffer, Mac_Read_POST_Resource,
|
||||
Mac_Read_sfnt_Resource, IsMacResource, IsMacBinary, load_mac_face)
|
||||
[!FT_MACINTOSH]: New functions.
|
||||
(FT_Open_Face) [!FT_MACINTOSH]: Use load_mac_face.
|
||||
|
||||
2003-05-17 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* src/base/ftobjs.c (FT_Load_Glyph): Scale linear advance width only
|
||||
if FT_FACE_FLAG_SCALABLE is set (otherwise we have a division by
|
||||
zero since FNT and friends don't define `face->units_per_EM').
|
||||
|
||||
2003-05-15 David Turner <david@freetype.org>
|
||||
|
||||
* src/base/fttrigon.c (FT_Vector_Rotate): Avoid rounding errors
|
||||
|
|
|
@ -217,6 +217,19 @@ FT_BEGIN_HEADER
|
|||
#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Support for Mac fonts */
|
||||
/* */
|
||||
/* Define this macro if you want support for outline fonts in Mac */
|
||||
/* format (mac dfont, mac resource, macbinary containing a mac */
|
||||
/* resource) on non-Mac platforms. */
|
||||
/* */
|
||||
/* Note that the `FOND' resource isn't checked. */
|
||||
/* */
|
||||
#define FT_CONFIG_OPTION_MAC_FONTS
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Allow the use of FT_Incremental_Interface to load typefaces that */
|
||||
|
|
|
@ -204,8 +204,8 @@
|
|||
if ( slot->flags & FT_GLYPH_OWN_BITMAP )
|
||||
{
|
||||
FT_Memory memory = FT_FACE_MEMORY( slot->face );
|
||||
|
||||
|
||||
|
||||
|
||||
FT_FREE( slot->bitmap.buffer );
|
||||
slot->flags &= ~FT_GLYPH_OWN_BITMAP;
|
||||
}
|
||||
|
@ -223,11 +223,11 @@
|
|||
FT_Byte* buffer )
|
||||
{
|
||||
ft_glyphslot_free_bitmap( slot );
|
||||
|
||||
|
||||
slot->bitmap.buffer = buffer;
|
||||
|
||||
|
||||
FT_ASSERT( (slot->flags & FT_GLYPH_OWN_BITMAP) == 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
|
@ -235,15 +235,15 @@
|
|||
FT_ULong size )
|
||||
{
|
||||
FT_Memory memory = FT_FACE_MEMORY( slot->face );
|
||||
|
||||
|
||||
|
||||
|
||||
if ( slot->flags & FT_GLYPH_OWN_BITMAP )
|
||||
FT_FREE( slot->bitmap.buffer );
|
||||
else
|
||||
slot->flags |= FT_GLYPH_OWN_BITMAP;
|
||||
|
||||
|
||||
return FT_MEM_ALLOC( slot->bitmap.buffer, size );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
|
@ -561,7 +561,8 @@
|
|||
}
|
||||
|
||||
/* compute the linear advance in 16.16 pixels */
|
||||
if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 )
|
||||
if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 &&
|
||||
( face->face_flags & FT_FACE_FLAG_SCALABLE ) )
|
||||
{
|
||||
FT_UInt EM = face->units_per_EM;
|
||||
FT_Size_Metrics* metrics = &face->size->metrics;
|
||||
|
@ -977,6 +978,580 @@
|
|||
}
|
||||
|
||||
|
||||
#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS )
|
||||
|
||||
/* The behavior here is very similar to that in base/ftmac.c, but it */
|
||||
/* is designed to work on non-mac systems, so no mac specific calls. */
|
||||
/* */
|
||||
/* We look at the file and determine if it is a mac dfont file or a mac */
|
||||
/* resource file, or a macbinary file containing a mac resource file. */
|
||||
/* */
|
||||
/* Unlike ftmac I'm not going to look at a `FOND'. I don't really see */
|
||||
/* the point, especially since there may be multiple `FOND' resources. */
|
||||
/* Instead I'll just look for `sfnt' and `POST' resources, ordered as */
|
||||
/* they occur in the file. */
|
||||
/* */
|
||||
/* Note that multiple `POST' resources do not mean multiple postscript */
|
||||
/* fonts; they all get jammed together to make what is essentially a */
|
||||
/* pfb file. */
|
||||
/* */
|
||||
/* We aren't interested in `NFNT' or `FONT' bitmap resources. */
|
||||
/* */
|
||||
/* As soon as we get an `sfnt' load it into memory and pass it off to */
|
||||
/* FT_Open_Face. */
|
||||
/* */
|
||||
/* If we have a (set of) `POST' resources, massage them into a (memory) */
|
||||
/* pfb file and pass that to FT_Open_Face. (As with ftmac.c I'm not */
|
||||
/* going to try to save the kerning info. After all that lives in the */
|
||||
/* `FOND' which isn't in the file containing the `POST' resources so */
|
||||
/* we don't really have access to it. */
|
||||
|
||||
|
||||
/* Finalizer for a memory stream; gets called by FT_Done_Face().
|
||||
It frees the memory it uses. */
|
||||
/* from ftmac.c */
|
||||
static void
|
||||
memory_stream_close( FT_Stream stream )
|
||||
{
|
||||
FT_Memory memory = stream->memory;
|
||||
|
||||
|
||||
FT_FREE( stream->base );
|
||||
|
||||
stream->size = 0;
|
||||
stream->base = 0;
|
||||
stream->close = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new memory stream from a buffer and a size. */
|
||||
/* from ftmac.c */
|
||||
static FT_Error
|
||||
new_memory_stream( FT_Library library,
|
||||
FT_Byte* base,
|
||||
FT_ULong size,
|
||||
FT_Stream_CloseFunc close,
|
||||
FT_Stream *astream )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory;
|
||||
FT_Stream stream;
|
||||
|
||||
|
||||
if ( !library )
|
||||
return FT_Err_Invalid_Library_Handle;
|
||||
|
||||
if ( !base )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
*astream = 0;
|
||||
memory = library->memory;
|
||||
if ( FT_NEW( stream ) )
|
||||
goto Exit;
|
||||
|
||||
FT_Stream_OpenMemory( stream, base, size );
|
||||
|
||||
stream->close = close;
|
||||
|
||||
*astream = stream;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new FT_Face given a buffer and a driver name. */
|
||||
/* from ftmac.c */
|
||||
static FT_Error
|
||||
open_face_from_buffer( FT_Library library,
|
||||
FT_Byte* base,
|
||||
FT_ULong size,
|
||||
FT_Long face_index,
|
||||
const char* driver_name,
|
||||
FT_Face *aface )
|
||||
{
|
||||
FT_Open_Args args;
|
||||
FT_Error error;
|
||||
FT_Stream stream;
|
||||
FT_Memory memory = library->memory;
|
||||
|
||||
|
||||
error = new_memory_stream( library,
|
||||
base,
|
||||
size,
|
||||
memory_stream_close,
|
||||
&stream );
|
||||
if ( error )
|
||||
{
|
||||
FT_FREE( base );
|
||||
return error;
|
||||
}
|
||||
|
||||
args.flags = FT_OPEN_STREAM;
|
||||
args.stream = stream;
|
||||
if ( driver_name )
|
||||
{
|
||||
args.flags = args.flags | FT_OPEN_DRIVER;
|
||||
args.driver = FT_Get_Module( library, driver_name );
|
||||
}
|
||||
|
||||
error = FT_Open_Face( library, &args, face_index, aface );
|
||||
|
||||
if ( error == FT_Err_Ok )
|
||||
(*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
|
||||
else
|
||||
{
|
||||
FT_Stream_Close( stream );
|
||||
FT_FREE( stream );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* The resource header says we've got resource_cnt `POST' (type1) */
|
||||
/* resources in this file. They all need to be coalesced into */
|
||||
/* one lump which gets passed on to the type1 driver. */
|
||||
/* Here can be only one PostScript font in a file so face_index */
|
||||
/* must be 0 (or -1). */
|
||||
/* */
|
||||
static FT_Error
|
||||
Mac_Read_POST_Resource( FT_Library library,
|
||||
FT_Stream stream,
|
||||
FT_Long resource_listoffset,
|
||||
FT_Long resource_cnt,
|
||||
FT_Long resource_data,
|
||||
FT_Long face_index,
|
||||
FT_Face *aface )
|
||||
{
|
||||
FT_Error error = FT_Err_Cannot_Open_Resource;
|
||||
FT_Memory memory = library->memory;
|
||||
FT_Byte* pfb_data;
|
||||
int i, type, flags, len;
|
||||
FT_Long pfb_len, pfb_pos, pfb_lenpos;
|
||||
FT_Long rlen, junk, temp;
|
||||
FT_Long *offsets;
|
||||
|
||||
|
||||
if ( face_index == -1 )
|
||||
face_index = 0;
|
||||
if ( face_index != 0 )
|
||||
return FT_Err_Cannot_Open_Resource;
|
||||
|
||||
if ( FT_ALLOC( offsets, (FT_Long)resource_cnt * sizeof ( FT_Long ) ) )
|
||||
return error;
|
||||
|
||||
error = FT_Stream_Seek( stream, resource_listoffset );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* Find all the POST resource offsets */
|
||||
for ( i = 0; i < resource_cnt; ++i )
|
||||
{
|
||||
(void)FT_READ_USHORT( junk ); /* resource id */
|
||||
(void)FT_READ_USHORT( junk ); /* rsource name */
|
||||
if ( FT_READ_LONG( temp ) )
|
||||
goto Exit;
|
||||
offsets[i] = resource_data + ( temp & 0xFFFFFFL );
|
||||
(void)FT_READ_LONG( junk ); /* mbz */
|
||||
}
|
||||
|
||||
/* Find the length of all the POST resources, concatenated. Assume */
|
||||
/* worst case (each resource in its own section). */
|
||||
pfb_len = 0;
|
||||
for ( i = 0; i < resource_cnt; ++i )
|
||||
{
|
||||
error = FT_Stream_Seek( stream, offsets[i] );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
if ( FT_READ_LONG( temp ) )
|
||||
goto Exit;
|
||||
pfb_len += temp + 6;
|
||||
}
|
||||
|
||||
if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) )
|
||||
goto Exit;
|
||||
|
||||
pfb_pos = 0;
|
||||
pfb_data[pfb_pos++] = 0x80;
|
||||
pfb_data[pfb_pos++] = 1; /* Ascii section */
|
||||
pfb_lenpos = pfb_pos;
|
||||
pfb_data[pfb_pos++] = 0; /* 4-byte length, fill in later */
|
||||
pfb_data[pfb_pos++] = 0;
|
||||
pfb_data[pfb_pos++] = 0;
|
||||
pfb_data[pfb_pos++] = 0;
|
||||
|
||||
len = 0;
|
||||
type = 1;
|
||||
for ( i = 0; i < resource_cnt; ++i )
|
||||
{
|
||||
error = FT_Stream_Seek( stream, offsets[i] );
|
||||
if ( error )
|
||||
goto Exit2;
|
||||
if ( FT_READ_LONG( rlen ) )
|
||||
goto Exit;
|
||||
if ( FT_READ_USHORT( flags ) )
|
||||
goto Exit;
|
||||
rlen -= 2; /* the flags are part of the resource */
|
||||
if ( ( flags >> 8 ) == type )
|
||||
len += rlen;
|
||||
else
|
||||
{
|
||||
pfb_data[pfb_lenpos ] = len & 0xFF;
|
||||
pfb_data[pfb_lenpos + 1] = ( len >> 8 ) & 0xFF;
|
||||
pfb_data[pfb_lenpos + 2] = ( len >> 16 ) & 0xFF;
|
||||
pfb_data[pfb_lenpos + 3] = ( len >> 24 ) & 0xFF;
|
||||
|
||||
if ( ( flags >> 8 ) == 5 ) /* End of font mark */
|
||||
break;
|
||||
|
||||
pfb_data[pfb_pos++] = 0x80;
|
||||
|
||||
type = flags >> 8;
|
||||
len = rlen;
|
||||
|
||||
pfb_data[pfb_pos++] = type;
|
||||
pfb_lenpos = pfb_pos;
|
||||
pfb_data[pfb_pos++] = 0; /* 4-byte length, fill in later */
|
||||
pfb_data[pfb_pos++] = 0;
|
||||
pfb_data[pfb_pos++] = 0;
|
||||
pfb_data[pfb_pos++] = 0;
|
||||
}
|
||||
|
||||
error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen );
|
||||
pfb_pos += rlen;
|
||||
}
|
||||
|
||||
pfb_data[pfb_pos++] = 0x80;
|
||||
pfb_data[pfb_pos++] = 3;
|
||||
|
||||
pfb_data[pfb_lenpos ] = len & 0xFF;
|
||||
pfb_data[pfb_lenpos + 1] = ( len >> 8 ) & 0xFF;
|
||||
pfb_data[pfb_lenpos + 2] = ( len >> 16 ) & 0xFF;
|
||||
pfb_data[pfb_lenpos + 3] = ( len >> 24 ) & 0xFF;
|
||||
|
||||
return open_face_from_buffer( library,
|
||||
pfb_data,
|
||||
pfb_pos,
|
||||
face_index,
|
||||
"type1",
|
||||
aface );
|
||||
|
||||
Exit2:
|
||||
FT_FREE( pfb_data );
|
||||
|
||||
Exit:
|
||||
FT_FREE( offsets );
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* The resource header says we've got resource_cnt `sfnt' */
|
||||
/* (TrueType/OpenType) resources in this file. Look through */
|
||||
/* them for the one indicated by face_index, load it into mem, */
|
||||
/* pass it on the the truetype driver and return it. */
|
||||
/* */
|
||||
static FT_Error
|
||||
Mac_Read_sfnt_Resource( FT_Library library,
|
||||
FT_Stream stream,
|
||||
FT_Long resource_listoffset,
|
||||
FT_Long resource_cnt,
|
||||
FT_Long resource_data,
|
||||
FT_Long face_index,
|
||||
FT_Face *aface )
|
||||
{
|
||||
FT_Memory memory = library->memory;
|
||||
FT_Byte* sfnt_data;
|
||||
FT_Error error;
|
||||
int i;
|
||||
FT_Long flag_offset= 0xFFFFFFL;
|
||||
FT_Long rlen, junk;
|
||||
int is_cff;
|
||||
|
||||
|
||||
if ( face_index == -1 )
|
||||
face_index = 0;
|
||||
if ( face_index >= resource_cnt )
|
||||
return FT_Err_Cannot_Open_Resource;
|
||||
|
||||
error = FT_Stream_Seek( stream, resource_listoffset );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
for ( i = 0; i <= face_index; ++i )
|
||||
{
|
||||
(void)FT_READ_USHORT( junk ); /* resource id */
|
||||
(void)FT_READ_USHORT( junk ); /* rsource name */
|
||||
if ( FT_READ_LONG( flag_offset ) )
|
||||
goto Exit;
|
||||
flag_offset &= 0xFFFFFFL;
|
||||
(void)FT_READ_LONG( junk ); /* mbz */
|
||||
}
|
||||
|
||||
if ( flag_offset == 0xFFFFFFL )
|
||||
return FT_Err_Cannot_Open_Resource;
|
||||
|
||||
error = FT_Stream_Seek( stream, flag_offset + resource_data );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
if ( FT_READ_LONG( rlen ) )
|
||||
goto Exit;
|
||||
if ( rlen == -1 )
|
||||
return FT_Err_Cannot_Open_Resource;
|
||||
|
||||
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 && sfnt_data[0] == 'O' &&
|
||||
sfnt_data[1] == 'T' &&
|
||||
sfnt_data[2] == 'T' &&
|
||||
sfnt_data[3] == 'O';
|
||||
|
||||
error = open_face_from_buffer( library,
|
||||
sfnt_data,
|
||||
rlen,
|
||||
face_index,
|
||||
is_cff ? "cff" : "truetype",
|
||||
aface );
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* Check for a valid resource fork header, or a valid dfont */
|
||||
/* header. In a resource fork the first 16 bytes are repeated */
|
||||
/* at the location specified by bytes 4-7. In a dfont bytes */
|
||||
/* 4-7 point to 16 bytes of zeroes instead. */
|
||||
/* */
|
||||
static FT_Error
|
||||
IsMacResource( FT_Library library,
|
||||
FT_Stream stream,
|
||||
FT_Long resource_offset,
|
||||
FT_Long face_index,
|
||||
FT_Face *aface )
|
||||
{
|
||||
FT_Error error;
|
||||
unsigned char head[16], head2[16];
|
||||
FT_Long rdata_pos, map_pos, rdata_len, map_len;
|
||||
int allzeros, allmatch, i, cnt, subcnt;
|
||||
FT_Long type_list, tag, rpos, junk;
|
||||
|
||||
|
||||
error = FT_Stream_Seek( stream, resource_offset );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
error = FT_Stream_Read( stream, (FT_Byte *)head, 16 );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
rdata_pos = resource_offset + ( ( head[0] << 24 ) |
|
||||
( head[1] << 16 ) |
|
||||
( head[2] << 8 ) |
|
||||
head[3] );
|
||||
map_pos = resource_offset + ( ( head[4] << 24 ) |
|
||||
( head[5] << 16 ) |
|
||||
( head[6] << 8 ) |
|
||||
head[7] );
|
||||
rdata_len = ( head[ 8] << 24 ) |
|
||||
( head[ 9] << 16 ) |
|
||||
( head[10] << 8 ) |
|
||||
head[11];
|
||||
map_len = ( head[12] << 24 ) |
|
||||
( head[13] << 16 ) |
|
||||
( head[14] << 8 ) |
|
||||
head[15];
|
||||
|
||||
if ( rdata_pos + rdata_len != map_pos || map_pos == resource_offset )
|
||||
return FT_Err_Unknown_File_Format;
|
||||
|
||||
error = FT_Stream_Seek( stream, map_pos );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
head2[15] = head[15] + 1; /* make it be different */
|
||||
|
||||
error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
allzeros = 1;
|
||||
allmatch = 1;
|
||||
for ( i = 0; i < 16; ++i )
|
||||
{
|
||||
if ( head2[i] != 0 )
|
||||
allzeros = 0;
|
||||
if ( head2[i] != head[i] )
|
||||
allmatch = 0;
|
||||
}
|
||||
if ( !allzeros && !allmatch )
|
||||
return FT_Err_Unknown_File_Format;
|
||||
|
||||
/* If we've gotten this far then it's probably a mac resource file. */
|
||||
/* Now, does it contain any interesting resources? */
|
||||
|
||||
(void)FT_READ_LONG( junk ); /* skip handle to next resource map */
|
||||
(void)FT_READ_USHORT( junk ); /* skip file resource number */
|
||||
(void)FT_READ_USHORT( junk ); /* skip attributes */
|
||||
|
||||
if ( FT_READ_USHORT( type_list ) )
|
||||
goto Exit;
|
||||
if ( type_list == -1 )
|
||||
return FT_Err_Unknown_File_Format;
|
||||
|
||||
error = FT_Stream_Seek( stream, map_pos + type_list );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
if ( FT_READ_USHORT( cnt ) )
|
||||
goto Exit;
|
||||
|
||||
++cnt;
|
||||
for ( i = 0; i < cnt; ++i )
|
||||
{
|
||||
if ( FT_READ_LONG( tag ) ||
|
||||
FT_READ_USHORT( subcnt ) ||
|
||||
FT_READ_USHORT( rpos ) )
|
||||
goto Exit;
|
||||
|
||||
++subcnt;
|
||||
rpos += map_pos + type_list;
|
||||
if ( tag == FT_MAKE_TAG( 'P', 'O', 'S', 'T' ) )
|
||||
return Mac_Read_POST_Resource( library,
|
||||
stream,
|
||||
rpos,
|
||||
subcnt,
|
||||
rdata_pos,
|
||||
face_index,
|
||||
aface );
|
||||
else if ( tag == FT_MAKE_TAG( 's', 'f', 'n', 't' ) )
|
||||
return Mac_Read_sfnt_Resource( library,
|
||||
stream,
|
||||
rpos,
|
||||
subcnt,
|
||||
rdata_pos,
|
||||
face_index,
|
||||
aface );
|
||||
}
|
||||
|
||||
error = FT_Err_Cannot_Open_Resource; /* this file contains no
|
||||
interesting resources */
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* Check for a valid macbinary header, and if we find one */
|
||||
/* check that the (flattened) resource fork in it is valid. */
|
||||
/* */
|
||||
static FT_Error
|
||||
IsMacBinary( FT_Library library,
|
||||
FT_Stream stream,
|
||||
FT_Long face_index,
|
||||
FT_Face *aface )
|
||||
{
|
||||
unsigned char header[128];
|
||||
FT_Error error;
|
||||
FT_Long dlen, offset;
|
||||
|
||||
|
||||
error = FT_Stream_Seek( stream, 0 );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
error = FT_Stream_Read( stream, (FT_Byte*)header, 128 );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
if ( header[ 0] != 0 ||
|
||||
header[74] != 0 ||
|
||||
header[82] != 0 ||
|
||||
header[ 1] == 0 ||
|
||||
header[ 1] > 33 ||
|
||||
header[63] != 0 ||
|
||||
header[2 + header[1]] != 0 )
|
||||
return FT_Err_Unknown_File_Format;
|
||||
|
||||
dlen = ( header[0x53] << 24 ) |
|
||||
( header[0x54] << 16 ) |
|
||||
( header[0x55] << 8 ) |
|
||||
header[0x56];
|
||||
#if 0
|
||||
rlen = ( header[0x57] << 24 ) |
|
||||
( header[0x58] << 16 ) |
|
||||
( header[0x59] << 8 ) |
|
||||
header[0x5a];
|
||||
#endif /* 0 */
|
||||
offset = 128 + ( ( dlen + 127 ) & ~127 );
|
||||
|
||||
return IsMacResource( library, stream, offset, face_index, aface );
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* Check for some macintosh formats */
|
||||
/* Is this a macbinary file? If so look at the resource fork. */
|
||||
/* Is this a mac dfont file? */
|
||||
/* Is this an old style resource fork? (in data) */
|
||||
/* Else if we're on Mac OS/X, open the resource fork explicitly. */
|
||||
/* */
|
||||
static FT_Error
|
||||
load_mac_face( FT_Library library,
|
||||
FT_Stream stream,
|
||||
FT_Long face_index,
|
||||
FT_Face *aface,
|
||||
const FT_Open_Args *args )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_UNUSED( args );
|
||||
|
||||
|
||||
error = IsMacBinary( library, stream, face_index, aface );
|
||||
if ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format )
|
||||
error = IsMacResource( library, stream, 0, face_index, aface );
|
||||
|
||||
#ifdef FT_MACINTOSH
|
||||
|
||||
if ( ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format ||
|
||||
FT_ERROR_BASE( error ) == FT_Err_Invalid_Stream_Operation ) &&
|
||||
( args->flags & FT_OPEN_PATHNAME ) )
|
||||
{
|
||||
FT_Open_Args args2;
|
||||
char* newpath;
|
||||
FT_Memory memory;
|
||||
FT_Stream stream2;
|
||||
|
||||
|
||||
memory = library->memory;
|
||||
|
||||
FT_ALLOC( newpath, strlen( args->pathname ) + strlen( "/rsrc" ) + 1 );
|
||||
strcpy( newpath, args->pathname );
|
||||
strcat( newpath, "/rsrc" );
|
||||
|
||||
args2.flags = FT_OPEN_PATHNAME;
|
||||
args2.pathname = (char*)newpath;
|
||||
error = ft_input_stream_new( library, &args2, &stream2 );
|
||||
if ( !error )
|
||||
{
|
||||
error = IsMacResource( library, stream2, 0, face_index, aface );
|
||||
FT_Stream_Close( stream2 );
|
||||
}
|
||||
FT_FREE( newpath );
|
||||
}
|
||||
|
||||
#endif /* FT_MACINTOSH */
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
|
||||
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
|
@ -1067,15 +1642,40 @@
|
|||
}
|
||||
|
||||
error = open_face( driver, stream, face_index,
|
||||
num_params, params, &face );
|
||||
num_params, params, &face );
|
||||
if ( !error )
|
||||
goto Success;
|
||||
|
||||
if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format )
|
||||
goto Fail2;
|
||||
goto Fail3;
|
||||
}
|
||||
}
|
||||
|
||||
Fail3:
|
||||
/* If we are on the mac, and we get an FT_Err_Invalid_Stream_Operation */
|
||||
/* it may be because we have an empty data fork, so we need to check */
|
||||
/* the resource fork. */
|
||||
if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format &&
|
||||
FT_ERROR_BASE( error ) != FT_Err_Invalid_Stream_Operation )
|
||||
goto Fail2;
|
||||
|
||||
#ifndef FT_MACINTOSH
|
||||
error = load_mac_face( library, stream, face_index, aface, args );
|
||||
if ( !error )
|
||||
{
|
||||
/* We don't want to go to Success here. We've already done that. */
|
||||
/* On the other hand, if we succeeded we still need to close this */
|
||||
/* stream (we opened a different stream which extracted the */
|
||||
/* interesting information out of this stream here. That stream */
|
||||
/* will still be open and the face will point to it). */
|
||||
ft_input_stream_free( stream, external_stream );
|
||||
return error;
|
||||
}
|
||||
|
||||
if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format )
|
||||
goto Fail2;
|
||||
#endif /* !FT_MACINTOSH */
|
||||
|
||||
/* no driver is able to handle this format */
|
||||
error = FT_Err_Unknown_File_Format;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/* */
|
||||
/* The FreeType glyph rasterizer (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002 by */
|
||||
/* Copyright 1996-2001, 2002, 2003 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
|
@ -687,8 +687,8 @@
|
|||
static Bool
|
||||
Insert_Y_Turn( RAS_ARGS Int y )
|
||||
{
|
||||
PLong y_turns;
|
||||
Int y2, n;
|
||||
PLong y_turns;
|
||||
Int y2, n;
|
||||
|
||||
|
||||
n = ras.numTurns - 1;
|
||||
|
@ -710,12 +710,12 @@
|
|||
|
||||
if ( n < 0 )
|
||||
{
|
||||
ras.maxBuff--;
|
||||
if ( ras.maxBuff <= ras.top )
|
||||
{
|
||||
ras.error = Raster_Err_Overflow;
|
||||
return FAILURE;
|
||||
}
|
||||
ras.maxBuff--;
|
||||
ras.numTurns++;
|
||||
ras.sizeBuff[-ras.numTurns] = y;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue