summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/freetype/src/base/ftobjs.c
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2015-03-19 17:34:42 +0400
committerKonstantin Ritt <ritt.ks@gmail.com>2015-03-20 13:42:29 +0000
commit2eaf0cf8fd6e7c290497fedb08134a89e7b49b1d (patch)
tree0a4f7bf528e87d0b0a71ce7fccf702b87f4cdec1 /src/3rdparty/freetype/src/base/ftobjs.c
parent77c518a50334d4dcf2476a4f39edc1e3990c7f0b (diff)
Update bundled FreeType to 2.5.5
Removed everything, imported with help of import_from_tarball.sh script, and then added a pre-generated builds/unix/ftconfig.h Task-number: QTBUG-44648 Change-Id: Iea948e41f7761f1580382b3763d04c7a61383382 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/3rdparty/freetype/src/base/ftobjs.c')
-rw-r--r--src/3rdparty/freetype/src/base/ftobjs.c1105
1 files changed, 767 insertions, 338 deletions
diff --git a/src/3rdparty/freetype/src/base/ftobjs.c b/src/3rdparty/freetype/src/base/ftobjs.c
index 3403188594..ee15a016c7 100644
--- a/src/3rdparty/freetype/src/base/ftobjs.c
+++ b/src/3rdparty/freetype/src/base/ftobjs.c
@@ -4,8 +4,7 @@
/* */
/* The FreeType private base classes (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */
-/* 2010 by */
+/* Copyright 1996-2014 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -29,8 +28,8 @@
#include FT_TRUETYPE_TABLES_H
#include FT_TRUETYPE_TAGS_H
#include FT_TRUETYPE_IDS_H
-#include FT_OUTLINE_H
+#include FT_SERVICE_PROPERTIES_H
#include FT_SERVICE_SFNT_H
#include FT_SERVICE_POSTSCRIPT_NAME_H
#include FT_SERVICE_GLYPH_DICT_H
@@ -42,6 +41,30 @@
#include "ftbase.h"
#endif
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+#include FT_BITMAP_H
+
+#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
+ /* We disable the warning `conversion from XXX to YYY, */
+ /* possible loss of data' in order to compile cleanly with */
+ /* the maximum level of warnings: `md5.c' is non-FreeType */
+ /* code, and it gets used during development builds only. */
+#pragma warning( push )
+#pragma warning( disable : 4244 )
+#endif /* _MSC_VER */
+
+ /* it's easiest to include `md5.c' directly */
+#include "md5.c"
+
+#if defined( _MSC_VER )
+#pragma warning( pop )
+#endif
+
+#endif /* FT_DEBUG_LEVEL_TRACE */
+
+
#define GRID_FIT_METRICS
@@ -132,18 +155,18 @@
{
FT_Error error;
FT_Memory memory;
- FT_Stream stream;
+ FT_Stream stream = NULL;
*astream = 0;
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
if ( !args )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
- memory = library->memory;
+ memory = library->memory;
if ( FT_NEW( stream ) )
goto Exit;
@@ -157,6 +180,9 @@
(const FT_Byte*)args->memory_base,
args->memory_size );
}
+
+#ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT
+
else if ( args->flags & FT_OPEN_PATHNAME )
{
/* create a normal system stream */
@@ -172,8 +198,11 @@
FT_FREE( stream );
stream = args->stream;
}
+
+#endif
+
else
- error = FT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
if ( error )
FT_FREE( stream );
@@ -230,11 +259,11 @@
static FT_Error
ft_glyphslot_init( FT_GlyphSlot slot )
{
- FT_Driver driver = slot->face->driver;
- FT_Driver_Class clazz = driver->clazz;
- FT_Memory memory = driver->root.memory;
- FT_Error error = FT_Err_Ok;
- FT_Slot_Internal internal;
+ FT_Driver driver = slot->face->driver;
+ FT_Driver_Class clazz = driver->clazz;
+ FT_Memory memory = driver->root.memory;
+ FT_Error error = FT_Err_Ok;
+ FT_Slot_Internal internal = NULL;
slot->library = driver->root.library;
@@ -376,11 +405,14 @@
FT_Driver driver;
FT_Driver_Class clazz;
FT_Memory memory;
- FT_GlyphSlot slot;
+ FT_GlyphSlot slot = NULL;
- if ( !face || !face->driver )
- return FT_Err_Invalid_Argument;
+ if ( !face )
+ return FT_THROW( Invalid_Face_Handle );
+
+ if ( !face->driver )
+ return FT_THROW( Invalid_Argument );
driver = face->driver;
clazz = driver->clazz;
@@ -441,6 +473,10 @@
else
prev->next = cur->next;
+ /* finalize client-specific data */
+ if ( slot->generic.finalizer )
+ slot->generic.finalizer( slot );
+
ft_glyphslot_done( slot );
FT_FREE( slot );
break;
@@ -475,6 +511,7 @@
internal->transform_matrix.xy = 0;
internal->transform_matrix.yx = 0;
internal->transform_matrix.yy = 0x10000L;
+
matrix = &internal->transform_matrix;
}
else
@@ -490,6 +527,7 @@
{
internal->transform_delta.x = 0;
internal->transform_delta.y = 0;
+
delta = &internal->transform_delta;
}
else
@@ -562,10 +600,11 @@
FT_Library library;
FT_Bool autohint = FALSE;
FT_Module hinter;
+ TT_Face ttface = (TT_Face)face;
if ( !face || !face->size || !face->glyph )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
/* The validity test for `glyph_index' is performed by the */
/* font drivers. */
@@ -602,7 +641,8 @@
* - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't
* have a native font hinter.
*
- * - Otherwise, auto-hint for LIGHT hinting mode.
+ * - Otherwise, auto-hint for LIGHT hinting mode or if there isn't
+ * any hinting bytecode in the TrueType/OpenType font.
*
* - Exception: The font is `tricky' and requires the native hinter to
* load properly.
@@ -614,7 +654,8 @@
FT_DRIVER_IS_SCALABLE( driver ) &&
FT_DRIVER_USES_OUTLINES( driver ) &&
!FT_IS_TRICKY( face ) &&
- ( ( face->internal->transform_matrix.yx == 0 &&
+ ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) ||
+ ( face->internal->transform_matrix.yx == 0 &&
face->internal->transform_matrix.xx != 0 ) ||
( face->internal->transform_matrix.xx == 0 &&
face->internal->transform_matrix.yx != 0 ) ) )
@@ -627,15 +668,27 @@
FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
- if ( mode == FT_RENDER_MODE_LIGHT ||
- face->internal->ignore_unpatented_hinter )
+ /* the check for `num_locations' assures that we actually */
+ /* test for instructions in a TTF and not in a CFF-based OTF */
+ /* */
+ /* since `maxSizeOfInstructions' might be unreliable, we */
+ /* check the size of the `fpgm' and `prep' tables, too -- */
+ /* the assumption is that there don't exist real TTFs where */
+ /* both `fpgm' and `prep' tables are missing */
+ if ( mode == FT_RENDER_MODE_LIGHT ||
+ face->internal->ignore_unpatented_hinter ||
+ ( FT_IS_SFNT( face ) &&
+ ttface->num_locations &&
+ ttface->max_profile.maxSizeOfInstructions == 0 &&
+ ttface->font_program_size == 0 &&
+ ttface->cvt_program_size == 0 ) )
autohint = TRUE;
}
}
if ( autohint )
{
- FT_AutoHinter_Service hinting;
+ FT_AutoHinter_Interface hinting;
/* try to load embedded bitmaps first if available */
@@ -664,7 +717,7 @@
internal->transform_flags = 0;
/* load auto-hinted outline */
- hinting = (FT_AutoHinter_Service)hinter->clazz->module_interface;
+ hinting = (FT_AutoHinter_Interface)hinter->clazz->module_interface;
error = hinting->load_glyph( (FT_AutoHinter)hinter,
slot, face->size,
@@ -745,11 +798,11 @@
else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
{
/* apply `standard' transformation if no renderer is available */
- if ( &internal->transform_matrix )
+ if ( internal->transform_flags & 1 )
FT_Outline_Transform( &slot->outline,
&internal->transform_matrix );
- if ( &internal->transform_delta )
+ if ( internal->transform_flags & 2 )
FT_Outline_Translate( &slot->outline,
internal->transform_delta.x,
internal->transform_delta.y );
@@ -798,7 +851,7 @@
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
glyph_index = (FT_UInt)char_code;
if ( face->charmap )
@@ -949,7 +1002,7 @@
first = face->charmaps;
if ( !first )
- return FT_Err_Invalid_CharMap_Handle;
+ return FT_THROW( Invalid_CharMap_Handle );
/*
* The original TrueType specification(s) only specified charmap
@@ -1011,7 +1064,7 @@
}
}
- return FT_Err_Invalid_CharMap_Handle;
+ return FT_THROW( Invalid_CharMap_Handle );
}
@@ -1064,7 +1117,8 @@
/* */
static FT_Error
open_face( FT_Driver driver,
- FT_Stream stream,
+ FT_Stream *astream,
+ FT_Bool external_stream,
FT_Long face_index,
FT_Int num_params,
FT_Parameter* params,
@@ -1072,10 +1126,11 @@
{
FT_Memory memory;
FT_Driver_Class clazz;
- FT_Face face = 0;
- FT_Error error, error2;
+ FT_Face face = NULL;
FT_Face_Internal internal = NULL;
+ FT_Error error, error2;
+
clazz = driver->clazz;
memory = driver->root.memory;
@@ -1084,15 +1139,19 @@
if ( FT_ALLOC( face, clazz->face_object_size ) )
goto Fail;
+ face->driver = driver;
+ face->memory = memory;
+ face->stream = *astream;
+
+ /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */
+ if ( external_stream )
+ face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
+
if ( FT_NEW( internal ) )
goto Fail;
face->internal = internal;
- face->driver = driver;
- face->memory = memory;
- face->stream = stream;
-
#ifdef FT_CONFIG_OPTION_INCREMENTAL
{
int i;
@@ -1108,11 +1167,12 @@
#endif
if ( clazz->init_face )
- error = clazz->init_face( stream,
+ error = clazz->init_face( *astream,
face,
(FT_Int)face_index,
num_params,
params );
+ *astream = face->stream; /* Stream may have been changed. */
if ( error )
goto Fail;
@@ -1123,7 +1183,7 @@
/* is returned. */
/* no error should happen, but we want to play safe */
- if ( error2 && error2 != FT_Err_Invalid_CharMap_Handle )
+ if ( error2 && FT_ERR_NEQ( error2, Invalid_CharMap_Handle ) )
{
error = error2;
goto Fail;
@@ -1135,7 +1195,7 @@
if ( error )
{
destroy_charmaps( face, memory );
- if ( clazz->done_face && face )
+ if ( clazz->done_face )
clazz->done_face( face );
FT_FREE( internal );
FT_FREE( face );
@@ -1149,7 +1209,7 @@
/* there's a Mac-specific extended implementation of FT_New_Face() */
/* in src/base/ftmac.c */
-#if !defined( FT_MACINTOSH ) || defined( DARWIN_NO_CARBON )
+#ifndef FT_MACINTOSH
/* documentation is in freetype.h */
@@ -1162,9 +1222,9 @@
FT_Open_Args args;
- /* test for valid `library' and `aface' delayed to FT_Open_Face() */
+ /* test for valid `library' and `aface' delayed to `FT_Open_Face' */
if ( !pathname )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
args.flags = FT_OPEN_PATHNAME;
args.pathname = (char*)pathname;
@@ -1173,7 +1233,7 @@
return FT_Open_Face( library, &args, face_index, aface );
}
-#endif /* defined( FT_MACINTOSH ) && !defined( DARWIN_NO_CARBON ) */
+#endif
/* documentation is in freetype.h */
@@ -1188,9 +1248,9 @@
FT_Open_Args args;
- /* test for valid `library' and `face' delayed to FT_Open_Face() */
+ /* test for valid `library' and `face' delayed to `FT_Open_Face' */
if ( !file_base )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
args.flags = FT_OPEN_MEMORY;
args.memory_base = file_base;
@@ -1258,14 +1318,14 @@
{
FT_Error error;
FT_Memory memory;
- FT_Stream stream;
+ FT_Stream stream = NULL;
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
if ( !base )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
*astream = 0;
memory = library->memory;
@@ -1379,7 +1439,7 @@
if ( FT_READ_ULONG( tag ) )
return error;
if ( tag != TTAG_typ1 )
- return FT_Err_Unknown_File_Format;
+ return FT_THROW( Unknown_File_Format );
if ( FT_READ_USHORT( numTables ) )
return error;
@@ -1416,7 +1476,7 @@
if ( face_index >= 0 && pstable_index == face_index )
return FT_Err_Ok;
}
- return FT_Err_Table_Missing;
+ return FT_THROW( Table_Missing );
}
@@ -1433,7 +1493,7 @@
FT_ULong offset, length;
FT_Long pos;
FT_Bool is_sfnt_cid;
- FT_Byte* sfnt_ps;
+ FT_Byte* sfnt_ps = NULL;
FT_UNUSED( num_params );
FT_UNUSED( params );
@@ -1462,7 +1522,7 @@
error = open_face_from_buffer( library,
sfnt_ps,
length,
- face_index < 0 ? face_index : 0,
+ FT_MIN( face_index, 0 ),
is_sfnt_cid ? "cid" : "type1",
aface );
Exit:
@@ -1470,7 +1530,7 @@
FT_Error error1;
- if ( error == FT_Err_Unknown_File_Format )
+ if ( FT_ERR_EQ( error, Unknown_File_Format ) )
{
error1 = FT_Stream_Seek( stream, pos );
if ( error1 )
@@ -1482,7 +1542,7 @@
}
-#if !defined( FT_MACINTOSH ) || defined( DARWIN_NO_CARBON )
+#ifndef FT_MACINTOSH
/* The resource header says we've got resource_cnt `POST' (type1) */
/* resources in this file. They all need to be coalesced into */
@@ -1498,13 +1558,13 @@
FT_Long face_index,
FT_Face *aface )
{
- FT_Error error = FT_Err_Cannot_Open_Resource;
+ FT_Error error = FT_ERR( Cannot_Open_Resource );
FT_Memory memory = library->memory;
- FT_Byte* pfb_data;
+ FT_Byte* pfb_data = NULL;
int i, type, flags;
- FT_Long len;
- FT_Long pfb_len, pfb_pos, pfb_lenpos;
- FT_Long rlen, temp;
+ FT_ULong len;
+ FT_ULong pfb_len, pfb_pos, pfb_lenpos;
+ FT_ULong rlen, temp;
if ( face_index == -1 )
@@ -1520,11 +1580,34 @@
error = FT_Stream_Seek( stream, offsets[i] );
if ( error )
goto Exit;
- if ( FT_READ_LONG( temp ) )
+ if ( FT_READ_ULONG( temp ) )
+ goto Exit;
+
+ /* FT2 allocator takes signed long buffer length,
+ * too large value causing overflow should be checked
+ */
+ FT_TRACE4(( " POST fragment #%d: length=0x%08x\n",
+ i, temp));
+ if ( 0x7FFFFFFFUL < temp || pfb_len + temp + 6 < pfb_len )
+ {
+ FT_TRACE2(( " too long fragment length makes"
+ " pfb_len confused: temp=0x%08x\n", temp ));
+ error = FT_THROW( Invalid_Offset );
goto Exit;
+ }
+
pfb_len += temp + 6;
}
+ FT_TRACE2(( " total buffer size to concatenate %d"
+ " POST fragments: 0x%08x\n",
+ resource_cnt, pfb_len + 2));
+ if ( pfb_len + 2 < 6 ) {
+ FT_TRACE2(( " too long fragment length makes"
+ " pfb_len confused: pfb_len=0x%08x\n", pfb_len ));
+ error = FT_THROW( Array_Too_Large );
+ goto Exit;
+ }
if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) )
goto Exit;
@@ -1544,15 +1627,46 @@
error = FT_Stream_Seek( stream, offsets[i] );
if ( error )
goto Exit2;
- if ( FT_READ_LONG( rlen ) )
- goto Exit;
+ if ( FT_READ_ULONG( rlen ) )
+ goto Exit2;
+
+ /* FT2 allocator takes signed long buffer length,
+ * too large fragment length causing overflow should be checked
+ */
+ if ( 0x7FFFFFFFUL < rlen )
+ {
+ error = FT_THROW( Invalid_Offset );
+ goto Exit2;
+ }
+
if ( FT_READ_USHORT( flags ) )
- goto Exit;
- rlen -= 2; /* the flags are part of the resource */
+ goto Exit2;
+ FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n",
+ i, offsets[i], rlen, flags ));
+
+ error = FT_ERR( Array_Too_Large );
+ /* postpone the check of rlen longer than buffer until FT_Stream_Read() */
+ if ( ( flags >> 8 ) == 0 ) /* Comment, should not be loaded */
+ {
+ FT_TRACE3(( " Skip POST fragment #%d because it is a comment\n", i ));
+ continue;
+ }
+
+ /* the flags are part of the resource, so rlen >= 2. */
+ /* but some fonts declare rlen = 0 for empty fragment */
+ if ( rlen > 2 )
+ rlen -= 2;
+ else
+ rlen = 0;
+
if ( ( flags >> 8 ) == type )
len += rlen;
else
{
+ FT_TRACE3(( " Write POST fragment #%d header (4-byte) to buffer"
+ " 0x%p + 0x%08x\n", i, pfb_data, pfb_lenpos ));
+ if ( pfb_lenpos + 3 > pfb_len + 2 )
+ goto Exit2;
pfb_data[pfb_lenpos ] = (FT_Byte)( len );
pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
@@ -1561,6 +1675,10 @@
if ( ( flags >> 8 ) == 5 ) /* End of font mark */
break;
+ FT_TRACE3(( " Write POST fragment #%d header (6-byte) to buffer"
+ " 0x%p + 0x%08x\n", i, pfb_data, pfb_pos ));
+ if ( pfb_pos + 6 > pfb_len + 2 )
+ goto Exit2;
pfb_data[pfb_pos++] = 0x80;
type = flags >> 8;
@@ -1574,13 +1692,25 @@
pfb_data[pfb_pos++] = 0;
}
+ if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len )
+ goto Exit2;
+
+ FT_TRACE3(( " Load POST fragment #%d (%d byte) to buffer"
+ " 0x%p + 0x%08x\n", i, rlen, pfb_data, pfb_pos ));
error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen );
+ if ( error )
+ goto Exit2;
pfb_pos += rlen;
}
+ error = FT_ERR( Array_Too_Large );
+ if ( pfb_pos + 2 > pfb_len + 2 )
+ goto Exit2;
pfb_data[pfb_pos++] = 0x80;
pfb_data[pfb_pos++] = 3;
+ if ( pfb_lenpos + 3 > pfb_len + 2 )
+ goto Exit2;
pfb_data[pfb_lenpos ] = (FT_Byte)( len );
pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
@@ -1594,6 +1724,13 @@
aface );
Exit2:
+ if ( error == FT_ERR( Array_Too_Large ) )
+ FT_TRACE2(( " Abort due to too-short buffer to store"
+ " all POST fragments\n" ));
+ else if ( error == FT_ERR( Invalid_Offset ) )
+ FT_TRACE2(( " Abort due to invalid offset in a POST fragment\n" ));
+ if ( error )
+ error = FT_ERR( Cannot_Open_Resource );
FT_FREE( pfb_data );
Exit:
@@ -1615,7 +1752,7 @@
FT_Face *aface )
{
FT_Memory memory = library->memory;
- FT_Byte* sfnt_data;
+ FT_Byte* sfnt_data = NULL;
FT_Error error;
FT_Long flag_offset;
FT_Long rlen;
@@ -1626,7 +1763,7 @@
if ( face_index == -1 )
face_index = 0;
if ( face_index >= resource_cnt )
- return FT_Err_Cannot_Open_Resource;
+ return FT_THROW( Cannot_Open_Resource );
flag_offset = offsets[face_index];
error = FT_Stream_Seek( stream, flag_offset );
@@ -1636,7 +1773,7 @@
if ( FT_READ_LONG( rlen ) )
goto Exit;
if ( rlen == -1 )
- return FT_Err_Cannot_Open_Resource;
+ return FT_THROW( Cannot_Open_Resource );
error = open_face_PS_from_sfnt_stream( library,
stream,
@@ -1693,9 +1830,10 @@
if ( error )
return error;
+ /* POST resources must be sorted to concatenate properly */
error = FT_Raccess_Get_DataOffsets( library, stream,
map_offset, rdara_pos,
- TTAG_POST,
+ TTAG_POST, TRUE,
&data_offsets, &count );
if ( !error )
{
@@ -1708,9 +1846,11 @@
return error;
}
+ /* sfnt resources should not be sorted to preserve the face order by
+ QuickDraw API */
error = FT_Raccess_Get_DataOffsets( library, stream,
map_offset, rdara_pos,
- TTAG_sfnt,
+ TTAG_sfnt, FALSE,
&data_offsets, &count );
if ( !error )
{
@@ -1743,7 +1883,7 @@
if ( NULL == stream )
- return FT_Err_Invalid_Stream_Operation;
+ return FT_THROW( Invalid_Stream_Operation );
error = FT_Stream_Seek( stream, 0 );
if ( error )
@@ -1760,7 +1900,7 @@
header[ 1] > 33 ||
header[63] != 0 ||
header[2 + header[1]] != 0 )
- return FT_Err_Unknown_File_Format;
+ return FT_THROW( Unknown_File_Format );
dlen = ( header[0x53] << 24 ) |
( header[0x54] << 16 ) |
@@ -1770,7 +1910,7 @@
rlen = ( header[0x57] << 24 ) |
( header[0x58] << 16 ) |
( header[0x59] << 8 ) |
- header[0x5a];
+ header[0x5A];
#endif /* 0 */
offset = 128 + ( ( dlen + 127 ) & ~127 );
@@ -1793,12 +1933,13 @@
#define FT_COMPONENT trace_raccess
FT_Memory memory = library->memory;
- FT_Error error = FT_Err_Unknown_File_Format;
+ FT_Error error = FT_ERR( Unknown_File_Format );
int i;
char * file_names[FT_RACCESS_N_RULES];
FT_Long offsets[FT_RACCESS_N_RULES];
FT_Error errors[FT_RACCESS_N_RULES];
+ FT_Bool is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */
FT_Open_Args args2;
FT_Stream stream2 = 0;
@@ -1809,6 +1950,15 @@
for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
{
+ is_darwin_vfs = ft_raccess_rule_by_darwin_vfs( library, i );
+ if ( is_darwin_vfs && vfs_rfork_has_no_font )
+ {
+ FT_TRACE3(( "Skip rule %d: darwin vfs resource fork"
+ " is already checked and"
+ " no font is found\n", i ));
+ continue;
+ }
+
if ( errors[i] )
{
FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i ));
@@ -1822,6 +1972,9 @@
i, args2.pathname, offsets[i] ));
error = FT_Stream_New( library, &args2, &stream2 );
+ if ( is_darwin_vfs && FT_ERR_EQ( error, Cannot_Open_Stream ) )
+ vfs_rfork_has_no_font = TRUE;
+
if ( error )
{
FT_TRACE3(( "failed\n" ));
@@ -1836,6 +1989,8 @@
if ( !error )
break;
+ else if ( is_darwin_vfs )
+ vfs_rfork_has_no_font = TRUE;
}
for (i = 0; i < FT_RACCESS_N_RULES; i++)
@@ -1846,7 +2001,7 @@
/* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */
if ( error )
- error = FT_Err_Unknown_File_Format;
+ error = FT_ERR( Unknown_File_Format );
return error;
@@ -1875,7 +2030,7 @@
error = IsMacBinary( library, stream, face_index, aface );
- if ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format )
+ if ( FT_ERR_EQ( error, Unknown_File_Format ) )
{
#undef FT_COMPONENT
@@ -1892,9 +2047,9 @@
}
- if ( ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format ||
- FT_ERROR_BASE( error ) == FT_Err_Invalid_Stream_Operation ) &&
- ( args->flags & FT_OPEN_PATHNAME ) )
+ if ( ( FT_ERR_EQ( error, Unknown_File_Format ) ||
+ FT_ERR_EQ( error, Invalid_Stream_Operation ) ) &&
+ ( args->flags & FT_OPEN_PATHNAME ) )
error = load_face_in_embedded_rfork( library, stream,
face_index, aface, args );
return error;
@@ -1913,21 +2068,20 @@
FT_Face *aface )
{
FT_Error error;
- FT_Driver driver;
- FT_Memory memory;
- FT_Stream stream = 0;
- FT_Face face = 0;
- FT_ListNode node = 0;
+ FT_Driver driver = NULL;
+ FT_Memory memory = NULL;
+ FT_Stream stream = NULL;
+ FT_Face face = NULL;
+ FT_ListNode node = NULL;
FT_Bool external_stream;
FT_Module* cur;
FT_Module* limit;
- /* test for valid `library' delayed to */
- /* FT_Stream_New() */
+ /* test for valid `library' delayed to `FT_Stream_New' */
if ( ( !aface && face_index >= 0 ) || !args )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) &&
args->stream );
@@ -1958,24 +2112,25 @@
params = args->params;
}
- error = open_face( driver, stream, face_index,
+ error = open_face( driver, &stream, external_stream, face_index,
num_params, params, &face );
if ( !error )
goto Success;
}
else
- error = FT_Err_Invalid_Handle;
+ error = FT_THROW( Invalid_Handle );
FT_Stream_Free( stream, external_stream );
goto Fail;
}
else
{
+ error = FT_ERR( Missing_Module );
+
/* check each font driver for an appropriate format */
cur = library->modules;
limit = cur + library->num_modules;
-
for ( ; cur < limit; cur++ )
{
/* not all modules are font drivers, so check... */
@@ -1993,14 +2148,14 @@
params = args->params;
}
- error = open_face( driver, stream, face_index,
+ error = open_face( driver, &stream, external_stream, face_index,
num_params, params, &face );
if ( !error )
goto Success;
#ifdef FT_CONFIG_OPTION_MAC_FONTS
if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 &&
- FT_ERROR_BASE( error ) == FT_Err_Table_Missing )
+ FT_ERR_EQ( error, Table_Missing ) )
{
/* TrueType but essential tables are missing */
if ( FT_Stream_Seek( stream, 0 ) )
@@ -2020,39 +2175,39 @@
}
#endif
- if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format )
+ if ( FT_ERR_NEQ( error, Unknown_File_Format ) )
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_Cannot_Open_Stream &&
- FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format &&
- FT_ERROR_BASE( error ) != FT_Err_Invalid_Stream_Operation )
- goto Fail2;
+ 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_ERR_NEQ( error, Cannot_Open_Stream ) &&
+ FT_ERR_NEQ( error, Unknown_File_Format ) &&
+ FT_ERR_NEQ( error, Invalid_Stream_Operation ) )
+ goto Fail2;
#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS )
- 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_Stream_Free( stream, external_stream );
- return error;
- }
+ 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_Stream_Free( stream, external_stream );
+ return error;
+ }
- if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format )
- goto Fail2;
+ if ( FT_ERR_NEQ( error, Unknown_File_Format ) )
+ goto Fail2;
#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
/* no driver is able to handle this format */
- error = FT_Err_Unknown_File_Format;
+ error = FT_THROW( Unknown_File_Format );
Fail2:
FT_Stream_Free( stream, external_stream );
@@ -2062,10 +2217,6 @@
Success:
FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" ));
- /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */
- if ( external_stream )
- face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
-
/* add the face object to its driver's list */
if ( FT_NEW( node ) )
goto Fail;
@@ -2141,6 +2292,8 @@
internal->transform_delta.x = 0;
internal->transform_delta.y = 0;
+
+ internal->refcount = 1;
}
if ( aface )
@@ -2151,7 +2304,10 @@
goto Exit;
Fail:
- FT_Done_Face( face );
+ if ( node )
+ FT_Done_Face( face ); /* face must be in the driver's list */
+ else if ( face )
+ destroy_face( memory, face, driver );
Exit:
FT_TRACE4(( "FT_Open_Face: Return %d\n", error ));
@@ -2169,10 +2325,10 @@
FT_Open_Args open;
- /* test for valid `face' delayed to FT_Attach_Stream() */
+ /* test for valid `face' delayed to `FT_Attach_Stream' */
if ( !filepathname )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
open.stream = NULL;
open.flags = FT_OPEN_PATHNAME;
@@ -2195,14 +2351,14 @@
FT_Driver_Class clazz;
- /* test for valid `parameters' delayed to FT_Stream_New() */
+ /* test for valid `parameters' delayed to `FT_Stream_New' */
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
driver = face->driver;
if ( !driver )
- return FT_Err_Invalid_Driver_Handle;
+ return FT_THROW( Invalid_Driver_Handle );
error = FT_Stream_New( driver->root.library, parameters, &stream );
if ( error )
@@ -2211,7 +2367,7 @@
/* we implement FT_Attach_Stream in each driver through the */
/* `attach_file' interface */
- error = FT_Err_Unimplemented_Feature;
+ error = FT_ERR( Unimplemented_Feature );
clazz = driver->clazz;
if ( clazz->attach_file )
error = clazz->attach_file( face, stream );
@@ -2229,6 +2385,20 @@
/* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Error )
+ FT_Reference_Face( FT_Face face )
+ {
+ if ( !face )
+ return FT_THROW( Invalid_Face_Handle );
+
+ face->internal->refcount++;
+
+ return FT_Err_Ok;
+ }
+
+
+ /* documentation is in freetype.h */
+
+ FT_EXPORT_DEF( FT_Error )
FT_Done_Face( FT_Face face )
{
FT_Error error;
@@ -2237,25 +2407,32 @@
FT_ListNode node;
- error = FT_Err_Invalid_Face_Handle;
+ error = FT_ERR( Invalid_Face_Handle );
if ( face && face->driver )
{
- driver = face->driver;
- memory = driver->root.memory;
-
- /* find face in driver's list */
- node = FT_List_Find( &driver->faces_list, face );
- if ( node )
+ face->internal->refcount--;
+ if ( face->internal->refcount > 0 )
+ error = FT_Err_Ok;
+ else
{
- /* remove face object from the driver's list */
- FT_List_Remove( &driver->faces_list, node );
- FT_FREE( node );
+ driver = face->driver;
+ memory = driver->root.memory;
- /* now destroy the object proper */
- destroy_face( memory, face, driver );
- error = FT_Err_Ok;
+ /* find face in driver's list */
+ node = FT_List_Find( &driver->faces_list, face );
+ if ( node )
+ {
+ /* remove face object from the driver's list */
+ FT_List_Remove( &driver->faces_list, node );
+ FT_FREE( node );
+
+ /* now destroy the object proper */
+ destroy_face( memory, face, driver );
+ error = FT_Err_Ok;
+ }
}
}
+
return error;
}
@@ -2276,13 +2453,13 @@
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
if ( !asize )
- return FT_Err_Invalid_Size_Handle;
+ return FT_THROW( Invalid_Argument );
if ( !face->driver )
- return FT_Err_Invalid_Driver_Handle;
+ return FT_THROW( Invalid_Driver_Handle );
*asize = 0;
@@ -2334,15 +2511,15 @@
if ( !size )
- return FT_Err_Invalid_Size_Handle;
+ return FT_THROW( Invalid_Size_Handle );
face = size->face;
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
driver = face->driver;
if ( !driver )
- return FT_Err_Invalid_Driver_Handle;
+ return FT_THROW( Invalid_Driver_Handle );
memory = driver->root.memory;
@@ -2363,7 +2540,7 @@
destroy_size( memory, size, driver );
}
else
- error = FT_Err_Invalid_Size_Handle;
+ error = FT_THROW( Invalid_Size_Handle );
return error;
}
@@ -2382,11 +2559,11 @@
if ( !FT_HAS_FIXED_SIZES( face ) )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
/* FT_Bitmap_Size doesn't provide enough info... */
if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
- return FT_Err_Unimplemented_Feature;
+ return FT_THROW( Unimplemented_Feature );
w = FT_REQUEST_WIDTH ( req );
h = FT_REQUEST_HEIGHT( req );
@@ -2409,6 +2586,8 @@
if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width )
{
+ FT_TRACE3(( "FT_Match_Size: bitmap strike %d matches\n", i ));
+
if ( size_index )
*size_index = (FT_ULong)i;
@@ -2416,7 +2595,7 @@
}
}
- return FT_Err_Invalid_Pixel_Size;
+ return FT_THROW( Invalid_Pixel_Size );
}
@@ -2514,6 +2693,18 @@
metrics->height = bsize->height << 6;
metrics->max_advance = bsize->x_ppem;
}
+
+ FT_TRACE5(( "FT_Select_Metrics:\n" ));
+ FT_TRACE5(( " x scale: %d (%f)\n",
+ metrics->x_scale, metrics->x_scale / 65536.0 ));
+ FT_TRACE5(( " y scale: %d (%f)\n",
+ metrics->y_scale, metrics->y_scale / 65536.0 ));
+ FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 ));
+ FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 ));
+ FT_TRACE5(( " height: %f\n", metrics->height / 64.0 ));
+ FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
+ FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
+ FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
}
@@ -2622,6 +2813,18 @@
metrics->x_scale = 1L << 16;
metrics->y_scale = 1L << 16;
}
+
+ FT_TRACE5(( "FT_Request_Metrics:\n" ));
+ FT_TRACE5(( " x scale: %d (%f)\n",
+ metrics->x_scale, metrics->x_scale / 65536.0 ));
+ FT_TRACE5(( " y scale: %d (%f)\n",
+ metrics->y_scale, metrics->y_scale / 65536.0 ));
+ FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 ));
+ FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 ));
+ FT_TRACE5(( " height: %f\n", metrics->height / 64.0 ));
+ FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
+ FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
+ FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
}
@@ -2635,15 +2838,41 @@
if ( !face || !FT_HAS_FIXED_SIZES( face ) )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
if ( strike_index < 0 || strike_index >= face->num_fixed_sizes )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
clazz = face->driver->clazz;
if ( clazz->select_size )
- return clazz->select_size( face->size, (FT_ULong)strike_index );
+ {
+ FT_Error error;
+
+
+ error = clazz->select_size( face->size, (FT_ULong)strike_index );
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ {
+ FT_Size_Metrics* metrics = &face->size->metrics;
+
+
+ FT_TRACE5(( "FT_Select_Size (font driver's `select_size'):\n" ));
+ FT_TRACE5(( " x scale: %d (%f)\n",
+ metrics->x_scale, metrics->x_scale / 65536.0 ));
+ FT_TRACE5(( " y scale: %d (%f)\n",
+ metrics->y_scale, metrics->y_scale / 65536.0 ));
+ FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 ));
+ FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 ));
+ FT_TRACE5(( " height: %f\n", metrics->height / 64.0 ));
+ FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
+ FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
+ FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
+ }
+#endif
+
+ return error;
+ }
FT_Select_Metrics( face, (FT_ULong)strike_index );
@@ -2662,16 +2891,42 @@
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
if ( !req || req->width < 0 || req->height < 0 ||
req->type >= FT_SIZE_REQUEST_TYPE_MAX )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
clazz = face->driver->clazz;
if ( clazz->request_size )
- return clazz->request_size( face->size, req );
+ {
+ FT_Error error;
+
+
+ error = clazz->request_size( face->size, req );
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ {
+ FT_Size_Metrics* metrics = &face->size->metrics;
+
+
+ FT_TRACE5(( "FT_Request_Size (font driver's `request_size'):\n" ));
+ FT_TRACE5(( " x scale: %d (%f)\n",
+ metrics->x_scale, metrics->x_scale / 65536.0 ));
+ FT_TRACE5(( " y scale: %d (%f)\n",
+ metrics->y_scale, metrics->y_scale / 65536.0 ));
+ FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 ));
+ FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 ));
+ FT_TRACE5(( " height: %f\n", metrics->height / 64.0 ));
+ FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
+ FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
+ FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
+ }
+#endif
+
+ return error;
+ }
/*
* The reason that a driver doesn't have `request_size' defined is
@@ -2689,9 +2944,6 @@
if ( error )
return error;
- FT_TRACE3(( "FT_Request_Size: bitmap strike %lu matched\n",
- strike_index ));
-
return FT_Select_Size( face, (FT_Int)strike_index );
}
@@ -2713,6 +2965,8 @@
FT_Size_RequestRec req;
+ /* check of `face' delayed to `FT_Request_Size' */
+
if ( !char_width )
char_width = char_height;
else if ( !char_height )
@@ -2751,6 +3005,8 @@
FT_Size_RequestRec req;
+ /* check of `face' delayed to `FT_Request_Size' */
+
if ( pixel_width == 0 )
pixel_width = pixel_height;
else if ( pixel_height == 0 )
@@ -2791,10 +3047,10 @@
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
if ( !akerning )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
driver = face->driver;
@@ -2850,14 +3106,14 @@
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
if ( !akerning )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
FT_FACE_FIND_SERVICE( face, service, KERNING );
if ( !service )
- return FT_Err_Unimplemented_Feature;
+ return FT_THROW( Unimplemented_Feature );
error = service->get_track( face,
point_size,
@@ -2879,10 +3135,10 @@
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
if ( encoding == FT_ENCODING_NONE )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
/* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */
/* charmap available, i.e., one with UCS-4 characters, if possible. */
@@ -2893,7 +3149,7 @@
cur = face->charmaps;
if ( !cur )
- return FT_Err_Invalid_CharMap_Handle;
+ return FT_THROW( Invalid_CharMap_Handle );
limit = cur + face->num_charmaps;
@@ -2906,7 +3162,7 @@
}
}
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
}
@@ -2921,13 +3177,14 @@
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
cur = face->charmaps;
- if ( !cur )
- return FT_Err_Invalid_CharMap_Handle;
+ if ( !cur || !charmap )
+ return FT_THROW( Invalid_CharMap_Handle );
+
if ( FT_Get_CMap_Format( charmap ) == 14 )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
limit = cur + face->num_charmaps;
@@ -2936,10 +3193,11 @@
if ( cur[0] == charmap )
{
face->charmap = cur[0];
- return 0;
+ return FT_Err_Ok;
}
}
- return FT_Err_Invalid_Argument;
+
+ return FT_THROW( Invalid_Argument );
}
@@ -2951,6 +3209,9 @@
FT_Int i;
+ if ( !charmap || !charmap->face )
+ return -1;
+
for ( i = 0; i < charmap->face->num_charmaps; i++ )
if ( charmap->face->charmaps[i] == charmap )
break;
@@ -2966,7 +3227,7 @@
{
FT_CMap_Class clazz = cmap->clazz;
FT_Face face = cmap->charmap.face;
- FT_Memory memory = FT_FACE_MEMORY(face);
+ FT_Memory memory = FT_FACE_MEMORY( face );
if ( clazz->done )
@@ -3031,11 +3292,11 @@
FT_Error error = FT_Err_Ok;
FT_Face face;
FT_Memory memory;
- FT_CMap cmap;
+ FT_CMap cmap = NULL;
if ( clazz == NULL || charmap == NULL || charmap->face == NULL )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
face = charmap->face;
memory = FT_FACE_MEMORY( face );
@@ -3095,7 +3356,7 @@
}
result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode );
}
- return result;
+ return result;
}
@@ -3109,14 +3370,15 @@
FT_UInt gindex = 0;
- if ( face && face->charmap )
+ /* only do something if we have a charmap, and we have glyphs at all */
+ if ( face && face->charmap && face->num_glyphs )
{
gindex = FT_Get_Char_Index( face, 0 );
- if ( gindex == 0 )
+ if ( gindex == 0 || gindex >= (FT_UInt)face->num_glyphs )
result = FT_Get_Next_Char( face, 0, &gindex );
}
- if ( agindex )
+ if ( agindex )
*agindex = gindex;
return result;
@@ -3134,13 +3396,18 @@
FT_UInt gindex = 0;
- if ( face && face->charmap )
+ if ( face && face->charmap && face->num_glyphs )
{
FT_UInt32 code = (FT_UInt32)charcode;
FT_CMap cmap = FT_CMAP( face->charmap );
- gindex = cmap->clazz->char_next( cmap, &code );
+ do
+ {
+ gindex = cmap->clazz->char_next( cmap, &code );
+
+ } while ( gindex >= (FT_UInt)face->num_glyphs );
+
result = ( gindex == 0 ) ? 0 : code;
}
@@ -3161,8 +3428,9 @@
FT_UInt result = 0;
- if ( face && face->charmap &&
- face->charmap->encoding == FT_ENCODING_UNICODE )
+ if ( face &&
+ face->charmap &&
+ face->charmap->encoding == FT_ENCODING_UNICODE )
{
FT_CharMap charmap = find_variant_selector_charmap( face );
FT_CMap ucmap = FT_CMAP( face->charmap );
@@ -3340,7 +3608,9 @@
FT_UInt result = 0;
- if ( face && FT_HAS_GLYPH_NAMES( face ) )
+ if ( face &&
+ FT_HAS_GLYPH_NAMES( face ) &&
+ glyph_name )
{
FT_Service_GlyphDict service;
@@ -3365,27 +3635,30 @@
FT_Pointer buffer,
FT_UInt buffer_max )
{
- FT_Error error = FT_Err_Invalid_Argument;
+ FT_Error error;
+ FT_Service_GlyphDict service;
- /* clean up buffer */
- if ( buffer && buffer_max > 0 )
- ((FT_Byte*)buffer)[0] = 0;
+ if ( !face )
+ return FT_THROW( Invalid_Face_Handle );
- if ( face &&
- (FT_Long)glyph_index <= face->num_glyphs &&
- FT_HAS_GLYPH_NAMES( face ) )
- {
- FT_Service_GlyphDict service;
+ if ( !buffer || buffer_max == 0 )
+ return FT_THROW( Invalid_Argument );
+
+ /* clean up buffer */
+ ((FT_Byte*)buffer)[0] = '\0';
+ if ( (FT_Long)glyph_index >= face->num_glyphs )
+ return FT_THROW( Invalid_Glyph_Index );
- FT_FACE_LOOKUP_SERVICE( face,
- service,
- GLYPH_DICT );
+ if ( !FT_HAS_GLYPH_NAMES( face ) )
+ return FT_THROW( Invalid_Argument );
- if ( service && service->get_name )
- error = service->get_name( face, glyph_index, buffer, buffer_max );
- }
+ FT_FACE_LOOKUP_SERVICE( face, service, GLYPH_DICT );
+ if ( service && service->get_name )
+ error = service->get_name( face, glyph_index, buffer, buffer_max );
+ else
+ error = FT_THROW( Invalid_Argument );
return error;
}
@@ -3426,7 +3699,7 @@
FT_Get_Sfnt_Table( FT_Face face,
FT_Sfnt_Tag tag )
{
- void* table = 0;
+ void* table = NULL;
FT_Service_SFNT_Table service;
@@ -3454,11 +3727,11 @@
if ( !face || !FT_IS_SFNT( face ) )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
if ( service == NULL )
- return FT_Err_Unimplemented_Feature;
+ return FT_THROW( Unimplemented_Feature );
return service->load_table( face, tag, offset, buffer, length );
}
@@ -3476,12 +3749,14 @@
FT_ULong offset;
+ /* test for valid `length' delayed to `service->table_info' */
+
if ( !face || !FT_IS_SFNT( face ) )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
if ( service == NULL )
- return FT_Err_Unimplemented_Feature;
+ return FT_THROW( Unimplemented_Feature );
return service->table_info( face, table_index, tag, &offset, length );
}
@@ -3543,12 +3818,12 @@
FT_Face face;
- if ( size == NULL )
- return FT_Err_Invalid_Argument;
+ if ( !size )
+ return FT_THROW( Invalid_Size_Handle );
face = size->face;
- if ( face == NULL || face->driver == NULL )
- return FT_Err_Invalid_Argument;
+ if ( !face || !face->driver )
+ return FT_THROW( Invalid_Face_Handle );
/* we don't need anything more complex than that; all size objects */
/* are already listed by the face */
@@ -3645,7 +3920,7 @@
FT_Library library = module->library;
FT_Memory memory = library->memory;
FT_Error error;
- FT_ListNode node;
+ FT_ListNode node = NULL;
if ( FT_NEW( node ) )
@@ -3661,7 +3936,7 @@
/* allocate raster object if needed */
if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
- clazz->raster_class->raster_new )
+ clazz->raster_class->raster_new )
{
error = clazz->raster_class->raster_new( memory, &render->raster );
if ( error )
@@ -3690,11 +3965,17 @@
static void
ft_remove_renderer( FT_Module module )
{
- FT_Library library = module->library;
- FT_Memory memory = library->memory;
+ FT_Library library;
+ FT_Memory memory;
FT_ListNode node;
+ library = module->library;
+ if ( !library )
+ return;
+
+ memory = library->memory;
+
node = FT_List_Find( &library->renderers, module );
if ( node )
{
@@ -3702,7 +3983,8 @@
/* release raster object, if any */
- if ( render->raster )
+ if ( render->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
+ render->raster )
render->clazz->raster_class->raster_done( render->raster );
/* remove from list */
@@ -3720,7 +4002,7 @@
FT_Get_Renderer( FT_Library library,
FT_Glyph_Format format )
{
- /* test for valid `library' delayed to FT_Lookup_Renderer() */
+ /* test for valid `library' delayed to `FT_Lookup_Renderer' */
return FT_Lookup_Renderer( library, format, 0 );
}
@@ -3737,17 +4019,31 @@
FT_ListNode node;
FT_Error error = FT_Err_Ok;
+ FT_Renderer_SetModeFunc set_mode;
+
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ {
+ error = FT_THROW( Invalid_Library_Handle );
+ goto Exit;
+ }
if ( !renderer )
- return FT_Err_Invalid_Argument;
+ {
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
+
+ if ( num_params > 0 && !parameters )
+ {
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
node = FT_List_Find( &library->renderers, renderer );
if ( !node )
{
- error = FT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -3756,17 +4052,14 @@
if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE )
library->cur_renderer = renderer;
- if ( num_params > 0 )
- {
- FT_Renderer_SetModeFunc set_mode = renderer->clazz->set_mode;
-
+ set_mode = renderer->clazz->set_mode;
- for ( ; num_params > 0; num_params-- )
- {
- error = set_mode( renderer, parameters->tag, parameters->data );
- if ( error )
- break;
- }
+ for ( ; num_params > 0; num_params-- )
+ {
+ error = set_mode( renderer, parameters->tag, parameters->data );
+ if ( error )
+ break;
+ parameters++;
}
Exit:
@@ -3804,12 +4097,12 @@
else
renderer = FT_Lookup_Renderer( library, slot->format, &node );
- error = FT_Err_Unimplemented_Feature;
+ error = FT_ERR( Unimplemented_Feature );
while ( renderer )
{
error = renderer->render( renderer, slot, render_mode, NULL );
- if ( !error ||
- FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph )
+ if ( !error ||
+ FT_ERR_NEQ( error, Cannot_Render_Glyph ) )
break;
/* FT_Err_Cannot_Render_Glyph is returned if the render mode */
@@ -3825,10 +4118,57 @@
/* if we changed the current renderer for the glyph image format */
/* we need to select it as the next current one */
if ( !error && update && renderer )
- FT_Set_Renderer( library, renderer, 0, 0 );
+ {
+ error = FT_Set_Renderer( library, renderer, 0, 0 );
+ if ( error )
+ break;
+ }
}
}
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_bitmap
+
+ /* we convert to a single bitmap format for computing the checksum */
+ if ( !error )
+ {
+ FT_Bitmap bitmap;
+ FT_Error err;
+
+
+ FT_Bitmap_New( &bitmap );
+
+ /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */
+ err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 );
+ if ( !err )
+ {
+ MD5_CTX ctx;
+ unsigned char md5[16];
+ int i;
+
+
+ MD5_Init( &ctx);
+ MD5_Update( &ctx, bitmap.buffer, bitmap.rows * bitmap.pitch );
+ MD5_Final( md5, &ctx );
+
+ FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n"
+ " ",
+ bitmap.rows, bitmap.pitch ));
+ for ( i = 0; i < 16; i++ )
+ FT_TRACE3(( "%02X", md5[i] ));
+ FT_TRACE3(( "\n" ));
+ }
+
+ FT_Bitmap_Done( library, &bitmap );
+ }
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_objs
+
+#endif /* FT_DEBUG_LEVEL_TRACE */
+
return error;
}
@@ -3842,8 +4182,8 @@
FT_Library library;
- if ( !slot )
- return FT_Err_Invalid_Argument;
+ if ( !slot || !slot->face )
+ return FT_THROW( Invalid_Argument );
library = FT_FACE_LIBRARY( slot->face );
@@ -3874,10 +4214,10 @@
/* all child faces. */
/* */
/* <InOut> */
- /* module :: A handle to the target driver object. */
+ /* module :: A handle to the target driver object. */
/* */
/* <Note> */
- /* The driver _must_ be LOCKED! */
+ /* The driver _must_ be LOCKED! */
/* */
static void
Destroy_Module( FT_Module module )
@@ -3887,10 +4227,6 @@
FT_Library library = module->library;
- /* finalize client-data - before anything else */
- if ( module->generic.finalizer )
- module->generic.finalizer( module );
-
if ( library && library->auto_hinter == module )
library->auto_hinter = 0;
@@ -3927,14 +4263,14 @@
FREETYPE_MINOR )
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
if ( !clazz )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
/* check freetype version */
if ( clazz->module_requires > FREETYPE_VER_FIXED )
- return FT_Err_Invalid_Version;
+ return FT_THROW( Invalid_Version );
/* look for a module with the same name in the library's table */
for ( nn = 0; nn < library->num_modules; nn++ )
@@ -3944,7 +4280,7 @@
{
/* this installed module has the same name, compare their versions */
if ( clazz->module_version <= module->clazz->module_version )
- return FT_Err_Lower_Module_Version;
+ return FT_THROW( Lower_Module_Version );
/* remove the module from our list, then exit the loop to replace */
/* it by our new version.. */
@@ -3958,7 +4294,7 @@
if ( library->num_modules >= FT_MAX_MODULES )
{
- error = FT_Err_Too_Many_Drivers;
+ error = FT_THROW( Too_Many_Drivers );
goto Exit;
}
@@ -4029,7 +4365,9 @@
FT_Renderer renderer = FT_RENDERER( module );
- if ( renderer->raster )
+ if ( renderer->clazz &&
+ renderer->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
+ renderer->raster )
renderer->clazz->raster_class->raster_done( renderer->raster );
}
@@ -4044,7 +4382,7 @@
FT_Get_Module( FT_Library library,
const char* module_name )
{
- FT_Module result = 0;
+ FT_Module result = NULL;
FT_Module* cur;
FT_Module* limit;
@@ -4089,23 +4427,23 @@
{
FT_Pointer result = NULL;
+
if ( module )
{
FT_ASSERT( module->clazz && module->clazz->get_interface );
- /* first, look for the service in the module
- */
+ /* first, look for the service in the module */
if ( module->clazz->get_interface )
result = module->clazz->get_interface( module, service_id );
if ( result == NULL )
{
- /* we didn't find it, look in all other modules then
- */
+ /* we didn't find it, look in all other modules then */
FT_Library library = module->library;
FT_Module* cur = library->modules;
FT_Module* limit = cur + library->num_modules;
+
for ( ; cur < limit; cur++ )
{
if ( cur[0] != module )
@@ -4136,7 +4474,7 @@
/* try to find the module from the table, then remove it from there */
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
if ( module )
{
@@ -4165,7 +4503,119 @@
}
}
}
- return FT_Err_Invalid_Driver_Handle;
+ return FT_THROW( Invalid_Driver_Handle );
+ }
+
+
+ static FT_Error
+ ft_property_do( FT_Library library,
+ const FT_String* module_name,
+ const FT_String* property_name,
+ void* value,
+ FT_Bool set )
+ {
+ FT_Module* cur;
+ FT_Module* limit;
+ FT_Module_Interface interface;
+
+ FT_Service_Properties service;
+
+#ifdef FT_DEBUG_LEVEL_ERROR
+ const FT_String* set_name = "FT_Property_Set";
+ const FT_String* get_name = "FT_Property_Get";
+ const FT_String* func_name = set ? set_name : get_name;
+#endif
+
+ FT_Bool missing_func;
+
+
+ if ( !library )
+ return FT_THROW( Invalid_Library_Handle );
+
+ if ( !module_name || !property_name || !value )
+ return FT_THROW( Invalid_Argument );
+
+ cur = library->modules;
+ limit = cur + library->num_modules;
+
+ /* search module */
+ for ( ; cur < limit; cur++ )
+ if ( !ft_strcmp( cur[0]->clazz->module_name, module_name ) )
+ break;
+
+ if ( cur == limit )
+ {
+ FT_ERROR(( "%s: can't find module `%s'\n",
+ func_name, module_name ));
+ return FT_THROW( Missing_Module );
+ }
+
+ /* check whether we have a service interface */
+ if ( !cur[0]->clazz->get_interface )
+ {
+ FT_ERROR(( "%s: module `%s' doesn't support properties\n",
+ func_name, module_name ));
+ return FT_THROW( Unimplemented_Feature );
+ }
+
+ /* search property service */
+ interface = cur[0]->clazz->get_interface( cur[0],
+ FT_SERVICE_ID_PROPERTIES );
+ if ( !interface )
+ {
+ FT_ERROR(( "%s: module `%s' doesn't support properties\n",
+ func_name, module_name ));
+ return FT_THROW( Unimplemented_Feature );
+ }
+
+ service = (FT_Service_Properties)interface;
+
+ if ( set )
+ missing_func = (FT_Bool)( !service->set_property );
+ else
+ missing_func = (FT_Bool)( !service->get_property );
+
+ if ( missing_func )
+ {
+ FT_ERROR(( "%s: property service of module `%s' is broken\n",
+ func_name, module_name ));
+ return FT_THROW( Unimplemented_Feature );
+ }
+
+ return set ? service->set_property( cur[0], property_name, value )
+ : service->get_property( cur[0], property_name, value );
+ }
+
+
+ /* documentation is in ftmodapi.h */
+
+ FT_EXPORT_DEF( FT_Error )
+ FT_Property_Set( FT_Library library,
+ const FT_String* module_name,
+ const FT_String* property_name,
+ const void* value )
+ {
+ return ft_property_do( library,
+ module_name,
+ property_name,
+ (void*)value,
+ TRUE );
+ }
+
+
+ /* documentation is in ftmodapi.h */
+
+ FT_EXPORT_DEF( FT_Error )
+ FT_Property_Get( FT_Library library,
+ const FT_String* module_name,
+ const FT_String* property_name,
+ void* value )
+ {
+ return ft_property_do( library,
+ module_name,
+ property_name,
+ value,
+ FALSE );
}
@@ -4185,15 +4635,29 @@
/* documentation is in ftmodapi.h */
FT_EXPORT_DEF( FT_Error )
+ FT_Reference_Library( FT_Library library )
+ {
+ if ( !library )
+ return FT_THROW( Invalid_Library_Handle );
+
+ library->refcount++;
+
+ return FT_Err_Ok;
+ }
+
+
+ /* documentation is in ftmodapi.h */
+
+ FT_EXPORT_DEF( FT_Error )
FT_New_Library( FT_Memory memory,
FT_Library *alibrary )
{
- FT_Library library = 0;
+ FT_Library library = NULL;
FT_Error error;
- if ( !memory )
- return FT_Err_Invalid_Argument;
+ if ( !memory || !alibrary )
+ return FT_THROW( Invalid_Argument );
#ifdef FT_DEBUG_LEVEL_ERROR
/* init debugging support */
@@ -4224,6 +4688,8 @@
library->version_minor = FREETYPE_MINOR;
library->version_patch = FREETYPE_PATCH;
+ library->refcount = 1;
+
/* That's ok now */
*alibrary = library;
@@ -4278,42 +4744,62 @@
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
- memory = library->memory;
+ library->refcount--;
+ if ( library->refcount > 0 )
+ goto Exit;
- /* Discard client-data */
- if ( library->generic.finalizer )
- library->generic.finalizer( library );
+ memory = library->memory;
- /* Close all faces in the library. If we don't do
- * this, we can have some subtle memory leaks.
+ /*
+ * Close all faces in the library. If we don't do this, we can have
+ * some subtle memory leaks.
+ *
* Example:
*
* - the cff font driver uses the pshinter module in cff_size_done
* - if the pshinter module is destroyed before the cff font driver,
* opened FT_Face objects managed by the driver are not properly
* destroyed, resulting in a memory leak
+ *
+ * Some faces are dependent on other faces, like Type42 faces that
+ * depend on TrueType faces synthesized internally.
+ *
+ * The order of drivers should be specified in driver_name[].
*/
{
- FT_UInt n;
+ FT_UInt m, n;
+ const char* driver_name[] = { "type42", NULL };
- for ( n = 0; n < library->num_modules; n++ )
+ for ( m = 0;
+ m < sizeof ( driver_name ) / sizeof ( driver_name[0] );
+ m++ )
{
- FT_Module module = library->modules[n];
- FT_List faces;
+ for ( n = 0; n < library->num_modules; n++ )
+ {
+ FT_Module module = library->modules[n];
+ const char* module_name = module->clazz->module_name;
+ FT_List faces;
- if ( ( module->clazz->module_flags & FT_MODULE_FONT_DRIVER ) == 0 )
- continue;
+ if ( driver_name[m] &&
+ ft_strcmp( module_name, driver_name[m] ) != 0 )
+ continue;
- faces = &FT_DRIVER(module)->faces_list;
- while ( faces->head )
- {
- FT_Done_Face( FT_FACE( faces->head->data ) );
- if ( faces->head )
- FT_TRACE0(( "FT_Done_Library: failed to free some faces\n" ));
+ if ( ( module->clazz->module_flags & FT_MODULE_FONT_DRIVER ) == 0 )
+ continue;
+
+ FT_TRACE7(( "FT_Done_Library: close faces for %s\n", module_name ));
+
+ faces = &FT_DRIVER( module )->faces_list;
+ while ( faces->head )
+ {
+ FT_Done_Face( FT_FACE( faces->head->data ) );
+ if ( faces->head )
+ FT_TRACE0(( "FT_Done_Library: failed to free some faces\n" ));
+ }
}
}
}
@@ -4355,6 +4841,8 @@
#endif
FT_FREE( library );
+
+ Exit:
return FT_Err_Ok;
}
@@ -4403,69 +4891,7 @@
}
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- FT_BASE_DEF( FT_Error )
- ft_stub_set_char_sizes( FT_Size size,
- FT_F26Dot6 width,
- FT_F26Dot6 height,
- FT_UInt horz_res,
- FT_UInt vert_res )
- {
- FT_Size_RequestRec req;
- FT_Driver driver = size->face->driver;
-
-
- if ( driver->clazz->request_size )
- {
- req.type = FT_SIZE_REQUEST_TYPE_NOMINAL;
- req.width = width;
- req.height = height;
-
- if ( horz_res == 0 )
- horz_res = vert_res;
-
- if ( vert_res == 0 )
- vert_res = horz_res;
-
- if ( horz_res == 0 )
- horz_res = vert_res = 72;
-
- req.horiResolution = horz_res;
- req.vertResolution = vert_res;
-
- return driver->clazz->request_size( size, &req );
- }
-
- return 0;
- }
-
-
- FT_BASE_DEF( FT_Error )
- ft_stub_set_pixel_sizes( FT_Size size,
- FT_UInt width,
- FT_UInt height )
- {
- FT_Size_RequestRec req;
- FT_Driver driver = size->face->driver;
-
-
- if ( driver->clazz->request_size )
- {
- req.type = FT_SIZE_REQUEST_TYPE_NOMINAL;
- req.width = width << 6;
- req.height = height << 6;
- req.horiResolution = 0;
- req.vertResolution = 0;
-
- return driver->clazz->request_size( size, &req );
- }
-
- return 0;
- }
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
+ /* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Error )
FT_Get_SubGlyph_Info( FT_GlyphSlot glyph,
@@ -4476,10 +4902,11 @@
FT_Int *p_arg2,
FT_Matrix *p_transform )
{
- FT_Error error = FT_Err_Invalid_Argument;
+ FT_Error error = FT_ERR( Invalid_Argument );
- if ( glyph != NULL &&
+ if ( glyph &&
+ glyph->subglyphs &&
glyph->format == FT_GLYPH_FORMAT_COMPOSITE &&
sub_index < glyph->num_subglyphs )
{
@@ -4491,6 +4918,8 @@
*p_arg1 = subg->arg1;
*p_arg2 = subg->arg2;
*p_transform = subg->transform;
+
+ error = FT_Err_Ok;
}
return error;