diff options
Diffstat (limited to 'Build/source/libs/freetype2/src')
84 files changed, 3622 insertions, 1063 deletions
diff --git a/Build/source/libs/freetype2/src/autofit/afcjk.c b/Build/source/libs/freetype2/src/autofit/afcjk.c index c7ca266da8a..7e9438b2284 100644 --- a/Build/source/libs/freetype2/src/autofit/afcjk.c +++ b/Build/source/libs/freetype2/src/autofit/afcjk.c @@ -45,7 +45,7 @@ /*************************************************************************/ /*************************************************************************/ - static FT_Error + FT_LOCAL_DEF( FT_Error ) af_cjk_metrics_init( AF_LatinMetrics metrics, FT_Face face ) { @@ -91,7 +91,7 @@ } - static void + FT_LOCAL_DEF( void ) af_cjk_metrics_scale( AF_LatinMetrics metrics, AF_Scaler scaler ) { @@ -427,7 +427,9 @@ /* insert a new edge in the list and */ /* sort according to the position */ - error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, memory, &edge ); + error = af_axis_hints_new_edge( axis, seg->pos, + (AF_Direction)seg->dir, + memory, &edge ); if ( error ) goto Exit; @@ -596,7 +598,7 @@ } - static FT_Error + FT_LOCAL_DEF( FT_Error ) af_cjk_hints_init( AF_GlyphHints hints, AF_LatinMetrics metrics ) { @@ -1350,7 +1352,7 @@ } - static FT_Error + FT_LOCAL_DEF( FT_Error ) af_cjk_hints_apply( AF_GlyphHints hints, FT_Outline* outline, AF_LatinMetrics metrics ) diff --git a/Build/source/libs/freetype2/src/autofit/afcjk.h b/Build/source/libs/freetype2/src/autofit/afcjk.h index 0de4a5ab728..9f77fda1430 100644 --- a/Build/source/libs/freetype2/src/autofit/afcjk.h +++ b/Build/source/libs/freetype2/src/autofit/afcjk.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for CJK script (specification). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,6 +31,23 @@ FT_BEGIN_HEADER af_cjk_script_class; + FT_LOCAL( FT_Error ) + af_cjk_metrics_init( AF_LatinMetrics metrics, + FT_Face face ); + + FT_LOCAL( void ) + af_cjk_metrics_scale( AF_LatinMetrics metrics, + AF_Scaler scaler ); + + FT_LOCAL( FT_Error ) + af_cjk_hints_init( AF_GlyphHints hints, + AF_LatinMetrics metrics ); + + FT_LOCAL( FT_Error ) + af_cjk_hints_apply( AF_GlyphHints hints, + FT_Outline* outline, + AF_LatinMetrics metrics ); + /* */ FT_END_HEADER diff --git a/Build/source/libs/freetype2/src/autofit/afglobal.c b/Build/source/libs/freetype2/src/autofit/afglobal.c index ad3baa1639d..bfb9091bfdc 100644 --- a/Build/source/libs/freetype2/src/autofit/afglobal.c +++ b/Build/source/libs/freetype2/src/autofit/afglobal.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter routines to compute global hinting values (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -84,8 +84,8 @@ if ( error ) { /* - * Ignore this error; we simply use Latin as the standard - * script. XXX: Shouldn't we rather disable hinting? + * Ignore this error; we simply use the default script. + * XXX: Shouldn't we rather disable hinting? */ error = AF_Err_Ok; goto Exit; diff --git a/Build/source/libs/freetype2/src/autofit/afhints.h b/Build/source/libs/freetype2/src/autofit/afhints.h index 1308d5c4b72..675826835ae 100644 --- a/Build/source/libs/freetype2/src/autofit/afhints.h +++ b/Build/source/libs/freetype2/src/autofit/afhints.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines (specification). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,7 +30,7 @@ FT_BEGIN_HEADER * script analysis routines (until now). */ - typedef enum + typedef enum AF_Dimension_ { AF_DIMENSION_HORZ = 0, /* x coordinates, */ /* i.e., vertical segments & edges */ @@ -44,7 +44,7 @@ FT_BEGIN_HEADER /* hint directions -- the values are computed so that two vectors are */ /* in opposite directions iff `dir1 + dir2 == 0' */ - typedef enum + typedef enum AF_Direction_ { AF_DIR_NONE = 4, AF_DIR_RIGHT = 1, @@ -56,7 +56,7 @@ FT_BEGIN_HEADER /* point hint flags */ - typedef enum + typedef enum AF_Flags_ { AF_FLAG_NONE = 0, @@ -87,7 +87,7 @@ FT_BEGIN_HEADER /* edge hint flags */ - typedef enum + typedef enum AF_Edge_Flags_ { AF_EDGE_NORMAL = 0, AF_EDGE_ROUND = 1 << 0, diff --git a/Build/source/libs/freetype2/src/autofit/afindic.c b/Build/source/libs/freetype2/src/autofit/afindic.c index c6e7522e15b..3d27f521b61 100644 --- a/Build/source/libs/freetype2/src/autofit/afindic.c +++ b/Build/source/libs/freetype2/src/autofit/afindic.c @@ -43,7 +43,7 @@ static void af_indic_metrics_scale( AF_LatinMetrics metrics, - AF_Scaler scaler ) + AF_Scaler scaler ) { /* use CJK routines */ af_cjk_metrics_scale( metrics, scaler ); @@ -52,7 +52,7 @@ static FT_Error af_indic_hints_init( AF_GlyphHints hints, - AF_LatinMetrics metrics ) + AF_LatinMetrics metrics ) { /* use CJK routines */ return af_cjk_hints_init( hints, metrics ); @@ -61,8 +61,8 @@ static FT_Error af_indic_hints_apply( AF_GlyphHints hints, - FT_Outline* outline, - AF_LatinMetrics metrics) + FT_Outline* outline, + AF_LatinMetrics metrics) { /* use CJK routines */ return af_cjk_hints_apply( hints, outline, metrics ); diff --git a/Build/source/libs/freetype2/src/autofit/aflatin.c b/Build/source/libs/freetype2/src/autofit/aflatin.c index 2ae9ec5a19c..b70da068afa 100644 --- a/Build/source/libs/freetype2/src/autofit/aflatin.c +++ b/Build/source/libs/freetype2/src/autofit/aflatin.c @@ -197,7 +197,7 @@ FT_UInt glyph_index; FT_Int best_point, best_y, best_first, best_last; FT_Vector* points; - FT_Bool round; + FT_Bool round = 0; AF_LOG(( "'%c'", *p )); @@ -1004,12 +1004,14 @@ if ( !found ) { - AF_Edge edge; + AF_Edge edge; /* insert a new edge in the list and */ /* sort according to the position */ - error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, memory, &edge ); + error = af_axis_hints_new_edge( axis, seg->pos, + (AF_Direction)seg->dir, + memory, &edge ); if ( error ) goto Exit; diff --git a/Build/source/libs/freetype2/src/autofit/afloader.c b/Build/source/libs/freetype2/src/autofit/afloader.c index 4e4373a4924..4e48c2fe975 100644 --- a/Build/source/libs/freetype2/src/autofit/afloader.c +++ b/Build/source/libs/freetype2/src/autofit/afloader.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter glyph loading routines (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -165,9 +165,10 @@ /* now load the slot image into the auto-outline and run the */ /* automatic hinting process */ - metrics->clazz->script_hints_apply( hints, - &gloader->current.outline, - metrics ); + if ( metrics->clazz->script_hints_apply ) + metrics->clazz->script_hints_apply( hints, + &gloader->current.outline, + metrics ); /* we now need to hint the metrics according to the change in */ /* width/positioning that occurred during the hinting process */ @@ -515,9 +516,13 @@ load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; load_flags &= ~FT_LOAD_RENDER; - error = metrics->clazz->script_hints_init( &loader->hints, metrics ); - if ( error ) - goto Exit; + if ( metrics->clazz->script_hints_init ) + { + error = metrics->clazz->script_hints_init( &loader->hints, + metrics ); + if ( error ) + goto Exit; + } error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 ); } diff --git a/Build/source/libs/freetype2/src/autofit/aftypes.h b/Build/source/libs/freetype2/src/autofit/aftypes.h index bd3fa882302..56811f0e42f 100644 --- a/Build/source/libs/freetype2/src/autofit/aftypes.h +++ b/Build/source/libs/freetype2/src/autofit/aftypes.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter types (specification only). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -202,7 +202,7 @@ extern void* _af_debug_hints; * auto-hinted glyph image. */ - typedef enum + typedef enum AF_ScalerFlags_ { AF_SCALER_FLAG_NO_HORIZONTAL = 1, /* disable horizontal hinting */ AF_SCALER_FLAG_NO_VERTICAL = 2, /* disable vertical hinting */ @@ -260,7 +260,7 @@ extern void* _af_debug_hints; * used by more than one script. */ - typedef enum + typedef enum AF_Script_ { AF_SCRIPT_NONE = 0, AF_SCRIPT_LATIN = 1, diff --git a/Build/source/libs/freetype2/src/base/ftbase.c b/Build/source/libs/freetype2/src/base/ftbase.c index d176b8150c3..300e02d154e 100644 --- a/Build/source/libs/freetype2/src/base/ftbase.c +++ b/Build/source/libs/freetype2/src/base/ftbase.c @@ -32,7 +32,7 @@ #include "ftutil.c" #if defined( __APPLE__ ) && !defined ( DARWIN_NO_CARBON ) -#include <ftmac.c> +#include "ftmac.c" #endif /* END */ diff --git a/Build/source/libs/freetype2/src/base/ftcalc.c b/Build/source/libs/freetype2/src/base/ftcalc.c index 63aed95b75e..17790c39a1e 100644 --- a/Build/source/libs/freetype2/src/base/ftcalc.c +++ b/Build/source/libs/freetype2/src/base/ftcalc.c @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -512,8 +512,8 @@ FT_UInt32 q; - s = a; a = FT_ABS(a); - s ^= b; b = FT_ABS(b); + s = a; a = FT_ABS( a ); + s ^= b; b = FT_ABS( b ); if ( b == 0 ) { @@ -668,6 +668,57 @@ /* documentation is in ftcalc.h */ + FT_BASE_DEF( void ) + FT_Matrix_Multiply_Scaled( const FT_Matrix* a, + FT_Matrix *b, + FT_Long scaling ) + { + FT_Fixed xx, xy, yx, yy; + + FT_Long val = 0x10000L * scaling; + + + if ( !a || !b ) + return; + + xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val ); + xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val ); + yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val ); + yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val ); + + b->xx = xx; b->xy = xy; + b->yx = yx; b->yy = yy; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( void ) + FT_Vector_Transform_Scaled( FT_Vector* vector, + const FT_Matrix* matrix, + FT_Long scaling ) + { + FT_Pos xz, yz; + + FT_Long val = 0x10000L * scaling; + + + if ( !vector || !matrix ) + return; + + xz = FT_MulDiv( vector->x, matrix->xx, val ) + + FT_MulDiv( vector->y, matrix->xy, val ); + + yz = FT_MulDiv( vector->x, matrix->yx, val ) + + FT_MulDiv( vector->y, matrix->yy, val ); + + vector->x = xz; + vector->y = yz; + } + + + /* documentation is in ftcalc.h */ + FT_BASE_DEF( FT_Int32 ) FT_SqrtFixed( FT_Int32 x ) { diff --git a/Build/source/libs/freetype2/src/base/ftcid.c b/Build/source/libs/freetype2/src/base/ftcid.c new file mode 100644 index 00000000000..5a8b50ff2c3 --- /dev/null +++ b/Build/source/libs/freetype2/src/base/ftcid.c @@ -0,0 +1,63 @@ +/***************************************************************************/ +/* */ +/* ftcid.c */ +/* */ +/* FreeType API for accessing CID font information. */ +/* */ +/* Copyright 2007 by Derek Clegg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_CID_H + + + /* documentation is in ftcid.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_CID_Registry_Ordering_Supplement( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement) + { + FT_Error error; + const char* r = NULL; + const char* o = NULL; + FT_Int s = 0; + + + error = FT_Err_Invalid_Argument; + + if ( face ) + { + FT_Service_CID service; + + + FT_FACE_FIND_SERVICE( face, service, CID ); + + if ( service && service->get_ros ) + error = service->get_ros( face, &r, &o, &s ); + } + + if ( registry ) + *registry = r; + + if ( ordering ) + *ordering = o; + + if ( supplement ) + *supplement = s; + + return error; + } + + +/* END */ diff --git a/Build/source/libs/freetype2/src/base/ftdebug.c b/Build/source/libs/freetype2/src/base/ftdebug.c index c55d3c8114e..356c8c2b19e 100644 --- a/Build/source/libs/freetype2/src/base/ftdebug.c +++ b/Build/source/libs/freetype2/src/base/ftdebug.c @@ -4,7 +4,7 @@ /* */ /* Debugging and logging component (body). */ /* */ -/* Copyright 1996-2001, 2002, 2004 by */ +/* Copyright 1996-2001, 2002, 2004, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -57,7 +57,7 @@ va_start( ap, fmt ); - vprintf( fmt, ap ); + vfprintf( stderr, fmt, ap ); va_end( ap ); } @@ -71,7 +71,7 @@ va_start( ap, fmt ); - vprintf( fmt, ap ); + vfprintf( stderr, fmt, ap ); va_end( ap ); exit( EXIT_FAILURE ); diff --git a/Build/source/libs/freetype2/src/base/ftglyph.c b/Build/source/libs/freetype2/src/base/ftglyph.c index 969c5dbb05a..db0e79fcafe 100644 --- a/Build/source/libs/freetype2/src/base/ftglyph.c +++ b/Build/source/libs/freetype2/src/base/ftglyph.c @@ -376,10 +376,16 @@ const FT_Glyph_Class* clazz; + /* check arguments */ + if ( !target ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + *target = 0; - /* check arguments */ - if ( !target || !source || !source->clazz ) + if ( !source || !source->clazz ) { error = FT_Err_Invalid_Argument; goto Exit; diff --git a/Build/source/libs/freetype2/src/base/ftlcdfil.c b/Build/source/libs/freetype2/src/base/ftlcdfil.c index f40bbeae5fb..5f1fa0bdb3f 100644 --- a/Build/source/libs/freetype2/src/base/ftlcdfil.c +++ b/Build/source/libs/freetype2/src/base/ftlcdfil.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for color filtering of subpixel bitmap glyphs (body). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -161,7 +161,7 @@ #ifdef USE_LEGACY - /* FIR filter used by the default and light filters */ + /* intra-pixel filter used by the legacy filter */ static void _ft_lcd_filter_legacy( FT_Bitmap* bitmap, FT_Render_Mode mode, @@ -181,7 +181,7 @@ FT_UNUSED( library ); - /* horizontal in-place FIR filter */ + /* horizontal in-place intra-pixel filter */ if ( mode == FT_RENDER_MODE_LCD && width >= 3 ) { FT_Byte* line = bitmap->buffer; diff --git a/Build/source/libs/freetype2/src/base/ftmac.c b/Build/source/libs/freetype2/src/base/ftmac.c index fd6201adb5a..7f059076d66 100644 --- a/Build/source/libs/freetype2/src/base/ftmac.c +++ b/Build/source/libs/freetype2/src/base/ftmac.c @@ -8,7 +8,7 @@ /* This file is for Mac OS X only; see builds/mac/ftoldmac.c for */ /* classic platforms built by MPW. */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -76,12 +76,16 @@ #undef OS_INLINE #define OS_INLINE static __inline__ #endif -#include <Carbon/Carbon.h> -#ifndef HFS_MAXPATHLEN -#define HFS_MAXPATHLEN 1024 + /* The ResourceIndex type was only added in the 10.5 SDK */ +#ifndef MAC_OS_X_VERSION_10_5 +typedef short ResourceIndex; #endif +#include <CoreServices/CoreServices.h> +#include <ApplicationServices/ApplicationServices.h> +#include <sys/syslimits.h> /* PATH_MAX */ + #define FT_DEPRECATED_ATTRIBUTE #include FT_MAC_H @@ -89,7 +93,13 @@ /* undefine blocking-macros in ftmac.h */ #undef FT_GetFile_From_Mac_Name( a, b, c ) #undef FT_GetFile_From_Mac_ATS_Name( a, b, c ) +#undef FT_New_Face_From_FOND( a, b, c, d ) #undef FT_New_Face_From_FSSpec( a, b, c, d ) +#undef FT_New_Face_From_FSRef( a, b, c, d ) + +#ifndef kATSOptionFlagsUnRestrictedScope /* since Mac OS X 10.1 */ +#define kATSOptionFlagsUnRestrictedScope kATSOptionFlagsDefault +#endif /* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over @@ -100,6 +110,7 @@ #endif + /* This function is deprecated because FSSpec is deprecated in Mac OS X */ FT_EXPORT_DEF( FT_Error ) FT_GetFile_From_Mac_Name( const char* fontName, FSSpec* pathSpec, @@ -115,19 +126,28 @@ /* Private function. */ /* The FSSpec type has been discouraged for a long time, */ - /* but for some reason, there is no FSRef version of */ - /* ATSFontGetFileSpecification(), so we made our own. */ - /* Apple will provide one eventually. */ + /* unfortunately an FSRef replacement API for */ + /* ATSFontGetFileSpecification() is only available in */ + /* Mac OS X 10.5 and later. */ static OSStatus FT_ATSFontGetFileReference( ATSFontRef ats_font_id, FSRef* ats_font_ref ) { -#if __LP64__ +#if defined( MAC_OS_X_VERSION_10_5 ) && \ + MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + + OSStatus err; + + err = ATSFontGetFileReference( ats_font_id, ats_font_ref ); + + return err; +#elif __LP64__ /* No 64bit Carbon API on legacy platforms */ FT_UNUSED( ats_font_id ); FT_UNUSED( ats_font_ref ); + return fnfErr; -#else +#else /* 32bit Carbon API on legacy platforms */ OSStatus err; FSSpec spec; @@ -214,7 +234,8 @@ FSSpec* pathSpec, FT_Long* face_index ) { -#if __LP64__ +#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \ + MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) FT_UNUSED( fontName ); FT_UNUSED( pathSpec ); FT_UNUSED( face_index ); @@ -239,8 +260,8 @@ static OSErr - FT_FSPathMakeRes( const UInt8* pathname, - short* res ) + FT_FSPathMakeRes( const UInt8* pathname, + ResFileRefNum* res ) { OSErr err; FSRef ref; @@ -357,7 +378,7 @@ static void parse_fond( char* fond_data, short* have_sfnt, - short* sfnt_id, + ResID* sfnt_id, Str255 lwfn_file_name, short face_index ) { @@ -374,6 +395,10 @@ assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 ); base_assoc = assoc; + /* the maximum faces in a FOND is 48, size of StyleTable.indexes[] */ + if ( 47 < face_index ) + return; + /* Let's do a little range checking before we get too excited here */ if ( face_index < count_faces_sfnt( fond_data ) ) { @@ -425,9 +450,10 @@ ft_memcpy(ps_name, names[0] + 1, ps_name_len); ps_name[ps_name_len] = 0; } - if ( style->indexes[0] > 1 ) + if ( style->indexes[face_index] > 1 && + style->indexes[face_index] <= FT_MIN( string_count, 64 ) ) { - unsigned char* suffixes = names[style->indexes[0] - 1]; + unsigned char* suffixes = names[style->indexes[face_index] - 1]; for ( i = 1; i <= suffixes[0]; i++ ) @@ -463,8 +489,8 @@ UInt8* path_lwfn, size_t path_size ) { - FSRef ref, par_ref; - int dirname_len; + FSRef ref, par_ref; + size_t dirname_len; /* Pathname for FSRef can be in various formats: HFS, HFS+, and POSIX. */ @@ -504,10 +530,10 @@ count_faces( Handle fond, const UInt8* pathname ) { - short sfnt_id; + ResID sfnt_id; short have_sfnt, have_lwfn; Str255 lwfn_file_name; - UInt8 buff[HFS_MAXPATHLEN]; + UInt8 buff[PATH_MAX]; FT_Error err; short num_faces; @@ -539,13 +565,13 @@ chunks are often not organized that way, so we glue chunks of the same type together. */ static FT_Error - read_lwfn( FT_Memory memory, - short res, - FT_Byte** pfb_data, - FT_ULong* size ) + read_lwfn( FT_Memory memory, + ResFileRefNum res, + FT_Byte** pfb_data, + FT_ULong* size ) { FT_Error error = FT_Err_Ok; - short res_id; + ResID res_id; unsigned char *buffer, *p, *size_p = NULL; FT_ULong total_size = 0; FT_ULong old_total_size = 0; @@ -563,7 +589,8 @@ for (;;) { - post_data = Get1Resource( 'POST', res_id++ ); + post_data = Get1Resource( FT_MAKE_TAG( 'P', 'O', 'S', 'T' ), + res_id++ ); if ( post_data == NULL ) break; /* we are done */ @@ -602,7 +629,8 @@ for (;;) { - post_data = Get1Resource( 'POST', res_id++ ); + post_data = Get1Resource( FT_MAKE_TAG( 'P', 'O', 'S', 'T' ), + res_id++ ); if ( post_data == NULL ) break; /* we are done */ @@ -707,12 +735,12 @@ /* Create a new FT_Face given a buffer and a driver name. */ static FT_Error - open_face_from_buffer( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Long face_index, - char* driver_name, - FT_Face* aface ) + 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; @@ -764,10 +792,10 @@ FT_Long face_index, FT_Face* aface ) { - FT_Byte* pfb_data; - FT_ULong pfb_size; - FT_Error error; - short res; + FT_Byte* pfb_data; + FT_ULong pfb_size; + FT_Error error; + ResFileRefNum res; if ( noErr != FT_FSPathMakeRes( pathname, &res ) ) @@ -792,7 +820,7 @@ /* Create a new FT_Face from an SFNT resource, specified by res ID. */ static FT_Error FT_New_Face_From_SFNT( FT_Library library, - short sfnt_id, + ResID sfnt_id, FT_Long face_index, FT_Face* aface ) { @@ -804,8 +832,8 @@ int is_cff; - sfnt = GetResource( 'sfnt', sfnt_id ); - if ( ResError() ) + sfnt = GetResource( FT_MAKE_TAG( 's', 'f', 'n', 't' ), sfnt_id ); + if ( sfnt == NULL ) return FT_Err_Invalid_Handle; sfnt_size = (FT_ULong)GetHandleSize( sfnt ); @@ -839,10 +867,11 @@ FT_Long face_index, FT_Face* aface ) { - FT_Error error = FT_Err_Cannot_Open_Resource; - short res_ref, res_index; - Handle fond; - short num_faces_in_res, num_faces_in_fond; + FT_Error error = FT_Err_Cannot_Open_Resource; + ResFileRefNum res_ref; + ResourceIndex res_index; + Handle fond; + short num_faces_in_res, num_faces_in_fond; if ( noErr != FT_FSPathMakeRes( pathname, &res_ref ) ) @@ -855,7 +884,8 @@ num_faces_in_res = 0; for ( res_index = 1; ; ++res_index ) { - fond = Get1IndResource( 'FOND', res_index ); + fond = Get1IndResource( FT_MAKE_TAG( 'F', 'O', 'N', 'D' ), + res_index ); if ( ResError() ) break; @@ -869,7 +899,7 @@ } CloseResFile( res_ref ); - if ( FT_Err_Ok == error && NULL != aface ) + if ( FT_Err_Ok == error && NULL != aface && NULL != *aface ) (*aface)->num_faces = num_faces_in_res; return error; } @@ -883,25 +913,25 @@ FT_Long face_index, FT_Face* aface ) { - short sfnt_id, have_sfnt, have_lwfn = 0; - short fond_id; + short have_sfnt, have_lwfn = 0; + ResID sfnt_id, fond_id; OSType fond_type; Str255 fond_name; Str255 lwfn_file_name; - UInt8 path_lwfn[HFS_MAXPATHLEN]; + UInt8 path_lwfn[PATH_MAX]; OSErr err; FT_Error error = FT_Err_Ok; GetResInfo( fond, &fond_id, &fond_type, fond_name ); - if ( ResError() != noErr || fond_type != 'FOND' ) + if ( ResError() != noErr || fond_type != FT_MAKE_TAG( 'F', 'O', 'N', 'D' ) ) return FT_Err_Invalid_File_Format; parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index ); if ( lwfn_file_name[0] ) { - short res; + ResFileRefNum res; res = HomeResFile( fond ); @@ -909,7 +939,7 @@ goto found_no_lwfn_file; { - UInt8 path_fond[HFS_MAXPATHLEN]; + UInt8 path_fond[PATH_MAX]; FSRef ref; @@ -961,7 +991,7 @@ /* LWFN is a (very) specific file format, check for it explicitly */ file_type = get_file_type_from_path( pathname ); - if ( file_type == 'LWFN' ) + if ( file_type == FT_MAKE_TAG( 'L', 'W', 'F', 'N' ) ) return FT_New_Face_From_LWFN( library, pathname, face_index, aface ); /* Otherwise the file type doesn't matter (there are more than */ @@ -1029,6 +1059,8 @@ /* FT_New_Face_From_FSRef is identical to FT_New_Face except it */ /* accepts an FSRef instead of a path. */ /* */ + /* This function is deprecated because Carbon data types (FSRef) */ + /* are not cross-platform, and thus not suitable for the freetype API. */ FT_EXPORT_DEF( FT_Error ) FT_New_Face_From_FSRef( FT_Library library, const FSRef* ref, @@ -1038,7 +1070,7 @@ FT_Error error; FT_Open_Args args; OSErr err; - UInt8 pathname[HFS_MAXPATHLEN]; + UInt8 pathname[PATH_MAX]; if ( !ref ) @@ -1068,13 +1100,15 @@ /* FT_New_Face_From_FSSpec is identical to FT_New_Face except it */ /* accepts an FSSpec instead of a path. */ /* */ + /* This function is deprecated because FSSpec is deprecated in Mac OS X */ FT_EXPORT_DEF( FT_Error ) FT_New_Face_From_FSSpec( FT_Library library, const FSSpec* spec, FT_Long face_index, FT_Face* aface ) { -#if __LP64__ +#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \ + MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) FT_UNUSED( library ); FT_UNUSED( spec ); FT_UNUSED( face_index ); diff --git a/Build/source/libs/freetype2/src/base/ftobjs.c b/Build/source/libs/freetype2/src/base/ftobjs.c index fa080940045..8208e2a451d 100644 --- a/Build/source/libs/freetype2/src/base/ftobjs.c +++ b/Build/source/libs/freetype2/src/base/ftobjs.c @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -634,12 +634,24 @@ goto Load_Ok; } - /* load auto-hinted outline */ - hinting = (FT_AutoHinter_Service)hinter->clazz->module_interface; + { + FT_Face_Internal internal = face->internal; + FT_Int transform_flags = internal->transform_flags; + + + /* since the auto-hinter calls FT_Load_Glyph by itself, */ + /* make sure that glyphs aren't transformed */ + internal->transform_flags = 0; + + /* load auto-hinted outline */ + hinting = (FT_AutoHinter_Service)hinter->clazz->module_interface; + + error = hinting->load_glyph( (FT_AutoHinter)hinter, + slot, face->size, + glyph_index, load_flags ); - error = hinting->load_glyph( (FT_AutoHinter)hinter, - slot, face->size, - glyph_index, load_flags ); + internal->transform_flags = transform_flags; + } } else { @@ -883,14 +895,13 @@ /* are limited to the BMP (said UCS-2 encoding.) */ /* */ /* This function is called from open_face() (just below), and also */ - /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE). */ + /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ). */ /* */ static FT_Error find_unicode_charmap( FT_Face face ) { FT_CharMap* first; FT_CharMap* cur; - FT_CharMap* unicmap = NULL; /* some UCS-2 map, if we found it */ /* caller should have already checked that `face' is valid */ @@ -935,32 +946,32 @@ { if ( cur[0]->encoding == FT_ENCODING_UNICODE ) { - unicmap = cur; /* record we found a Unicode charmap */ - - /* XXX If some new encodings to represent UCS-4 are added, */ - /* they should be added here. */ + /* XXX If some new encodings to represent UCS-4 are added, */ + /* they should be added here. */ if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT && - cur[0]->encoding_id == TT_MS_ID_UCS_4 ) || + cur[0]->encoding_id == TT_MS_ID_UCS_4 ) || ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && - cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) - - /* Hurray! We found a UCS-4 charmap. We can stop the scan! */ + cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) { face->charmap = cur[0]; - return 0; + return FT_Err_Ok; } } } - /* We do not have any UCS-4 charmap. Sigh. */ - /* Let's see if we have some other kind of Unicode charmap, though. */ - if ( unicmap != NULL ) + /* We do not have any UCS-4 charmap. */ + /* Do the loop again and search for UCS-2 charmaps. */ + cur = first + face->num_charmaps; + + for ( ; --cur >= first; ) { - face->charmap = unicmap[0]; - return 0; + if ( cur[0]->encoding == FT_ENCODING_UNICODE ) + { + face->charmap = cur[0]; + return FT_Err_Ok; + } } - /* Chou blanc! */ return FT_Err_Invalid_CharMap_Handle; } @@ -968,6 +979,45 @@ /*************************************************************************/ /* */ /* <Function> */ + /* find_variant_selector_charmap */ + /* */ + /* <Description> */ + /* This function finds the variant selector charmap, if there is one. */ + /* There can only be one (platform=0, specific=5, format=14). */ + /* */ + static FT_CharMap + find_variant_selector_charmap( FT_Face face ) + { + FT_CharMap* first; + FT_CharMap* end; + FT_CharMap* cur; + + + /* caller should have already checked that `face' is valid */ + FT_ASSERT( face ); + + first = face->charmaps; + + if ( !first ) + return NULL; + + end = first + face->num_charmaps; /* points after the last one */ + + for ( cur = first; cur < end; ++cur ) + { + if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && + cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR && + FT_Get_CMap_Format( cur[0] ) == 14 ) + return cur[0]; + } + + return NULL; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ /* open_face */ /* */ /* <Description> */ @@ -1013,15 +1063,17 @@ for ( i = 0; i < num_params && !face->internal->incremental_interface; i++ ) if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL ) - face->internal->incremental_interface = params[i].data; + face->internal->incremental_interface = + (FT_Incremental_Interface)params[i].data; } #endif - error = clazz->init_face( stream, - face, - (FT_Int)face_index, - num_params, - params ); + if ( clazz->init_face ) + error = clazz->init_face( stream, + face, + (FT_Int)face_index, + num_params, + params ); if ( error ) goto Fail; @@ -1044,7 +1096,8 @@ if ( error ) { destroy_charmaps( face, memory ); - clazz->done_face( face ); + if ( clazz->done_face ) + clazz->done_face( face ); FT_FREE( internal ); FT_FREE( face ); *aface = 0; @@ -1488,6 +1541,9 @@ FT_Long dlen, offset; + if ( NULL == stream ) + return FT_Err_Invalid_Stream_Operation; + error = FT_Stream_Seek( stream, 0 ); if ( error ) goto Exit; @@ -1661,6 +1717,8 @@ FT_Face face = 0; FT_ListNode node = 0; FT_Bool external_stream; + FT_Module* cur; + FT_Module* limit; /* test for valid `library' delayed to */ @@ -1675,7 +1733,7 @@ /* create input stream */ error = FT_Stream_New( library, args, &stream ); if ( error ) - goto Exit; + goto Fail3; memory = library->memory; @@ -1712,8 +1770,8 @@ else { /* check each font driver for an appropriate format */ - FT_Module* cur = library->modules; - FT_Module* limit = cur + library->num_modules; + cur = library->modules; + limit = cur + library->num_modules; for ( ; cur < limit; cur++ ) @@ -1747,7 +1805,8 @@ /* 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 && + 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; @@ -2631,6 +2690,8 @@ cur = face->charmaps; if ( !cur ) return FT_Err_Invalid_CharMap_Handle; + if ( FT_Get_CMap_Format( charmap ) == 14 ) + return FT_Err_Invalid_Argument; limit = cur + face->num_charmaps; @@ -2852,6 +2913,149 @@ /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_UInt ) + FT_Face_GetCharVariantIndex( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ) + { + FT_UInt result = 0; + + + 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 ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + + + result = vcmap->clazz->char_var_index( vcmap, ucmap, charcode, + variantSelector ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Int ) + FT_Face_GetCharVariantIsDefault( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ) + { + FT_Int result = -1; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + + + result = vcmap->clazz->char_var_default( vcmap, charcode, + variantSelector ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt32* ) + FT_Face_GetVariantSelectors( FT_Face face ) + { + FT_UInt32 *result = NULL; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + result = vcmap->clazz->variant_list( vcmap, memory ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt32* ) + FT_Face_GetVariantsOfChar( FT_Face face, + FT_ULong charcode ) + { + FT_UInt32 *result = NULL; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + result = vcmap->clazz->charvariant_list( vcmap, memory, charcode ); + } + } + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt32* ) + FT_Face_GetCharsOfVariant( FT_Face face, + FT_ULong variantSelector ) + { + FT_UInt32 *result = NULL; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + result = vcmap->clazz->variantchar_list( vcmap, memory, + variantSelector ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt ) FT_Get_Name_Index( FT_Face face, FT_String* glyph_name ) { @@ -3725,9 +3929,10 @@ /* allocate the render pool */ library->raster_pool_size = FT_RENDER_POOL_SIZE; - if ( FT_RENDER_POOL_SIZE > 0 ) - if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) - goto Fail; +#if FT_RENDER_POOL_SIZE > 0 + if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) + goto Fail; +#endif /* That's ok now */ *alibrary = library; diff --git a/Build/source/libs/freetype2/src/base/ftoutln.c b/Build/source/libs/freetype2/src/base/ftoutln.c index 6926f3a09a7..2bae8573f40 100644 --- a/Build/source/libs/freetype2/src/base/ftoutln.c +++ b/Build/source/libs/freetype2/src/base/ftoutln.c @@ -474,12 +474,14 @@ FT_Pos yOffset ) { FT_UShort n; - FT_Vector* vec = outline->points; + FT_Vector* vec; if ( !outline ) return; + vec = outline->points; + for ( n = 0; n < outline->n_points; n++ ) { vec->x += xOffset; @@ -626,13 +628,13 @@ } - /* documentation is in ftoutln.h */ + /* documentation is in freetype.h */ FT_EXPORT_DEF( void ) FT_Vector_Transform( FT_Vector* vector, const FT_Matrix* matrix ) { - FT_Pos xz, yz; + FT_Pos xz, yz; if ( !vector || !matrix ) diff --git a/Build/source/libs/freetype2/src/base/ftrfork.c b/Build/source/libs/freetype2/src/base/ftrfork.c index a4f726d9303..5a835ee6389 100644 --- a/Build/source/libs/freetype2/src/base/ftrfork.c +++ b/Build/source/libs/freetype2/src/base/ftrfork.c @@ -4,7 +4,7 @@ /* */ /* Embedded resource forks accessor (body). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2007 by */ /* Masatake YAMATO and Redhat K.K. */ /* */ /* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ @@ -132,6 +132,19 @@ } + static int + ft_raccess_sort_ref_by_id( FT_RFork_Ref* a, + FT_RFork_Ref* b ) + { + if ( a->res_id < b->res_id ) + return -1; + else if ( a->res_id > b->res_id ) + return 1; + else + return 0; + } + + FT_BASE_DEF( FT_Error ) FT_Raccess_Get_DataOffsets( FT_Library library, FT_Stream stream, @@ -141,12 +154,13 @@ FT_Long **offsets, FT_Long *count ) { - FT_Error error; - int i, j, cnt, subcnt; - FT_Long tag_internal, rpos; - FT_Memory memory = library->memory; - FT_Long temp; - FT_Long *offsets_internal; + FT_Error error; + int i, j, cnt, subcnt; + FT_Long tag_internal, rpos; + FT_Memory memory = library->memory; + FT_Long temp; + FT_Long *offsets_internal; + FT_RFork_Ref *ref; error = FT_Stream_Seek( stream, map_offset ); @@ -179,28 +193,43 @@ if ( error ) return error; - if ( FT_NEW_ARRAY( offsets_internal, *count ) ) + if ( FT_NEW_ARRAY( ref, *count ) ) return error; for ( j = 0; j < *count; ++j ) { - (void)FT_STREAM_SKIP( 2 ); /* resource id */ - (void)FT_STREAM_SKIP( 2 ); /* rsource name */ - + if ( FT_READ_USHORT( ref[j].res_id ) ) + goto Exit; + if ( FT_STREAM_SKIP( 2 ) ) /* resource name */ + goto Exit; if ( FT_READ_LONG( temp ) ) - { - FT_FREE( offsets_internal ); - return error; - } + goto Exit; + if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ + goto Exit; - offsets_internal[j] = rdata_pos + ( temp & 0xFFFFFFL ); - - (void)FT_STREAM_SKIP( 4 ); /* mbz */ + ref[j].offset = temp & 0xFFFFFFL; } + ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ), + ( int(*)(const void*, const void*) ) + ft_raccess_sort_ref_by_id ); + + if ( FT_NEW_ARRAY( offsets_internal, *count ) ) + goto Exit; + + /* XXX: duplicated reference ID, + * gap between reference IDs are acceptable? + * further investigation on Apple implementation is needed. + */ + for ( j = 0; j < *count; ++j ) + offsets_internal[j] = rdata_pos + ref[j].offset; + *offsets = offsets_internal; + error = FT_Err_Ok; - return FT_Err_Ok; + Exit: + FT_FREE( ref ); + return error; } } @@ -227,7 +256,7 @@ typedef FT_Error (*raccess_guess_func)( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); @@ -235,56 +264,63 @@ static FT_Error raccess_guess_apple_double( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_apple_single( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_darwin_ufs_export( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error + raccess_guess_darwin_newvfs( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error raccess_guess_darwin_hfsplus( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_vfat( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_linux_cap( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_linux_double( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_linux_netatalk( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); @@ -298,7 +334,7 @@ static FT_Error raccess_guess_apple_generic( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, FT_Int32 magic, FT_Long *result_offset ); @@ -329,6 +365,7 @@ raccess_guess_apple_double, raccess_guess_apple_single, raccess_guess_darwin_ufs_export, + raccess_guess_darwin_newvfs, raccess_guess_darwin_hfsplus, raccess_guess_vfat, raccess_guess_linux_cap, @@ -339,7 +376,11 @@ for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) { new_names[i] = NULL; - errors[i] = FT_Stream_Seek( stream, 0 ); + if ( NULL != stream ) + errors[i] = FT_Stream_Seek( stream, 0 ); + else + errors[i] = FT_Err_Ok; + if ( errors[i] ) continue ; @@ -354,7 +395,7 @@ static FT_Error raccess_guess_apple_double( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -362,6 +403,9 @@ *result_file_name = NULL; + if ( NULL == stream ) + return FT_Err_Cannot_Open_Stream; + return raccess_guess_apple_generic( library, stream, base_file_name, magic, result_offset ); } @@ -370,7 +414,7 @@ static FT_Error raccess_guess_apple_single( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -378,6 +422,9 @@ *result_file_name = NULL; + if ( NULL == stream ) + return FT_Err_Cannot_Open_Stream; + return raccess_guess_apple_generic( library, stream, base_file_name, magic, result_offset ); } @@ -386,7 +433,7 @@ static FT_Error raccess_guess_darwin_ufs_export( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -416,7 +463,7 @@ static FT_Error raccess_guess_darwin_hfsplus( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -433,7 +480,7 @@ memory = library->memory; - if ( base_file_len > FT_INT_MAX ) + if ( base_file_len + 6 > FT_INT_MAX ) return FT_Err_Array_Too_Large; if ( FT_ALLOC( newpath, base_file_len + 6 ) ) @@ -450,9 +497,45 @@ static FT_Error + raccess_guess_darwin_newvfs( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + /* + Only meaningful on systems with Mac OS X (> 10.1). + */ + FT_Error error; + char* newpath; + FT_Memory memory; + FT_Long base_file_len = ft_strlen( base_file_name ); + + FT_UNUSED( stream ); + + + memory = library->memory; + + if ( base_file_len + 18 > FT_INT_MAX ) + return FT_Err_Array_Too_Large; + + if ( FT_ALLOC( newpath, base_file_len + 18 ) ) + return error; + + FT_MEM_COPY( newpath, base_file_name, base_file_len ); + FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 ); + + *result_file_name = newpath; + *result_offset = 0; + + return FT_Err_Ok; + } + + + static FT_Error raccess_guess_vfat( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -479,7 +562,7 @@ static FT_Error raccess_guess_linux_cap( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -505,7 +588,7 @@ static FT_Error raccess_guess_linux_double( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -536,7 +619,7 @@ static FT_Error raccess_guess_linux_netatalk( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -568,7 +651,7 @@ static FT_Error raccess_guess_apple_generic( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, FT_Int32 magic, FT_Long *result_offset ) { @@ -629,7 +712,7 @@ static FT_Error raccess_guess_linux_double_from_file_name( FT_Library library, - char * file_name, + char *file_name, FT_Long *result_offset ) { FT_Open_Args args2; @@ -701,7 +784,7 @@ FT_BASE_DEF( void ) FT_Raccess_Guess( FT_Library library, FT_Stream stream, - char* base_name, + char *base_name, char **new_names, FT_Long *offsets, FT_Error *errors ) diff --git a/Build/source/libs/freetype2/src/base/ftstream.c b/Build/source/libs/freetype2/src/base/ftstream.c index a067a1fde7d..569e46c79bf 100644 --- a/Build/source/libs/freetype2/src/base/ftstream.c +++ b/Build/source/libs/freetype2/src/base/ftstream.c @@ -4,7 +4,7 @@ /* */ /* I/O stream support (body). */ /* */ -/* Copyright 2000-2001, 2002, 2004, 2005, 2006 by */ +/* Copyright 2000-2001, 2002, 2004, 2005, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -89,6 +89,9 @@ FT_Stream_Skip( FT_Stream stream, FT_Long distance ) { + if ( distance < 0 ) + return FT_Err_Invalid_Stream_Operation; + return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) ); } diff --git a/Build/source/libs/freetype2/src/base/ftstroke.c b/Build/source/libs/freetype2/src/base/ftstroke.c index 8f7e0459da4..5dfee8ba3d9 100644 --- a/Build/source/libs/freetype2/src/base/ftstroke.c +++ b/Build/source/libs/freetype2/src/base/ftstroke.c @@ -4,7 +4,7 @@ /* */ /* FreeType path stroker (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -230,7 +230,7 @@ /***************************************************************************/ /***************************************************************************/ - typedef enum + typedef enum FT_StrokeTags_ { FT_STROKE_TAG_ON = 1, /* on-curve point */ FT_STROKE_TAG_CUBIC = 2, /* cubic off-point */ diff --git a/Build/source/libs/freetype2/src/bdf/bdfdrivr.c b/Build/source/libs/freetype2/src/bdf/bdfdrivr.c index 74cc2f1b8bf..2a5767e2f0e 100644 --- a/Build/source/libs/freetype2/src/bdf/bdfdrivr.c +++ b/Build/source/libs/freetype2/src/bdf/bdfdrivr.c @@ -181,7 +181,9 @@ THE SOFTWARE. bdf_cmap_init, bdf_cmap_done, bdf_cmap_char_index, - bdf_cmap_char_next + bdf_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL }; diff --git a/Build/source/libs/freetype2/src/cff/cffcmap.c b/Build/source/libs/freetype2/src/cff/cffcmap.c index fffc5fc550d..578d048bedd 100644 --- a/Build/source/libs/freetype2/src/cff/cffcmap.c +++ b/Build/source/libs/freetype2/src/cff/cffcmap.c @@ -4,7 +4,7 @@ /* */ /* CFF character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -107,7 +107,9 @@ (FT_CMap_InitFunc) cff_cmap_encoding_init, (FT_CMap_DoneFunc) cff_cmap_encoding_done, (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, - (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next + (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next, + + NULL, NULL, NULL, NULL, NULL }; @@ -213,7 +215,9 @@ (FT_CMap_InitFunc) cff_cmap_unicode_init, (FT_CMap_DoneFunc) cff_cmap_unicode_done, (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, - (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next + (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next, + + NULL, NULL, NULL, NULL, NULL }; diff --git a/Build/source/libs/freetype2/src/cff/cffdrivr.c b/Build/source/libs/freetype2/src/cff/cffdrivr.c index 952e88e39f2..6c3ff989fb0 100644 --- a/Build/source/libs/freetype2/src/cff/cffdrivr.c +++ b/Build/source/libs/freetype2/src/cff/cffdrivr.c @@ -22,8 +22,10 @@ #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H #include FT_TRUETYPE_IDS_H +#include FT_SERVICE_CID_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_POSTSCRIPT_NAME_H #include FT_SERVICE_TT_CMAP_H #include "cffdrivr.h" @@ -36,6 +38,7 @@ #include FT_SERVICE_XFREE86_NAME_H #include FT_SERVICE_GLYPH_DICT_H + /*************************************************************************/ /* */ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ @@ -151,7 +154,7 @@ FT_UInt glyph_index, FT_Int32 load_flags ) { - FT_Error error; + FT_Error error; CFF_GlyphSlot slot = (CFF_GlyphSlot)cffslot; CFF_Size size = (CFF_Size)cffsize; @@ -163,10 +166,10 @@ if ( !size ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + /* reset the size object if necessary */ if ( load_flags & FT_LOAD_NO_SCALE ) size = NULL; - /* reset the size object if necessary */ if ( size ) { /* these two objects must have the same parent */ @@ -184,10 +187,10 @@ } - /* - * GLYPH DICT SERVICE - * - */ + /* + * GLYPH DICT SERVICE + * + */ static FT_Error cff_get_glyph_name( CFF_Face face, @@ -226,8 +229,8 @@ FT_FREE( gname ); error = CFF_Err_Ok; - Exit: - return error; + Exit: + return error; } @@ -284,10 +287,10 @@ }; - /* - * POSTSCRIPT INFO SERVICE - * - */ + /* + * POSTSCRIPT INFO SERVICE + * + */ static FT_Int cff_ps_has_glyph_names( FT_Face face ) @@ -306,9 +309,10 @@ if ( cff && cff->font_info == NULL ) { - CFF_FontRecDict dict = &cff->top_font.font_dict; - PS_FontInfoRec *font_info; - FT_Memory memory = face->root.memory; + CFF_FontRecDict dict = &cff->top_font.font_dict; + PS_FontInfoRec *font_info; + FT_Memory memory = face->root.memory; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) ) @@ -316,19 +320,19 @@ font_info->version = cff_index_get_sid_string( &cff->string_index, dict->version, - cff->psnames ); + psnames ); font_info->notice = cff_index_get_sid_string( &cff->string_index, dict->notice, - cff->psnames ); + psnames ); font_info->full_name = cff_index_get_sid_string( &cff->string_index, dict->full_name, - cff->psnames ); + psnames ); font_info->family_name = cff_index_get_sid_string( &cff->string_index, dict->family_name, - cff->psnames ); + psnames ); font_info->weight = cff_index_get_sid_string( &cff->string_index, dict->weight, - cff->psnames ); + psnames ); font_info->italic_angle = dict->italic_angle; font_info->is_fixed_pitch = dict->is_fixed_pitch; font_info->underline_position = (FT_Short)dict->underline_position; @@ -353,6 +357,27 @@ /* + * POSTSCRIPT NAME SERVICE + * + */ + + static const char* + cff_get_ps_name( CFF_Face face ) + { + CFF_Font cff = (CFF_Font)face->extra.data; + + + return (const char*)cff->font_name; + } + + + static const FT_Service_PsFontNameRec cff_service_ps_name = + { + (FT_PsName_GetFunc)cff_get_ps_name + }; + + + /* * TT CMAP INFO * * If the charmap is a synthetic Unicode encoding cmap or @@ -397,6 +422,65 @@ }; + /* + * CID INFO SERVICE + * + */ + static FT_Error + cff_get_ros( CFF_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ) + { + FT_Error error = CFF_Err_Ok; + CFF_Font cff = (CFF_Font)face->extra.data; + + + if ( cff ) + { + CFF_FontRecDict dict = &cff->top_font.font_dict; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + + + if ( dict->cid_registry == 0xFFFFU ) + { + error = CFF_Err_Invalid_Argument; + goto Fail; + } + + if ( registry ) + { + if ( cff->registry == NULL ) + cff->registry = cff_index_get_sid_string( &cff->string_index, + dict->cid_registry, + psnames ); + *registry = cff->registry; + } + + if ( ordering ) + { + if ( cff->ordering == NULL ) + cff->ordering = cff_index_get_sid_string( &cff->string_index, + dict->cid_ordering, + psnames ); + *ordering = cff->ordering; + } + + if ( supplement ) + *supplement = dict->cid_supplement; + } + + Fail: + return error; + } + + + static const FT_Service_CIDRec cff_service_cid_info = + { + (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros + }; + + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -411,12 +495,14 @@ static const FT_ServiceDescRec cff_services[] = { - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF }, - { FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF }, + { FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info }, + { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name }, #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES - { FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict }, + { FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict }, #endif - { FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info }, + { FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info }, + { FT_SERVICE_ID_CID, &cff_service_cid_info }, { NULL, NULL } }; diff --git a/Build/source/libs/freetype2/src/cff/cffgload.c b/Build/source/libs/freetype2/src/cff/cffgload.c index 0e2a179c7cc..6553c8d1a56 100644 --- a/Build/source/libs/freetype2/src/cff/cffgload.c +++ b/Build/source/libs/freetype2/src/cff/cffgload.c @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -110,6 +110,9 @@ cff_op_callgsubr, cff_op_return, + cff_op_hsbw, /* Type 1 opcode: invalid but seen in real life */ + cff_op_closepath, /* ditto */ + /* do not remove */ cff_op_max @@ -187,6 +190,9 @@ 1, /* callsubr */ 1, + 0, + + 2, /* hsbw */ 0 }; @@ -222,6 +228,8 @@ /* */ /* glyph :: The current glyph object. */ /* */ + /* hinting :: Whether hinting is active. */ + /* */ static void cff_builder_init( CFF_Builder* builder, TT_Face face, @@ -251,17 +259,14 @@ if ( hinting && size ) { - builder->hints_globals = size->root.internal; + CFF_Internal internal = (CFF_Internal)size->root.internal; + + + builder->hints_globals = (void *)internal->topfont; builder->hints_funcs = glyph->root.internal->glyph_hints; } } - if ( size ) - { - builder->scale_x = size->root.metrics.x_scale; - builder->scale_y = size->root.metrics.y_scale; - } - builder->pos_x = 0; builder->pos_y = 0; @@ -339,11 +344,15 @@ /* decoder :: A pointer to the glyph builder to initialize. */ /* */ /* <Input> */ - /* face :: The current face object. */ + /* face :: The current face object. */ /* */ - /* size :: The current size object. */ + /* size :: The current size object. */ + /* */ + /* slot :: The current glyph object. */ + /* */ + /* hinting :: Whether hinting is active. */ /* */ - /* slot :: The current glyph object. */ + /* hint_mode :: The hinting mode. */ /* */ FT_LOCAL_DEF( void ) cff_decoder_init( CFF_Decoder* decoder, @@ -371,18 +380,21 @@ } - /* this function is used to select the locals subrs array */ + /* this function is used to select the subfont */ + /* and the locals subrs array */ FT_LOCAL_DEF( FT_Error ) cff_decoder_prepare( CFF_Decoder* decoder, + CFF_Size size, FT_UInt glyph_index ) { - CFF_Font cff = (CFF_Font)decoder->builder.face->extra.data; - CFF_SubFont sub = &cff->top_font; - FT_Error error = CFF_Err_Ok; + CFF_Builder *builder = &decoder->builder; + CFF_Font cff = (CFF_Font)builder->face->extra.data; + CFF_SubFont sub = &cff->top_font; + FT_Error error = CFF_Err_Ok; /* manage CID fonts */ - if ( cff->num_subfonts >= 1 ) + if ( cff->num_subfonts ) { FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index ); @@ -393,8 +405,17 @@ error = CFF_Err_Invalid_File_Format; goto Exit; } - + sub = cff->subfonts[fd_index]; + + if ( builder->hints_funcs ) + { + CFF_Internal internal = (CFF_Internal)size->root.internal; + + + /* for CFFs without subfonts, this value has already been set */ + builder->hints_globals = (void *)internal->subfonts[fd_index]; + } } decoder->num_locals = sub->num_local_subrs; @@ -954,6 +975,9 @@ case 8: op = cff_op_rrcurveto; break; + case 9: + op = cff_op_closepath; + break; case 10: op = cff_op_callsubr; break; @@ -1055,6 +1079,9 @@ } } break; + case 13: + op = cff_op_hsbw; + break; case 14: op = cff_op_endchar; break; @@ -1168,7 +1195,7 @@ req_args = 0; } - req_args &= 15; + req_args &= 0x000F; if ( num_args < req_args ) goto Stack_Underflow; args -= req_args; @@ -2022,6 +2049,30 @@ FT_TRACE4(( " dotsection" )); break; + case cff_op_closepath: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " closepath (invalid op)" )); + + args = stack; + break; + + case cff_op_hsbw: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " hsbw (invalid op)" )); + + decoder->glyph_width = decoder->nominal_width + + (args[1] >> 16); + x = args[0]; + y = 0; + args = stack; + break; + case cff_op_and: { FT_Fixed cond = args[0] && args[1]; @@ -2260,7 +2311,7 @@ &charstring, &charstring_len ); if ( !error ) { - error = cff_decoder_prepare( &decoder, glyph_index ); + error = cff_decoder_prepare( &decoder, size, glyph_index ); if ( !error ) error = cff_decoder_parse_charstrings( &decoder, charstring, @@ -2291,18 +2342,20 @@ FT_Error error; CFF_Decoder decoder; TT_Face face = (TT_Face)glyph->root.face; - FT_Bool hinting; + FT_Bool hinting, force_scaling; CFF_Font cff = (CFF_Font)face->extra.data; FT_Matrix font_matrix; FT_Vector font_offset; + force_scaling = FALSE; + /* in a CID-keyed font, consider `glyph_index' as a CID and map */ /* it immediately to the real glyph_index -- if it isn't a */ /* subsetted font, glyph_indices and CIDs are identical, though */ if ( cff->top_font.font_dict.cid_registry != 0xFFFFU && - cff->charset.cids ) + cff->charset.cids ) { glyph_index = cff_charset_cid_to_gindex( &cff->charset, glyph_index ); if ( glyph_index == 0 ) @@ -2389,6 +2442,36 @@ if ( load_flags & FT_LOAD_SBITS_ONLY ) return CFF_Err_Invalid_Argument; + /* if we have a CID subfont, use its matrix (which has already */ + /* been multiplied with the root matrix) */ + + /* this scaling is only relevant if the PS hinter isn't active */ + if ( cff->num_subfonts ) + { + FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, + glyph_index ); + + FT_Int top_upm = cff->top_font.font_dict.units_per_em; + FT_Int sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em; + + + font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix; + font_offset = cff->subfonts[fd_index]->font_dict.font_offset; + + if ( top_upm != sub_upm ) + { + glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm ); + glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm ); + + force_scaling = TRUE; + } + } + else + { + font_matrix = cff->top_font.font_dict.font_matrix; + font_offset = cff->top_font.font_dict.font_offset; + } + glyph->root.outline.n_points = 0; glyph->root.outline.n_contours = 0; @@ -2413,7 +2496,7 @@ &charstring, &charstring_len ); if ( !error ) { - error = cff_decoder_prepare( &decoder, glyph_index ); + error = cff_decoder_prepare( &decoder, size, glyph_index ); if ( !error ) { error = cff_decoder_parse_charstrings( &decoder, @@ -2481,21 +2564,6 @@ if ( !error ) { - if ( cff->num_subfonts >= 1 ) - { - FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, - glyph_index ); - - - font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix; - font_offset = cff->subfonts[fd_index]->font_dict.font_offset; - } - else - { - font_matrix = cff->top_font.font_dict.font_matrix; - font_offset = cff->top_font.font_dict.font_offset; - } - /* Now, set the metrics -- this is rather simple, as */ /* the left side bearing is the xMin, and the top side */ /* bearing the yMax. */ @@ -2565,9 +2633,8 @@ glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; - /* apply the font matrix */ - if ( !( font_matrix.xx == 0x10000L && - font_matrix.yy == 0x10000L && + /* apply the font matrix -- `xx' has already been normalized */ + if ( !( font_matrix.yy == 0x10000L && font_matrix.xy == 0 && font_matrix.yx == 0 ) ) FT_Outline_Transform( &glyph->root.outline, &font_matrix ); @@ -2587,7 +2654,7 @@ FT_Vector_Transform( &advance, &font_matrix ); metrics->vertAdvance = advance.y + font_offset.y; - if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) + if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling ) { /* scale the outline and the metrics */ FT_Int n; diff --git a/Build/source/libs/freetype2/src/cff/cffgload.h b/Build/source/libs/freetype2/src/cff/cffgload.h index f67864a6925..d661f9e7043 100644 --- a/Build/source/libs/freetype2/src/cff/cffgload.h +++ b/Build/source/libs/freetype2/src/cff/cffgload.h @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -55,10 +55,6 @@ FT_BEGIN_HEADER /* */ /* last :: The last point position. */ /* */ - /* scale_x :: The horizontal scale (FUnits to sub-pixels). */ - /* */ - /* scale_y :: The vertical scale (FUnits to sub-pixels). */ - /* */ /* pos_x :: The horizontal translation (if composite glyph). */ /* */ /* pos_y :: The vertical translation (if composite glyph). */ @@ -94,9 +90,6 @@ FT_BEGIN_HEADER FT_Vector last; - FT_Fixed scale_x; - FT_Fixed scale_y; - FT_Pos pos_x; FT_Pos pos_y; @@ -177,6 +170,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) cff_decoder_prepare( CFF_Decoder* decoder, + CFF_Size size, FT_UInt glyph_index ); #if 0 /* unused until we support pure CFF fonts */ diff --git a/Build/source/libs/freetype2/src/cff/cffload.c b/Build/source/libs/freetype2/src/cff/cffload.c index dd2f1133dca..1e7dd143646 100644 --- a/Build/source/libs/freetype2/src/cff/cffload.c +++ b/Build/source/libs/freetype2/src/cff/cffload.c @@ -31,6 +31,7 @@ #if 1 + static const FT_UShort cff_isoadobe_charset[229] = { 0, 1, 2, 3, 4, 5, 6, 7, @@ -175,13 +176,15 @@ 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378 }; -#endif + +#endif /* 1 */ FT_LOCAL_DEF( FT_UShort ) cff_get_standard_encoding( FT_UInt charcode ) { - return (FT_UShort)(charcode < 256 ? cff_standard_encoding[charcode] : 0); + return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode] + : 0 ); } @@ -1272,8 +1275,9 @@ top->cid_ordering = 0xFFFFU; top->cid_font_name = 0xFFFFU; - error = cff_index_access_element( idx, font_index, &dict, &dict_len ) || - cff_parser_run( &parser, dict, dict + dict_len ); + error = cff_index_access_element( idx, font_index, &dict, &dict_len ); + if ( !error ) + error = cff_parser_run( &parser, dict, dict + dict_len ); cff_index_forget_element( idx, &dict ); @@ -1590,6 +1594,9 @@ FT_FREE( font->font_info ); } + FT_FREE( font->registry ); + FT_FREE( font->ordering ); + FT_FREE( font->global_subrs ); FT_FREE( font->font_name ); } diff --git a/Build/source/libs/freetype2/src/cff/cffobjs.c b/Build/source/libs/freetype2/src/cff/cffobjs.c index c02cf33fc8b..12997a94bcd 100644 --- a/Build/source/libs/freetype2/src/cff/cffobjs.c +++ b/Build/source/libs/freetype2/src/cff/cffobjs.c @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -56,7 +56,7 @@ cff_size_get_globals_funcs( CFF_Size size ) { CFF_Face face = (CFF_Face)size->root.face; - CFF_Font font = (CFF_FontRec *)face->extra.data; + CFF_Font font = (CFF_Font)face->extra.data; PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; FT_Module module; @@ -72,23 +72,84 @@ FT_LOCAL_DEF( void ) cff_size_done( FT_Size cffsize ) /* CFF_Size */ { - CFF_Size size = (CFF_Size)cffsize; + CFF_Size size = (CFF_Size)cffsize; + CFF_Face face = (CFF_Face)size->root.face; + CFF_Font font = (CFF_Font)face->extra.data; + CFF_Internal internal = (CFF_Internal)cffsize->internal; - if ( cffsize->internal ) + if ( internal ) { PSH_Globals_Funcs funcs; funcs = cff_size_get_globals_funcs( size ); if ( funcs ) - funcs->destroy( (PSH_Globals)cffsize->internal ); + { + FT_UInt i; + + + funcs->destroy( internal->topfont ); - cffsize->internal = 0; + for ( i = font->num_subfonts; i > 0; i-- ) + funcs->destroy( internal->subfonts[i - 1] ); + } + + /* `internal' is freed by destroy_size (in ftobjs.c) */ } } + /* CFF and Type 1 private dictionaries have slightly different */ + /* structures; we need to synthetize a Type 1 dictionary on the fly */ + + static void + cff_make_private_dict( CFF_SubFont subfont, + PS_Private priv ) + { + CFF_Private cpriv = &subfont->private_dict; + FT_UInt n, count; + + + FT_MEM_ZERO( priv, sizeof ( *priv ) ); + + count = priv->num_blue_values = cpriv->num_blue_values; + for ( n = 0; n < count; n++ ) + priv->blue_values[n] = (FT_Short)cpriv->blue_values[n]; + + count = priv->num_other_blues = cpriv->num_other_blues; + for ( n = 0; n < count; n++ ) + priv->other_blues[n] = (FT_Short)cpriv->other_blues[n]; + + count = priv->num_family_blues = cpriv->num_family_blues; + for ( n = 0; n < count; n++ ) + priv->family_blues[n] = (FT_Short)cpriv->family_blues[n]; + + count = priv->num_family_other_blues = cpriv->num_family_other_blues; + for ( n = 0; n < count; n++ ) + priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n]; + + priv->blue_scale = cpriv->blue_scale; + priv->blue_shift = (FT_Int)cpriv->blue_shift; + priv->blue_fuzz = (FT_Int)cpriv->blue_fuzz; + + priv->standard_width[0] = (FT_UShort)cpriv->standard_width; + priv->standard_height[0] = (FT_UShort)cpriv->standard_height; + + count = priv->num_snap_widths = cpriv->num_snap_widths; + for ( n = 0; n < count; n++ ) + priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n]; + + count = priv->num_snap_heights = cpriv->num_snap_heights; + for ( n = 0; n < count; n++ ) + priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n]; + + priv->force_bold = cpriv->force_bold; + priv->language_group = cpriv->language_group; + priv->lenIV = cpriv->lenIV; + } + + FT_LOCAL_DEF( FT_Error ) cff_size_init( FT_Size cffsize ) /* CFF_Size */ { @@ -99,68 +160,43 @@ if ( funcs ) { - PSH_Globals globals; - CFF_Face face = (CFF_Face)cffsize->face; - CFF_Font font = (CFF_FontRec *)face->extra.data; - CFF_SubFont subfont = &font->top_font; + CFF_Face face = (CFF_Face)cffsize->face; + CFF_Font font = (CFF_Font)face->extra.data; + CFF_Internal internal; - CFF_Private cpriv = &subfont->private_dict; PS_PrivateRec priv; + FT_Memory memory = cffsize->face->memory; + FT_UInt i; - /* IMPORTANT: The CFF and Type1 private dictionaries have */ - /* slightly different structures; we need to */ - /* synthetize a type1 dictionary on the fly here. */ - - { - FT_UInt n, count; - - - FT_MEM_ZERO( &priv, sizeof ( priv ) ); - - count = priv.num_blue_values = cpriv->num_blue_values; - for ( n = 0; n < count; n++ ) - priv.blue_values[n] = (FT_Short)cpriv->blue_values[n]; - - count = priv.num_other_blues = cpriv->num_other_blues; - for ( n = 0; n < count; n++ ) - priv.other_blues[n] = (FT_Short)cpriv->other_blues[n]; - count = priv.num_family_blues = cpriv->num_family_blues; - for ( n = 0; n < count; n++ ) - priv.family_blues[n] = (FT_Short)cpriv->family_blues[n]; - - count = priv.num_family_other_blues = cpriv->num_family_other_blues; - for ( n = 0; n < count; n++ ) - priv.family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n]; - - priv.blue_scale = cpriv->blue_scale; - priv.blue_shift = (FT_Int)cpriv->blue_shift; - priv.blue_fuzz = (FT_Int)cpriv->blue_fuzz; + if ( FT_NEW( internal ) ) + goto Exit; - priv.standard_width[0] = (FT_UShort)cpriv->standard_width; - priv.standard_height[0] = (FT_UShort)cpriv->standard_height; + cff_make_private_dict( &font->top_font, &priv ); + error = funcs->create( cffsize->face->memory, &priv, + &internal->topfont ); + if ( error ) + goto Exit; - count = priv.num_snap_widths = cpriv->num_snap_widths; - for ( n = 0; n < count; n++ ) - priv.snap_widths[n] = (FT_Short)cpriv->snap_widths[n]; + for ( i = font->num_subfonts; i > 0; i-- ) + { + CFF_SubFont sub = font->subfonts[i - 1]; - count = priv.num_snap_heights = cpriv->num_snap_heights; - for ( n = 0; n < count; n++ ) - priv.snap_heights[n] = (FT_Short)cpriv->snap_heights[n]; - priv.force_bold = cpriv->force_bold; - priv.language_group = cpriv->language_group; - priv.lenIV = cpriv->lenIV; + cff_make_private_dict( sub, &priv ); + error = funcs->create( cffsize->face->memory, &priv, + &internal->subfonts[i - 1] ); + if ( error ) + goto Exit; } - error = funcs->create( cffsize->face->memory, &priv, &globals ); - if ( !error ) - cffsize->internal = (FT_Size_Internal)(void*)globals; + cffsize->internal = (FT_Size_Internal)(void*)internal; } size->strike_index = 0xFFFFFFFFUL; + Exit: return error; } @@ -182,11 +218,42 @@ funcs = cff_size_get_globals_funcs( cffsize ); if ( funcs ) - funcs->set_scale( (PSH_Globals)size->internal, - size->metrics.x_scale, - size->metrics.y_scale, + { + CFF_Face face = (CFF_Face)size->face; + CFF_Font font = (CFF_Font)face->extra.data; + CFF_Internal internal = (CFF_Internal)size->internal; + + FT_Int top_upm = font->top_font.font_dict.units_per_em; + FT_UInt i; + + + funcs->set_scale( internal->topfont, + size->metrics.x_scale, size->metrics.y_scale, 0, 0 ); + for ( i = font->num_subfonts; i > 0; i-- ) + { + CFF_SubFont sub = font->subfonts[i - 1]; + FT_Int sub_upm = sub->font_dict.units_per_em; + FT_Pos x_scale, y_scale; + + + if ( top_upm != sub_upm ) + { + x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm ); + y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm ); + } + else + { + x_scale = size->metrics.x_scale; + y_scale = size->metrics.y_scale; + } + + funcs->set_scale( internal->subfonts[i - 1], + x_scale, y_scale, 0, 0 ); + } + } + return CFF_Err_Ok; } @@ -223,11 +290,42 @@ funcs = cff_size_get_globals_funcs( cffsize ); if ( funcs ) - funcs->set_scale( (PSH_Globals)size->internal, - size->metrics.x_scale, - size->metrics.y_scale, + { + CFF_Face cffface = (CFF_Face)size->face; + CFF_Font font = (CFF_Font)cffface->extra.data; + CFF_Internal internal = (CFF_Internal)size->internal; + + FT_Int top_upm = font->top_font.font_dict.units_per_em; + FT_UInt i; + + + funcs->set_scale( internal->topfont, + size->metrics.x_scale, size->metrics.y_scale, 0, 0 ); + for ( i = font->num_subfonts; i > 0; i-- ) + { + CFF_SubFont sub = font->subfonts[i - 1]; + FT_Int sub_upm = sub->font_dict.units_per_em; + FT_Pos x_scale, y_scale; + + + if ( top_upm != sub_upm ) + { + x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm ); + y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm ); + } + else + { + x_scale = size->metrics.x_scale; + y_scale = size->metrics.y_scale; + } + + funcs->set_scale( internal->subfonts[i - 1], + x_scale, y_scale, 0, 0 ); + } + } + return CFF_Err_Ok; } @@ -249,7 +347,7 @@ cff_slot_init( FT_GlyphSlot slot ) { CFF_Face face = (CFF_Face)slot->face; - CFF_Font font = (CFF_FontRec *)face->extra.data; + CFF_Font font = (CFF_Font)face->extra.data; PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; @@ -270,7 +368,7 @@ } } - return 0; + return CFF_Err_Ok; } @@ -288,7 +386,9 @@ FT_String* result; - result = ft_mem_strdup( memory, source, &error ); + (void)FT_STRDUP( result, source ); + + FT_UNUSED( error ); return result; } @@ -444,7 +544,7 @@ /* compute number of glyphs */ if ( dict->cid_registry != 0xFFFFU ) - cffface->num_glyphs = dict->cid_count; + cffface->num_glyphs = cff->charset.max_cid; else cffface->num_glyphs = cff->charstrings_index.count; @@ -617,39 +717,119 @@ dict->units_per_em = face->root.units_per_EM; } - /* handle font matrix settings in subfonts (if any) */ + /* Normalize the font matrix so that `matrix->xx' is 1; the */ + /* scaling is done with `units_per_em' then (at this point, */ + /* it already contains the scaling factor, but without */ + /* normalization of the matrix). */ + /* */ + /* Note that the offsets must be expressed in integer font */ + /* units. */ + + { + FT_Matrix* matrix = &dict->font_matrix; + FT_Vector* offset = &dict->font_offset; + FT_ULong* upm = &dict->units_per_em; + FT_Fixed temp = FT_ABS( matrix->yy ); + + + if ( temp != 0x10000L ) + { + *upm = FT_DivFix( *upm, temp ); + + matrix->xx = FT_DivFix( matrix->xx, temp ); + matrix->yx = FT_DivFix( matrix->yx, temp ); + matrix->xy = FT_DivFix( matrix->xy, temp ); + matrix->yy = FT_DivFix( matrix->yy, temp ); + offset->x = FT_DivFix( offset->x, temp ); + offset->y = FT_DivFix( offset->y, temp ); + } + + offset->x >>= 16; + offset->y >>= 16; + } + for ( i = cff->num_subfonts; i > 0; i-- ) { CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict; CFF_FontRecDict top = &cff->top_font.font_dict; + FT_Matrix* matrix; + FT_Vector* offset; + FT_ULong* upm; + FT_Fixed temp; + if ( sub->units_per_em ) { - FT_Matrix scale; + FT_Int scaling; - scale.xx = scale.yy = (FT_Fixed)FT_DivFix( top->units_per_em, - sub->units_per_em ); - scale.xy = scale.yx = 0; - - FT_Matrix_Multiply( &scale, &sub->font_matrix ); - FT_Vector_Transform( &sub->font_offset, &scale ); + if ( top->units_per_em > 1 && sub->units_per_em > 1 ) + scaling = FT_MIN( top->units_per_em, sub->units_per_em ); + else + scaling = 1; + + FT_Matrix_Multiply_Scaled( &top->font_matrix, + &sub->font_matrix, + scaling ); + FT_Vector_Transform_Scaled( &sub->font_offset, + &top->font_matrix, + scaling ); + + sub->units_per_em = FT_MulDiv( sub->units_per_em, + top->units_per_em, + scaling ); } else { sub->font_matrix = top->font_matrix; sub->font_offset = top->font_offset; + + sub->units_per_em = top->units_per_em; } + + matrix = &sub->font_matrix; + offset = &sub->font_offset; + upm = &sub->units_per_em; + temp = FT_ABS( matrix->yy ); + + if ( temp != 0x10000L ) + { + *upm = FT_DivFix( *upm, temp ); + + /* if *upm is larger than 100*1000 we divide by 1000 -- */ + /* this can happen if e.g. there is no top-font FontMatrix */ + /* and the subfont FontMatrix already contains the complete */ + /* scaling for the subfont (see section 5.11 of the PLRM) */ + + /* 100 is a heuristic value */ + + if ( *upm > 100L * 1000L ) + *upm = ( *upm + 500 ) / 1000; + + matrix->xx = FT_DivFix( matrix->xx, temp ); + matrix->yx = FT_DivFix( matrix->yx, temp ); + matrix->xy = FT_DivFix( matrix->xy, temp ); + matrix->yy = FT_DivFix( matrix->yy, temp ); + offset->x = FT_DivFix( offset->x, temp ); + offset->y = FT_DivFix( offset->y, temp ); + } + + offset->x >>= 16; + offset->y >>= 16; } #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */ - /* has unset this flag because of the 3.0 `post' table */ + /* has unset this flag because of the 3.0 `post' table. */ if ( dict->cid_registry == 0xFFFFU ) cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; #endif + if ( dict->cid_registry != 0xFFFFU ) + cffface->face_flags |= FT_FACE_FLAG_CID_KEYED; + + /*******************************************************************/ /* */ /* Compute char maps. */ @@ -683,7 +863,7 @@ if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU ) goto Exit; - /* we didn't find a Unicode charmap -- synthetize one */ + /* we didn't find a Unicode charmap -- synthesize one */ cmaprec.face = cffface; cmaprec.platform_id = 3; cmaprec.encoding_id = 1; diff --git a/Build/source/libs/freetype2/src/cff/cffobjs.h b/Build/source/libs/freetype2/src/cff/cffobjs.h index f18b5d9322d..3c81cee0094 100644 --- a/Build/source/libs/freetype2/src/cff/cffobjs.h +++ b/Build/source/libs/freetype2/src/cff/cffobjs.h @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,6 +25,7 @@ #include "cfftypes.h" #include FT_INTERNAL_TRUETYPE_TYPES_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H FT_BEGIN_HEADER @@ -53,8 +54,8 @@ FT_BEGIN_HEADER /* */ typedef struct CFF_SizeRec_ { - FT_SizeRec root; - FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */ + FT_SizeRec root; + FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */ } CFF_SizeRec, *CFF_Size; @@ -80,6 +81,21 @@ FT_BEGIN_HEADER } CFF_GlyphSlotRec, *CFF_GlyphSlot; + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_Internal */ + /* */ + /* <Description> */ + /* The interface to the `internal' field of `FT_Size'. */ + /* */ + typedef struct CFF_InternalRec_ + { + PSH_Globals topfont; + PSH_Globals subfonts[CFF_MAX_CID_FONTS]; + + } CFF_InternalRec, *CFF_Internal; + /*************************************************************************/ /* */ diff --git a/Build/source/libs/freetype2/src/cff/cffparse.c b/Build/source/libs/freetype2/src/cff/cffparse.c index 41af6a317f1..d6d77dd08da 100644 --- a/Build/source/libs/freetype2/src/cff/cffparse.c +++ b/Build/source/libs/freetype2/src/cff/cffparse.c @@ -4,7 +4,7 @@ /* */ /* CFF token stream parser (body) */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,6 +19,7 @@ #include <ft2build.h> #include "cffparse.h" #include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_DEBUG_H #include "cfferrs.h" @@ -136,24 +137,51 @@ } + static const FT_Long power_tens[] = + { + 1L, + 10L, + 100L, + 1000L, + 10000L, + 100000L, + 1000000L, + 10000000L, + 100000000L, + 1000000000L + }; + + /* read a real */ static FT_Fixed cff_parse_real( FT_Byte* start, FT_Byte* limit, - FT_Int power_ten ) + FT_Int power_ten, + FT_Int* scaling ) { - FT_Byte* p = start; - FT_Long num, divider, result, exponent; - FT_Int sign = 0, exponent_sign = 0; + FT_Byte* p = start; FT_UInt nib; FT_UInt phase; + FT_Long result, number, rest, exponent; + FT_Int sign = 0, exponent_sign = 0; + FT_Int exponent_add, integer_length, fraction_length; + + + if ( scaling ) + *scaling = 0; + + result = 0; + + number = 0; + rest = 0; + exponent = 0; - result = 0; - num = 0; - divider = 1; + exponent_add = 0; + integer_length = 0; + fraction_length = 0; - /* first of all, read the integer part */ + /* First of all, read the integer part. */ phase = 4; for (;;) @@ -166,7 +194,7 @@ /* Make sure we don't read past the end. */ if ( p >= limit ) - goto Bad; + goto Exit; } /* Get the nibble. */ @@ -178,10 +206,20 @@ else if ( nib > 9 ) break; else - result = result * 10 + nib; + { + /* Increase exponent if we can't add the digit. */ + if ( number >= 0xCCCCCCCL ) + exponent_add++; + /* Skip leading zeros. */ + else if ( nib || number ) + { + integer_length++; + number = number * 10 + nib; + } + } } - /* read decimal part, if any */ + /* Read fraction part, if any. */ if ( nib == 0xa ) for (;;) { @@ -193,7 +231,7 @@ /* Make sure we don't read past the end. */ if ( p >= limit ) - goto Bad; + goto Exit; } /* Get the nibble. */ @@ -202,14 +240,18 @@ if ( nib >= 10 ) break; - if ( divider < 10000000L ) + /* Skip leading zeros if possible. */ + if ( !nib && !number ) + exponent_add--; + /* Only add digit if we don't overflow. */ + else if ( number < 0xCCCCCCCL ) { - num = num * 10 + nib; - divider *= 10; + fraction_length++; + number = number * 10 + nib; } } - /* read exponent, if any */ + /* Read exponent, if any. */ if ( nib == 12 ) { exponent_sign = 1; @@ -218,19 +260,17 @@ if ( nib == 11 ) { - exponent = 0; - for (;;) { - /* If we entered this iteration with phase == 4, we need */ - /* to read a new byte. */ + /* If we entered this iteration with phase == 4, */ + /* we need to read a new byte. */ if ( phase ) { p++; /* Make sure we don't read past the end. */ if ( p >= limit ) - goto Bad; + goto Exit; } /* Get the nibble. */ @@ -240,47 +280,105 @@ break; exponent = exponent * 10 + nib; + + /* Arbitrarily limit exponent. */ + if ( exponent > 1000 ) + goto Exit; } if ( exponent_sign ) exponent = -exponent; - - power_ten += (FT_Int)exponent; } - /* raise to power of ten if needed */ - while ( power_ten > 0 ) + /* We don't check `power_ten' and `exponent_add'. */ + exponent += power_ten + exponent_add; + + if ( scaling ) { - result = result * 10; - num = num * 10; + /* Only use `fraction_length'. */ + fraction_length += integer_length; + exponent += integer_length; - power_ten--; - } + if ( fraction_length <= 5 ) + { + if ( number > 0x7FFFL ) + { + result = FT_DivFix( number, 10 ); + *scaling = exponent - fraction_length + 1; + } + else + { + if ( exponent > 0 ) + { + FT_Int new_fraction_length, shift; - while ( power_ten < 0 ) - { - result = result / 10; - divider = divider * 10; - power_ten++; + /* Make `scaling' as small as possible. */ + new_fraction_length = FT_MIN( exponent, 5 ); + exponent -= new_fraction_length; + shift = new_fraction_length - fraction_length; + + number *= power_tens[shift]; + if ( number > 0x7FFFL ) + { + number /= 10; + exponent += 1; + } + } + else + exponent -= fraction_length; + + result = number << 16; + *scaling = exponent; + } + } + else + { + if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL ) + { + result = FT_DivFix( number, power_tens[fraction_length - 4] ); + *scaling = exponent - 4; + } + else + { + result = FT_DivFix( number, power_tens[fraction_length - 5] ); + *scaling = exponent - 5; + } + } } + else + { + integer_length += exponent; + fraction_length -= exponent; + + /* Check for overflow and underflow. */ + if ( FT_ABS( integer_length ) > 5 ) + goto Exit; - /* Move the integer part into the high 16 bits. */ - result <<= 16; + /* Convert into 16.16 format. */ + if ( fraction_length > 0 ) + { + if ( ( number / power_tens[fraction_length] ) > 0x7FFFL ) + goto Exit; + + result = FT_DivFix( number, power_tens[fraction_length] ); + } + else + { + number *= power_tens[-fraction_length]; + + if ( number > 0x7FFFL ) + goto Exit; - /* Place the decimal part into the low 16 bits. */ - if ( num ) - result |= FT_DivFix( num, divider ); + result = number << 16; + } + } if ( sign ) result = -result; Exit: return result; - - Bad: - result = 0; - goto Exit; } @@ -288,8 +386,8 @@ static FT_Long cff_parse_num( FT_Byte** d ) { - return ( **d == 30 ? ( cff_parse_real ( d[0], d[1], 0 ) >> 16 ) - : cff_parse_integer( d[0], d[1] ) ); + return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 ) + : cff_parse_integer( d[0], d[1] ); } @@ -297,64 +395,121 @@ static FT_Fixed cff_parse_fixed( FT_Byte** d ) { - return ( **d == 30 ? cff_parse_real ( d[0], d[1], 0 ) - : cff_parse_integer( d[0], d[1] ) << 16 ); + return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL ) + : cff_parse_integer( d[0], d[1] ) << 16; } + /* read a floating point number, either integer or real, */ - /* but return 1000 times the number read in. */ + /* but return `10^scaling' times the number read in */ static FT_Fixed - cff_parse_fixed_thousand( FT_Byte** d ) + cff_parse_fixed_scaled( FT_Byte** d, + FT_Int scaling ) { return **d == - 30 ? cff_parse_real ( d[0], d[1], 3 ) - : (FT_Fixed)FT_MulFix( cff_parse_integer( d[0], d[1] ) << 16, 1000 ); + 30 ? cff_parse_real( d[0], d[1], scaling, NULL ) + : (FT_Fixed)FT_MulFix( cff_parse_integer( d[0], d[1] ) << 16, + power_tens[scaling] ); } + + /* read a floating point number, either integer or real, */ + /* and return it as precise as possible -- `scaling' returns */ + /* the scaling factor (as a power of 10) */ + static FT_Fixed + cff_parse_fixed_dynamic( FT_Byte** d, + FT_Int* scaling ) + { + FT_ASSERT( scaling ); + + if ( **d == 30 ) + return cff_parse_real( d[0], d[1], 0, scaling ); + else + { + FT_Long number; + FT_Int integer_length; + + + number = cff_parse_integer( d[0], d[1] ); + + if ( number > 0x7FFFL ) + { + for ( integer_length = 5; integer_length < 10; integer_length++ ) + if ( number < power_tens[integer_length] ) + break; + + if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL ) + { + *scaling = integer_length - 4; + return FT_DivFix( number, power_tens[integer_length - 4] ); + } + else + { + *scaling = integer_length - 5; + return FT_DivFix( number, power_tens[integer_length - 5] ); + } + } + else + { + *scaling = 0; + return number << 16; + } + } + } + + static FT_Error cff_parse_font_matrix( CFF_Parser parser ) { CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; FT_Matrix* matrix = &dict->font_matrix; FT_Vector* offset = &dict->font_offset; - FT_UShort* upm = &dict->units_per_em; + FT_ULong* upm = &dict->units_per_em; FT_Byte** data = parser->stack; - FT_Error error; - FT_Fixed temp; + FT_Error error = CFF_Err_Stack_Underflow; - error = CFF_Err_Stack_Underflow; - if ( parser->top >= parser->stack + 6 ) { - matrix->xx = cff_parse_fixed_thousand( data++ ); - matrix->yx = cff_parse_fixed_thousand( data++ ); - matrix->xy = cff_parse_fixed_thousand( data++ ); - matrix->yy = cff_parse_fixed_thousand( data++ ); - offset->x = cff_parse_fixed_thousand( data++ ); - offset->y = cff_parse_fixed_thousand( data ); + FT_Int scaling; - temp = FT_ABS( matrix->yy ); - *upm = (FT_UShort)FT_DivFix( 0x10000L, FT_DivFix( temp, 1000 ) ); + error = CFF_Err_Ok; - if ( temp != 0x10000L ) + /* We expect a well-formed font matrix, this is, the matrix elements */ + /* `xx' and `yy' are of approximately the same magnitude. To avoid */ + /* loss of precision, we use the magnitude of element `xx' to scale */ + /* all other elements. The scaling factor is then contained in the */ + /* `units_per_em' value. */ + + matrix->xx = cff_parse_fixed_dynamic( data++, &scaling ); + + scaling = -scaling; + + if ( scaling < 0 || scaling > 9 ) { - matrix->xx = FT_DivFix( matrix->xx, temp ); - matrix->yx = FT_DivFix( matrix->yx, temp ); - matrix->xy = FT_DivFix( matrix->xy, temp ); - matrix->yy = FT_DivFix( matrix->yy, temp ); - offset->x = FT_DivFix( offset->x, temp ); - offset->y = FT_DivFix( offset->y, temp ); + /* Return default matrix in case of unlikely values. */ + matrix->xx = 0x10000L; + matrix->yx = 0; + matrix->yx = 0; + matrix->yy = 0x10000L; + offset->x = 0; + offset->y = 0; + *upm = 1; + + goto Exit; } - /* note that the offsets must be expressed in integer font units */ - offset->x >>= 16; - offset->y >>= 16; + matrix->yx = cff_parse_fixed_scaled( data++, scaling ); + matrix->xy = cff_parse_fixed_scaled( data++, scaling ); + matrix->yy = cff_parse_fixed_scaled( data++, scaling ); + offset->x = cff_parse_fixed_scaled( data++, scaling ); + offset->y = cff_parse_fixed_scaled( data, scaling ); - error = CFF_Err_Ok; + *upm = power_tens[scaling]; } + Exit: return error; } @@ -585,7 +740,7 @@ goto Store_Number; case cff_kind_fixed_thousand: - val = cff_parse_fixed_thousand( parser->stack ); + val = cff_parse_fixed_scaled( parser->stack, 3 ); Store_Number: switch ( field->size ) diff --git a/Build/source/libs/freetype2/src/cff/cfftypes.h b/Build/source/libs/freetype2/src/cff/cfftypes.h index 306e5aab670..546ea3b99d4 100644 --- a/Build/source/libs/freetype2/src/cff/cfftypes.h +++ b/Build/source/libs/freetype2/src/cff/cfftypes.h @@ -5,7 +5,7 @@ /* Basic OpenType/CFF type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -114,7 +114,7 @@ FT_BEGIN_HEADER FT_Int paint_type; FT_Int charstring_type; FT_Matrix font_matrix; - FT_UShort units_per_em; + FT_ULong units_per_em; /* temporarily used as scaling value also */ FT_Vector font_offset; FT_ULong unique_id; FT_BBox font_bbox; @@ -259,6 +259,10 @@ FT_BEGIN_HEADER /* since version 2.3.0 */ PS_FontInfoRec* font_info; /* font info dictionary */ + /* since version 2.3.6 */ + FT_String* registry; + FT_String* ordering; + } CFF_FontRec, *CFF_Font; diff --git a/Build/source/libs/freetype2/src/cid/cidgload.c b/Build/source/libs/freetype2/src/cid/cidgload.c index 8bec6e187b4..64994b44194 100644 --- a/Build/source/libs/freetype2/src/cid/cidgload.c +++ b/Build/source/libs/freetype2/src/cid/cidgload.c @@ -74,7 +74,7 @@ if ( glyph_data.length != 0 ) { glyph_length = glyph_data.length - cid->fd_bytes; - FT_ALLOC( charstring, glyph_length ); + (void)FT_ALLOC( charstring, glyph_length ); if ( !error ) ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes, glyph_length ); diff --git a/Build/source/libs/freetype2/src/cid/cidriver.c b/Build/source/libs/freetype2/src/cid/cidriver.c index 5c5a72957c0..85ee6cf1915 100644 --- a/Build/source/libs/freetype2/src/cid/cidriver.c +++ b/Build/source/libs/freetype2/src/cid/cidriver.c @@ -4,7 +4,7 @@ /* */ /* CID driver interface (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,6 +27,8 @@ #include FT_SERVICE_POSTSCRIPT_NAME_H #include FT_SERVICE_XFREE86_NAME_H #include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_CID_H + /*************************************************************************/ /* */ @@ -38,10 +40,10 @@ #define FT_COMPONENT trace_ciddriver - /* - * POSTSCRIPT NAME SERVICE - * - */ + /* + * POSTSCRIPT NAME SERVICE + * + */ static const char* cid_get_postscript_name( CID_Face face ) @@ -62,10 +64,10 @@ }; - /* - * POSTSCRIPT INFO SERVICE - * - */ + /* + * POSTSCRIPT INFO SERVICE + * + */ static FT_Error cid_ps_get_font_info( FT_Face face, @@ -84,16 +86,49 @@ }; - /* - * SERVICE LIST - * - */ + /* + * CID INFO SERVICE + * + */ + static FT_Error + cid_get_ros( CID_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ) + { + CID_FaceInfo cid = &face->cid; + + + if ( registry ) + *registry = cid->registry; + + if ( ordering ) + *ordering = cid->ordering; + + if ( supplement ) + *supplement = cid->supplement; + + return CID_Err_Ok; + } + + + static const FT_Service_CIDRec cid_service_cid_info = + { + (FT_CID_GetRegistryOrderingSupplementFunc)cid_get_ros + }; + + + /* + * SERVICE LIST + * + */ static const FT_ServiceDescRec cid_services[] = { - { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name }, { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CID }, + { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name }, { FT_SERVICE_ID_POSTSCRIPT_INFO, &cid_service_ps_info }, + { FT_SERVICE_ID_CID, &cid_service_cid_info }, { NULL, NULL } }; diff --git a/Build/source/libs/freetype2/src/gxvalid/gxvfeat.c b/Build/source/libs/freetype2/src/gxvalid/gxvfeat.c index d7c6ad166d5..ad30a764c64 100644 --- a/Build/source/libs/freetype2/src/gxvalid/gxvfeat.c +++ b/Build/source/libs/freetype2/src/gxvalid/gxvfeat.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT feat table validation (body). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004, 2005, 2008 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -59,7 +60,7 @@ #define GXV_FEAT_DATA( field ) GXV_TABLE_DATA( feat, field ) - typedef enum + typedef enum GXV_FeatureFlagsMask_ { GXV_FEAT_MASK_EXCLUSIVE_SETTINGS = 0x8000U, GXV_FEAT_MASK_DYNAMIC_DEFAULT = 0x4000, diff --git a/Build/source/libs/freetype2/src/gxvalid/gxvmort1.c b/Build/source/libs/freetype2/src/gxvalid/gxvmort1.c index 0575b1260ac..711bbd0baa6 100644 --- a/Build/source/libs/freetype2/src/gxvalid/gxvmort1.c +++ b/Build/source/libs/freetype2/src/gxvalid/gxvmort1.c @@ -202,7 +202,7 @@ if ( dst_gid > valid->face->num_glyphs ) { - GXV_TRACE(( "substTable include toolarge gid[%d]=%d >" + GXV_TRACE(( "substTable include too large gid[%d]=%d >" " max defined gid #%d\n", i, dst_gid, valid->face->num_glyphs )); if ( valid->root->level >= FT_VALIDATE_PARANOID ) diff --git a/Build/source/libs/freetype2/src/lzw/ftzopen.h b/Build/source/libs/freetype2/src/lzw/ftzopen.h index 97881149c22..dd602402ac0 100644 --- a/Build/source/libs/freetype2/src/lzw/ftzopen.h +++ b/Build/source/libs/freetype2/src/lzw/ftzopen.h @@ -8,7 +8,7 @@ /* be used to parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2005, 2006, 2007 by David Turner. */ +/* Copyright 2005, 2006, 2007, 2008 by David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -46,7 +46,7 @@ #define LZW_MASK( n ) ( ( 1U << (n) ) - 1U ) - typedef enum + typedef enum FT_LzwPhase_ { FT_LZW_PHASE_START = 0, FT_LZW_PHASE_CODE, @@ -109,7 +109,7 @@ * `free_ent', `num_bits' cannot grow larger than `max_bits'. */ - typedef struct _FT_LzwStateRec + typedef struct FT_LzwStateRec_ { FT_LzwPhase phase; FT_Int in_eof; diff --git a/Build/source/libs/freetype2/src/otvalid/otvalid.c b/Build/source/libs/freetype2/src/otvalid/otvalid.c index 2f85f601b66..d5c2b75abb6 100644 --- a/Build/source/libs/freetype2/src/otvalid/otvalid.c +++ b/Build/source/libs/freetype2/src/otvalid/otvalid.c @@ -4,7 +4,7 @@ /* */ /* FreeType validator for OpenType tables (body only). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,6 +25,7 @@ #include "otvgpos.c" #include "otvgsub.c" #include "otvjstf.c" +#include "otvmath.c" #include "otvmod.c" /* END */ diff --git a/Build/source/libs/freetype2/src/otvalid/otvalid.h b/Build/source/libs/freetype2/src/otvalid/otvalid.h index 38f030f3935..90255cdbad5 100644 --- a/Build/source/libs/freetype2/src/otvalid/otvalid.h +++ b/Build/source/libs/freetype2/src/otvalid/otvalid.h @@ -4,7 +4,7 @@ /* */ /* OpenType table validation (specification only). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -63,6 +63,11 @@ FT_BEGIN_HEADER FT_UInt glyph_count, FT_Validator valid ); + FT_LOCAL( void ) + otv_MATH_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator ftvalid ); + FT_END_HEADER diff --git a/Build/source/libs/freetype2/src/otvalid/otvbase.c b/Build/source/libs/freetype2/src/otvalid/otvbase.c index 8ad2238d6d6..d742d2dc95f 100644 --- a/Build/source/libs/freetype2/src/otvalid/otvbase.c +++ b/Build/source/libs/freetype2/src/otvalid/otvbase.c @@ -4,7 +4,7 @@ /* */ /* OpenType BASE table validation (body). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -62,7 +62,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -297,7 +297,7 @@ OTV_LIMIT_CHECK( 6 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_DATA; + FT_INVALID_FORMAT; table_size = 6; diff --git a/Build/source/libs/freetype2/src/otvalid/otvcommn.c b/Build/source/libs/freetype2/src/otvalid/otvcommn.c index d94e4f3cb62..a4f885b51f8 100644 --- a/Build/source/libs/freetype2/src/otvalid/otvcommn.c +++ b/Build/source/libs/freetype2/src/otvalid/otvcommn.c @@ -4,7 +4,7 @@ /* */ /* OpenType common tables validation (body). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,10 +39,12 @@ FT_LOCAL_DEF( void ) otv_Coverage_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator valid, + FT_Int expected_count ) { FT_Bytes p = table; FT_UInt CoverageFormat; + FT_UInt total = 0; OTV_NAME_ENTER( "Coverage" ); @@ -57,6 +59,7 @@ case 1: /* CoverageFormat1 */ { FT_UInt GlyphCount; + FT_UInt i; GlyphCount = FT_NEXT_USHORT( p ); @@ -64,13 +67,25 @@ OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); OTV_LIMIT_CHECK( GlyphCount * 2 ); /* GlyphArray */ + + for ( i = 0; i < GlyphCount; ++i ) + { + FT_UInt gid; + + + gid = FT_NEXT_USHORT( p ); + if ( gid >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + } + + total = GlyphCount; } break; case 2: /* CoverageFormat2 */ { FT_UInt n, RangeCount; - FT_UInt Start, End, StartCoverageIndex, total = 0, last = 0; + FT_UInt Start, End, StartCoverageIndex, last = 0; RangeCount = FT_NEXT_USHORT( p ); @@ -89,6 +104,9 @@ if ( Start > End || StartCoverageIndex != total ) FT_INVALID_DATA; + if ( End >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + if ( n > 0 && Start <= last ) FT_INVALID_DATA; @@ -102,8 +120,11 @@ FT_INVALID_FORMAT; } - /* no need to check glyph indices used as input to coverage tables */ - /* since even invalid glyph indices return a meaningful result */ + /* Generally, a coverage table offset has an associated count field. */ + /* The number of glyphs in the table should match this field. If */ + /* there is no associated count, a value of -1 tells us not to check. */ + if ( expected_count != -1 && (FT_UInt)expected_count != total ) + FT_INVALID_DATA; OTV_EXIT; } @@ -215,18 +236,21 @@ { case 1: /* ClassDefFormat1 */ { + FT_UInt StartGlyph; FT_UInt GlyphCount; - p += 2; /* skip StartGlyph */ - - OTV_LIMIT_CHECK( 2 ); + OTV_LIMIT_CHECK( 4 ); + StartGlyph = FT_NEXT_USHORT( p ); GlyphCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); OTV_LIMIT_CHECK( GlyphCount * 2 ); /* ClassValueArray */ + + if ( StartGlyph + GlyphCount - 1 >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; } break; @@ -252,6 +276,9 @@ if ( Start > End || ( n > 0 && Start <= last ) ) FT_INVALID_DATA; + if ( End >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + last = End; } } @@ -291,7 +318,10 @@ EndSize = FT_NEXT_USHORT( p ); DeltaFormat = FT_NEXT_USHORT( p ); - if ( DeltaFormat < 1 || DeltaFormat > 3 || EndSize < StartSize ) + if ( DeltaFormat < 1 || DeltaFormat > 3 ) + FT_INVALID_FORMAT; + + if ( EndSize < StartSize ) FT_INVALID_DATA; count = EndSize - StartSize + 1; @@ -330,7 +360,7 @@ OTV_TRACE(( " (type %d)\n", LookupType )); - if ( LookupType == 0 || LookupType >= valid->type_count ) + if ( LookupType == 0 || LookupType > valid->type_count ) FT_INVALID_DATA; validate = valid->type_funcs[LookupType - 1]; @@ -657,7 +687,7 @@ OTV_TRACE(( " (Count = %d)\n", Count )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, Count ); OTV_LIMIT_CHECK( Count * 2 ); @@ -729,6 +759,7 @@ FT_INVALID_DATA; OTV_LIMIT_CHECK( ( Count1 - 1 ) * 2 + Count2 * 4 ); + p += ( Count1 - 1 ) * 2; for ( ; Count2 > 0; Count2-- ) { @@ -824,7 +855,7 @@ OTV_TRACE(( " (ClassSetCount = %d)\n", ClassSetCount )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, -1 ); otv_ClassDef_validate( table + ClassDef, valid ); OTV_LIMIT_CHECK( ClassSetCount * 2 ); @@ -872,7 +903,7 @@ OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 ); for ( count1 = GlyphCount; count1 > 0; count1-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); for ( ; Count > 0; Count-- ) { @@ -913,7 +944,7 @@ OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, -1 ); otv_ClassDef_validate( table + BacktrackClassDef, valid ); otv_ClassDef_validate( table + InputClassDef, valid ); @@ -963,7 +994,7 @@ OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); InputGlyphCount = FT_NEXT_USHORT( p ); @@ -972,7 +1003,7 @@ OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 ); for ( count1 = InputGlyphCount; count1 > 0; count1-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); LookaheadGlyphCount = FT_NEXT_USHORT( p ); @@ -981,7 +1012,7 @@ OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); count2 = FT_NEXT_USHORT( p ); diff --git a/Build/source/libs/freetype2/src/otvalid/otvcommn.h b/Build/source/libs/freetype2/src/otvalid/otvcommn.h index be6ac69c284..7c06b16ffad 100644 --- a/Build/source/libs/freetype2/src/otvalid/otvcommn.h +++ b/Build/source/libs/freetype2/src/otvalid/otvcommn.h @@ -4,7 +4,7 @@ /* */ /* OpenType common tables validation (specification). */ /* */ -/* Copyright 2004, 2005 by */ +/* Copyright 2004, 2005, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -215,7 +215,8 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_Coverage_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator valid, + FT_Int expected_count ); /* return first covered glyph */ FT_LOCAL( FT_UInt ) diff --git a/Build/source/libs/freetype2/src/otvalid/otvgdef.c b/Build/source/libs/freetype2/src/otvalid/otvgdef.c index 7d24902e881..77bd651659c 100644 --- a/Build/source/libs/freetype2/src/otvalid/otvgdef.c +++ b/Build/source/libs/freetype2/src/otvalid/otvgdef.c @@ -4,7 +4,7 @@ /* */ /* OpenType GDEF table validation (body). */ /* */ -/* Copyright 2004, 2005 by */ +/* Copyright 2004, 2005, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -61,7 +61,7 @@ OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); - otv_Coverage_validate( Coverage, valid ); + otv_Coverage_validate( Coverage, valid, GlyphCount ); if ( GlyphCount != otv_Coverage_get_count( Coverage ) ) FT_INVALID_DATA; @@ -126,7 +126,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; diff --git a/Build/source/libs/freetype2/src/otvalid/otvgpos.c b/Build/source/libs/freetype2/src/otvalid/otvgpos.c index ed347053d65..220f714a9ea 100644 --- a/Build/source/libs/freetype2/src/otvalid/otvgpos.c +++ b/Build/source/libs/freetype2/src/otvalid/otvgpos.c @@ -4,7 +4,7 @@ /* */ /* OpenType GPOS table validation (body). */ /* */ -/* Copyright 2002, 2004, 2005, 2006 by */ +/* Copyright 2002, 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -124,8 +124,8 @@ Array1 = FT_NEXT_USHORT( p ); Array2 = FT_NEXT_USHORT( p ); - otv_Coverage_validate( table + Coverage1, valid ); - otv_Coverage_validate( table + Coverage2, valid ); + otv_Coverage_validate( table + Coverage1, valid, -1 ); + otv_Coverage_validate( table + Coverage2, valid, -1 ); otv_MarkArray_validate( table + Array1, valid ); @@ -191,7 +191,7 @@ #endif if ( format >= 0x100 ) - FT_INVALID_DATA; + FT_INVALID_FORMAT; for ( count = 4; count > 0; count-- ) { @@ -294,7 +294,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -376,7 +376,7 @@ Coverage = FT_NEXT_USHORT( p ); ValueFormat = FT_NEXT_USHORT( p ); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, -1 ); otv_ValueRecord_validate( p, ValueFormat, valid ); /* Value */ } break; @@ -395,7 +395,7 @@ len_value = otv_value_length( ValueFormat ); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, ValueCount ); OTV_LIMIT_CHECK( ValueCount * len_value ); @@ -409,7 +409,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -498,7 +498,7 @@ OTV_TRACE(( " (PairSetCount = %d)\n", PairSetCount )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, -1 ); OTV_LIMIT_CHECK( PairSetCount * 2 ); @@ -530,7 +530,7 @@ len_value1 = otv_value_length( ValueFormat1 ); len_value2 = otv_value_length( ValueFormat2 ); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, -1 ); otv_ClassDef_validate( table + ClassDef1, valid ); otv_ClassDef_validate( table + ClassDef2, valid ); @@ -558,7 +558,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -605,7 +605,7 @@ OTV_TRACE(( " (EntryExitCount = %d)\n", EntryExitCount )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, EntryExitCount ); OTV_LIMIT_CHECK( EntryExitCount * 4 ); @@ -629,7 +629,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -670,7 +670,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -711,7 +711,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -752,7 +752,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -811,7 +811,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -872,7 +872,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -925,7 +925,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -989,7 +989,7 @@ OTV_LIMIT_CHECK( 10 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_DATA; + FT_INVALID_FORMAT; ScriptList = FT_NEXT_USHORT( p ); FeatureList = FT_NEXT_USHORT( p ); diff --git a/Build/source/libs/freetype2/src/otvalid/otvgsub.c b/Build/source/libs/freetype2/src/otvalid/otvgsub.c index 91dae0bb161..f01fca1e897 100644 --- a/Build/source/libs/freetype2/src/otvalid/otvgsub.c +++ b/Build/source/libs/freetype2/src/otvalid/otvgsub.c @@ -4,7 +4,7 @@ /* */ /* OpenType GSUB table validation (body). */ /* */ -/* Copyright 2004, 2005 by */ +/* Copyright 2004, 2005, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -68,7 +68,7 @@ Coverage = table + FT_NEXT_USHORT( p ); DeltaGlyphID = FT_NEXT_SHORT( p ); - otv_Coverage_validate( Coverage, valid ); + otv_Coverage_validate( Coverage, valid, -1 ); idx = otv_Coverage_get_first( Coverage ) + DeltaGlyphID; if ( idx < 0 ) @@ -91,19 +91,19 @@ OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, GlyphCount ); OTV_LIMIT_CHECK( GlyphCount * 2 ); /* Substitute */ for ( ; GlyphCount > 0; GlyphCount-- ) if ( FT_NEXT_USHORT( p ) >= valid->glyph_count ) - FT_INVALID_DATA; + FT_INVALID_GLYPH_ID; } break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -144,7 +144,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -185,7 +185,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -259,7 +259,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -318,7 +318,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -379,7 +379,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -434,7 +434,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -476,12 +476,12 @@ OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount )); - otv_Coverage_validate( Coverage, valid ); + otv_Coverage_validate( Coverage, valid, -1 ); OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); LookaheadGlyphCount = FT_NEXT_USHORT( p ); @@ -490,7 +490,7 @@ OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); GlyphCount = FT_NEXT_USHORT( p ); @@ -509,7 +509,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -560,7 +560,7 @@ OTV_LIMIT_CHECK( 10 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_DATA; + FT_INVALID_FORMAT; ScriptList = FT_NEXT_USHORT( p ); FeatureList = FT_NEXT_USHORT( p ); diff --git a/Build/source/libs/freetype2/src/otvalid/otvjstf.c b/Build/source/libs/freetype2/src/otvalid/otvjstf.c index 80b8dd66043..a616a23432c 100644 --- a/Build/source/libs/freetype2/src/otvalid/otvjstf.c +++ b/Build/source/libs/freetype2/src/otvalid/otvjstf.c @@ -4,7 +4,7 @@ /* */ /* OpenType JSTF table validation (body). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -222,7 +222,7 @@ OTV_LIMIT_CHECK( 6 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_DATA; + FT_INVALID_FORMAT; JstfScriptCount = FT_NEXT_USHORT( p ); diff --git a/Build/source/libs/freetype2/src/otvalid/otvmath.c b/Build/source/libs/freetype2/src/otvalid/otvmath.c new file mode 100644 index 00000000000..b777d6a0c9e --- /dev/null +++ b/Build/source/libs/freetype2/src/otvalid/otvmath.c @@ -0,0 +1,450 @@ +/***************************************************************************/ +/* */ +/* otvmath.c */ +/* */ +/* OpenType MATH table validation (body). */ +/* */ +/* Copyright 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* Written by George Williams. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "otvalid.h" +#include "otvcommn.h" +#include "otvgpos.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_otvmath + + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH TYPOGRAPHIC CONSTANTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathConstants_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i; + FT_UInt table_size; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + OTV_NAME_ENTER( "MathConstants" ); + + /* 56 constants, 51 have device tables */ + OTV_LIMIT_CHECK( 2 * ( 56 + 51 ) ); + table_size = 2 * ( 56 + 51 ); + + p += 4 * 2; /* First 4 constants have no device tables */ + for ( i = 0; i < 51; ++i ) + { + p += 2; /* skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH ITALICS CORRECTION *****/ + /***** MATH TOP ACCENT ATTACHMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathItalicsCorrectionInfo_validate( FT_Bytes table, + OTV_Validator valid, + FT_Int isItalic ) + { + FT_Bytes p = table; + FT_UInt i, cnt, table_size ; + + OTV_OPTIONAL_TABLE( Coverage ); + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo" + : "MathTopAccentAttachment" ); + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( Coverage ); + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * cnt ); + table_size = 4 + 4 * cnt; + + OTV_SIZE_CHECK( Coverage ); + otv_Coverage_validate( table + Coverage, valid, cnt ); + + for ( i = 0; i < cnt; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH KERNING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathKern_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i, cnt, table_size; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + /* OTV_NAME_ENTER( "MathKern" );*/ + + OTV_LIMIT_CHECK( 2 ); + + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * cnt + 2 ); + table_size = 4 + 4 * cnt; + + /* Heights */ + for ( i = 0; i < cnt; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + /* One more Kerning value */ + for ( i = 0; i < cnt + 1; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + static void + otv_MathKernInfo_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i, j, cnt, table_size; + + OTV_OPTIONAL_TABLE( Coverage ); + OTV_OPTIONAL_TABLE( MKRecordOffset ); + + + OTV_NAME_ENTER( "MathKernInfo" ); + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( Coverage ); + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 8 * cnt ); + table_size = 4 + 8 * cnt; + + OTV_SIZE_CHECK( Coverage ); + otv_Coverage_validate( table + Coverage, valid, cnt ); + + for ( i = 0; i < cnt; ++i ) + { + for ( j = 0; j < 4; ++j ) + { + OTV_OPTIONAL_OFFSET( MKRecordOffset ); + OTV_SIZE_CHECK( MKRecordOffset ); + if ( MKRecordOffset ) + otv_MathKern_validate( table + MKRecordOffset, valid ); + } + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH GLYPH INFO *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathGlyphInfo_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt MathItalicsCorrectionInfo, MathTopAccentAttachment; + FT_UInt ExtendedShapeCoverage, MathKernInfo; + + + OTV_NAME_ENTER( "MathGlyphInfo" ); + + OTV_LIMIT_CHECK( 8 ); + + MathItalicsCorrectionInfo = FT_NEXT_USHORT( p ); + MathTopAccentAttachment = FT_NEXT_USHORT( p ); + ExtendedShapeCoverage = FT_NEXT_USHORT( p ); + MathKernInfo = FT_NEXT_USHORT( p ); + + if ( MathItalicsCorrectionInfo ) + otv_MathItalicsCorrectionInfo_validate( + table + MathItalicsCorrectionInfo, valid, TRUE ); + + /* Italic correction and Top Accent Attachment have the same format */ + if ( MathTopAccentAttachment ) + otv_MathItalicsCorrectionInfo_validate( + table + MathTopAccentAttachment, valid, FALSE ); + + if ( ExtendedShapeCoverage ) { + OTV_NAME_ENTER( "ExtendedShapeCoverage" ); + otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 ); + OTV_EXIT; + } + + if ( MathKernInfo ) + otv_MathKernInfo_validate( table + MathKernInfo, valid ); + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH GLYPH CONSTRUCTION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_GlyphAssembly_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt pcnt, table_size; + FT_UInt i; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + /* OTV_NAME_ENTER( "GlyphAssembly" ); */ + + OTV_LIMIT_CHECK( 6 ); + + p += 2; /* Skip the Italics Correction value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + pcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 8 * pcnt ); + table_size = 6 + 8 * pcnt; + + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + + for ( i = 0; i < pcnt; ++i ) + { + FT_UInt gid; + + + gid = FT_NEXT_USHORT( p ); + if ( gid >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + p += 2*4; /* skip the Start, End, Full, and Flags fields */ + } + + /* OTV_EXIT; */ + } + + + static void + otv_MathGlyphConstruction_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt vcnt, table_size; + FT_UInt i; + + OTV_OPTIONAL_TABLE( GlyphAssembly ); + + + /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */ + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( GlyphAssembly ); + vcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * vcnt ); + table_size = 4 + 4 * vcnt; + + for ( i = 0; i < vcnt; ++i ) + { + FT_UInt gid; + + + gid = FT_NEXT_USHORT( p ); + if ( gid >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + p += 2; /* skip the size */ + } + + OTV_SIZE_CHECK( GlyphAssembly ); + if ( GlyphAssembly ) + otv_GlyphAssembly_validate( table+GlyphAssembly, valid ); + + /* OTV_EXIT; */ + } + + + static void + otv_MathVariants_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt vcnt, hcnt, i, table_size; + + OTV_OPTIONAL_TABLE( VCoverage ); + OTV_OPTIONAL_TABLE( HCoverage ); + OTV_OPTIONAL_TABLE( Offset ); + + + OTV_NAME_ENTER( "MathVariants" ); + + OTV_LIMIT_CHECK( 10 ); + + p += 2; /* Skip the MinConnectorOverlap constant */ + OTV_OPTIONAL_OFFSET( VCoverage ); + OTV_OPTIONAL_OFFSET( HCoverage ); + vcnt = FT_NEXT_USHORT( p ); + hcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt ); + table_size = 10 + 2 * vcnt + 2 * hcnt; + + OTV_SIZE_CHECK( VCoverage ); + if ( VCoverage ) + otv_Coverage_validate( table + VCoverage, valid, vcnt ); + + OTV_SIZE_CHECK( HCoverage ); + if ( HCoverage ) + otv_Coverage_validate( table + HCoverage, valid, hcnt ); + + for ( i = 0; i < vcnt; ++i ) + { + OTV_OPTIONAL_OFFSET( Offset ); + OTV_SIZE_CHECK( Offset ); + otv_MathGlyphConstruction_validate( table + Offset, valid ); + } + + for ( i = 0; i < hcnt; ++i ) + { + OTV_OPTIONAL_OFFSET( Offset ); + OTV_SIZE_CHECK( Offset ); + otv_MathGlyphConstruction_validate( table + Offset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->glyph_count */ + + FT_LOCAL_DEF( void ) + otv_MATH_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator ftvalid ) + { + OTV_ValidatorRec validrec; + OTV_Validator valid = &validrec; + FT_Bytes p = table; + FT_UInt MathConstants, MathGlyphInfo, MathVariants; + + + valid->root = ftvalid; + + FT_TRACE3(( "validating MATH table\n" )); + OTV_INIT; + + OTV_LIMIT_CHECK( 10 ); + + if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + FT_INVALID_FORMAT; + + MathConstants = FT_NEXT_USHORT( p ); + MathGlyphInfo = FT_NEXT_USHORT( p ); + MathVariants = FT_NEXT_USHORT( p ); + + valid->glyph_count = glyph_count; + + otv_MathConstants_validate( table + MathConstants, + valid ); + otv_MathGlyphInfo_validate( table + MathGlyphInfo, + valid ); + otv_MathVariants_validate ( table + MathVariants, + valid ); + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/Build/source/libs/freetype2/src/otvalid/otvmod.c b/Build/source/libs/freetype2/src/otvalid/otvmod.c index 157272f1ae9..c280299152c 100644 --- a/Build/source/libs/freetype2/src/otvalid/otvmod.c +++ b/Build/source/libs/freetype2/src/otvalid/otvmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType's OpenType validation module implementation (body). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -79,12 +79,14 @@ FT_Byte* volatile gpos; FT_Byte* volatile gsub; FT_Byte* volatile jstf; + FT_Byte* volatile math; FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf; + FT_ULong len_math; FT_ValidatorRec volatile valid; - base = gdef = gpos = gsub = jstf = NULL; - len_base = len_gdef = len_gpos = len_gsub = len_jstf = 0; + base = gdef = gpos = gsub = jstf = math = NULL; + len_base = len_gdef = len_gpos = len_gsub = len_jstf = len_math = 0; /* load tables */ @@ -123,6 +125,13 @@ goto Exit; } + if ( ot_flags & FT_VALIDATE_MATH ) + { + error = otv_load_table( face, TTAG_MATH, &math, &len_math ); + if ( error ) + goto Exit; + } + /* validate tables */ if ( base ) @@ -175,6 +184,16 @@ goto Exit; } + if ( math ) + { + ft_validator_init( &valid, math, math + len_math, FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + otv_MATH_validate( math, face->num_glyphs, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + *ot_base = (FT_Bytes)base; *ot_gdef = (FT_Bytes)gdef; *ot_gpos = (FT_Bytes)gpos; @@ -192,6 +211,12 @@ FT_FREE( gsub ); FT_FREE( jstf ); } + { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( math ); /* Can't return this as API is frozen */ + } return error; } diff --git a/Build/source/libs/freetype2/src/otvalid/rules.mk b/Build/source/libs/freetype2/src/otvalid/rules.mk index 48f12336f79..53bd41e5e7d 100644 --- a/Build/source/libs/freetype2/src/otvalid/rules.mk +++ b/Build/source/libs/freetype2/src/otvalid/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2004 by +# Copyright 2004, 2007 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -31,14 +31,15 @@ OTV_DRV_SRC := $(OTV_DIR)/otvbase.c \ $(OTV_DIR)/otvgpos.c \ $(OTV_DIR)/otvgsub.c \ $(OTV_DIR)/otvjstf.c \ + $(OTV_DIR)/otvmath.c \ $(OTV_DIR)/otvmod.c # OTV driver headers # -OTV_DRV_H := $(OTV_DIR)/otvalid.h \ - $(OTV_DIR)/otverror.h \ +OTV_DRV_H := $(OTV_DIR)/otvalid.h \ $(OTV_DIR)/otvcommn.h \ - $(OTV_DIR)/otvgpos.h \ + $(OTV_DIR)/otverror.h \ + $(OTV_DIR)/otvgpos.h \ $(OTV_DIR)/otvmod.h diff --git a/Build/source/libs/freetype2/src/pcf/pcfdrivr.c b/Build/source/libs/freetype2/src/pcf/pcfdrivr.c index c0f0e49ca12..0fea30e8cbc 100644 --- a/Build/source/libs/freetype2/src/pcf/pcfdrivr.c +++ b/Build/source/libs/freetype2/src/pcf/pcfdrivr.c @@ -2,7 +2,7 @@ FreeType font driver for pcf files - Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006 by + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -187,7 +187,9 @@ THE SOFTWARE. pcf_cmap_init, pcf_cmap_done, pcf_cmap_char_index, - pcf_cmap_char_next + pcf_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL }; @@ -271,6 +273,7 @@ THE SOFTWARE. error = error2; if ( error ) +#ifdef FT_CONFIG_OPTION_USE_LZW { FT_Error error3; @@ -293,6 +296,9 @@ THE SOFTWARE. if ( error ) goto Fail; } +#else + goto Fail; +#endif else { face->gzip_source = stream; diff --git a/Build/source/libs/freetype2/src/pfr/pfrcmap.c b/Build/source/libs/freetype2/src/pfr/pfrcmap.c index c8faee04364..d4656d1b5e9 100644 --- a/Build/source/libs/freetype2/src/pfr/pfrcmap.c +++ b/Build/source/libs/freetype2/src/pfr/pfrcmap.c @@ -20,6 +20,8 @@ #include "pfrobjs.h" #include FT_INTERNAL_DEBUG_H +#include "pfrerror.h" + FT_CALLBACK_DEF( FT_Error ) pfr_cmap_init( PFR_CMap cmap ) @@ -156,7 +158,9 @@ (FT_CMap_InitFunc) pfr_cmap_init, (FT_CMap_DoneFunc) pfr_cmap_done, (FT_CMap_CharIndexFunc)pfr_cmap_char_index, - (FT_CMap_CharNextFunc) pfr_cmap_char_next + (FT_CMap_CharNextFunc) pfr_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL }; diff --git a/Build/source/libs/freetype2/src/pfr/pfrgload.c b/Build/source/libs/freetype2/src/pfr/pfrgload.c index 3bb173302d4..6fe6e4225ab 100644 --- a/Build/source/libs/freetype2/src/pfr/pfrgload.c +++ b/Build/source/libs/freetype2/src/pfr/pfrgload.c @@ -595,7 +595,7 @@ if ( org_count + count > glyph->max_subs ) { - FT_UInt new_max = ( org_count + count + 3 ) & -4; + FT_UInt new_max = ( org_count + count + 3 ) & (FT_UInt)-4; if ( FT_RENEW_ARRAY( glyph->subs, glyph->max_subs, new_max ) ) diff --git a/Build/source/libs/freetype2/src/psaux/psconv.c b/Build/source/libs/freetype2/src/psaux/psconv.c index 3bbeab6d256..d824b59139c 100644 --- a/Build/source/libs/freetype2/src/psaux/psconv.c +++ b/Build/source/libs/freetype2/src/psaux/psconv.c @@ -4,7 +4,7 @@ /* */ /* Some convenience conversions (body). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -187,10 +187,18 @@ if ( c < 0 || c >= 10 ) break; - if ( divider < 10000000L ) + if ( !integral && power_ten > 0 ) { + power_ten--; decimal = decimal * 10 + c; - divider *= 10; + } + else + { + if ( divider < 10000000L ) + { + decimal = decimal * 10 + c; + divider *= 10; + } } } } diff --git a/Build/source/libs/freetype2/src/psaux/psobjs.c b/Build/source/libs/freetype2/src/psaux/psobjs.c index 957085668be..b7b84ac830f 100644 --- a/Build/source/libs/freetype2/src/psaux/psobjs.c +++ b/Build/source/libs/freetype2/src/psaux/psobjs.c @@ -4,7 +4,7 @@ /* */ /* Auxiliary functions for PostScript fonts (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -169,7 +169,7 @@ void* object, FT_PtrDist length ) { - if ( idx < 0 || idx > table->max_elems ) + if ( idx < 0 || idx >= table->max_elems ) { FT_ERROR(( "ps_table_add: invalid index\n" )); return PSaux_Err_Invalid_Argument; @@ -1483,12 +1483,6 @@ builder->hints_funcs = glyph->internal->glyph_hints; } - if ( size ) - { - builder->scale_x = size->metrics.x_scale; - builder->scale_y = size->metrics.y_scale; - } - builder->pos_x = 0; builder->pos_y = 0; diff --git a/Build/source/libs/freetype2/src/psaux/t1cmap.c b/Build/source/libs/freetype2/src/psaux/t1cmap.c index 29346869660..67a23db569f 100644 --- a/Build/source/libs/freetype2/src/psaux/t1cmap.c +++ b/Build/source/libs/freetype2/src/psaux/t1cmap.c @@ -4,7 +4,7 @@ /* */ /* Type 1 character map support (body). */ /* */ -/* Copyright 2002, 2003, 2006 by */ +/* Copyright 2002, 2003, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -135,7 +135,9 @@ (FT_CMap_InitFunc) t1_cmap_standard_init, (FT_CMap_DoneFunc) t1_cmap_std_done, (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, - (FT_CMap_CharNextFunc) t1_cmap_std_char_next + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + + NULL, NULL, NULL, NULL, NULL }; @@ -154,7 +156,9 @@ (FT_CMap_InitFunc) t1_cmap_expert_init, (FT_CMap_DoneFunc) t1_cmap_std_done, (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, - (FT_CMap_CharNextFunc) t1_cmap_std_char_next + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + + NULL, NULL, NULL, NULL, NULL }; @@ -245,7 +249,9 @@ (FT_CMap_InitFunc) t1_cmap_custom_init, (FT_CMap_DoneFunc) t1_cmap_custom_done, (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, - (FT_CMap_CharNextFunc) t1_cmap_custom_char_next + (FT_CMap_CharNextFunc) t1_cmap_custom_char_next, + + NULL, NULL, NULL, NULL, NULL }; @@ -326,7 +332,9 @@ (FT_CMap_InitFunc) t1_cmap_unicode_init, (FT_CMap_DoneFunc) t1_cmap_unicode_done, (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, - (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next + (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next, + + NULL, NULL, NULL, NULL, NULL }; diff --git a/Build/source/libs/freetype2/src/psaux/t1decode.c b/Build/source/libs/freetype2/src/psaux/t1decode.c index f790643f961..550ba641429 100644 --- a/Build/source/libs/freetype2/src/psaux/t1decode.c +++ b/Build/source/libs/freetype2/src/psaux/t1decode.c @@ -4,7 +4,7 @@ /* */ /* PostScript Type 1 decoding routines (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -1062,10 +1062,11 @@ case op_closepath: FT_TRACE4(( " closepath" )); - close_contour( builder ); - if ( !( builder->parse_state == T1_Parse_Have_Path || - builder->parse_state == T1_Parse_Have_Moveto ) ) - goto Syntax_Error; + /* if there is no path, `closepath' is a no-op */ + if ( builder->parse_state == T1_Parse_Have_Path || + builder->parse_state == T1_Parse_Have_Moveto ) + close_contour( builder ); + builder->parse_state = T1_Parse_Have_Width; break; diff --git a/Build/source/libs/freetype2/src/pshinter/pshalgo.c b/Build/source/libs/freetype2/src/pshinter/pshalgo.c index 505d95c5720..5d7e2f490d9 100644 --- a/Build/source/libs/freetype2/src/pshinter/pshalgo.c +++ b/Build/source/libs/freetype2/src/pshinter/pshalgo.c @@ -4,7 +4,7 @@ /* */ /* PostScript hinting algorithm (body). */ /* */ -/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -2223,15 +2223,22 @@ FT_Fixed x_scale = dim_x->scale_mult; FT_Fixed y_scale = dim_y->scale_mult; + FT_Fixed old_x_scale = x_scale; + FT_Fixed old_y_scale = y_scale; + FT_Fixed scaled; FT_Fixed fitted; + FT_Bool rescale = FALSE; + scaled = FT_MulFix( globals->blues.normal_top.zones->org_ref, y_scale ); fitted = FT_PIX_ROUND( scaled ); if ( fitted != 0 && scaled != fitted ) { + rescale = TRUE; + y_scale = FT_MulDiv( y_scale, fitted, scaled ); if ( fitted < scaled ) @@ -2239,43 +2246,47 @@ psh_globals_set_scale( glyph->globals, x_scale, y_scale, 0, 0 ); } - } - - glyph->do_horz_hints = 1; - glyph->do_vert_hints = 1; - - glyph->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || - hint_mode == FT_RENDER_MODE_LCD ); - glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || - hint_mode == FT_RENDER_MODE_LCD_V ); + glyph->do_horz_hints = 1; + glyph->do_vert_hints = 1; - glyph->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT ); + glyph->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || + hint_mode == FT_RENDER_MODE_LCD ); - for ( dimension = 0; dimension < 2; dimension++ ) - { - /* load outline coordinates into glyph */ - psh_glyph_load_points( glyph, dimension ); - - /* compute local extrema */ - psh_glyph_compute_extrema( glyph ); - - /* compute aligned stem/hints positions */ - psh_hint_table_align_hints( &glyph->hint_tables[dimension], - glyph->globals, - dimension, - glyph ); + glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || + hint_mode == FT_RENDER_MODE_LCD_V ); - /* find strong points, align them, then interpolate others */ - psh_glyph_find_strong_points( glyph, dimension ); - if ( dimension == 1 ) - psh_glyph_find_blue_points( &globals->blues, glyph ); - psh_glyph_interpolate_strong_points( glyph, dimension ); - psh_glyph_interpolate_normal_points( glyph, dimension ); - psh_glyph_interpolate_other_points( glyph, dimension ); + glyph->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT ); - /* save hinted coordinates back to outline */ - psh_glyph_save_points( glyph, dimension ); + for ( dimension = 0; dimension < 2; dimension++ ) + { + /* load outline coordinates into glyph */ + psh_glyph_load_points( glyph, dimension ); + + /* compute local extrema */ + psh_glyph_compute_extrema( glyph ); + + /* compute aligned stem/hints positions */ + psh_hint_table_align_hints( &glyph->hint_tables[dimension], + glyph->globals, + dimension, + glyph ); + + /* find strong points, align them, then interpolate others */ + psh_glyph_find_strong_points( glyph, dimension ); + if ( dimension == 1 ) + psh_glyph_find_blue_points( &globals->blues, glyph ); + psh_glyph_interpolate_strong_points( glyph, dimension ); + psh_glyph_interpolate_normal_points( glyph, dimension ); + psh_glyph_interpolate_other_points( glyph, dimension ); + + /* save hinted coordinates back to outline */ + psh_glyph_save_points( glyph, dimension ); + + if ( rescale ) + psh_globals_set_scale( glyph->globals, + old_x_scale, old_y_scale, 0, 0 ); + } } Exit: diff --git a/Build/source/libs/freetype2/src/pshinter/pshalgo.h b/Build/source/libs/freetype2/src/pshinter/pshalgo.h index f68de71202e..1a248a70524 100644 --- a/Build/source/libs/freetype2/src/pshinter/pshalgo.h +++ b/Build/source/libs/freetype2/src/pshinter/pshalgo.h @@ -4,7 +4,7 @@ /* */ /* PostScript hinting algorithm (specification). */ /* */ -/* Copyright 2001, 2002, 2003 by */ +/* Copyright 2001, 2002, 2003, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,7 +32,7 @@ FT_BEGIN_HEADER typedef struct PSH_HintRec_* PSH_Hint; /* hint bit-flags */ - typedef enum + typedef enum PSH_Hint_Flags_ { PSH_HINT_GHOST = PS_HINT_FLAG_GHOST, PSH_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM, diff --git a/Build/source/libs/freetype2/src/pshinter/pshrec.h b/Build/source/libs/freetype2/src/pshinter/pshrec.h index f7ef9004ea1..dcb3197f94d 100644 --- a/Build/source/libs/freetype2/src/pshinter/pshrec.h +++ b/Build/source/libs/freetype2/src/pshinter/pshrec.h @@ -4,7 +4,7 @@ /* */ /* Postscript (Type1/Type2) hints recorder (specification). */ /* */ -/* Copyright 2001, 2002, 2003, 2006 by */ +/* Copyright 2001, 2002, 2003, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -52,7 +52,7 @@ FT_BEGIN_HEADER typedef struct PS_HintRec_* PS_Hint; /* hint types */ - typedef enum + typedef enum PS_Hint_Type_ { PS_HINT_TYPE_1 = 1, PS_HINT_TYPE_2 = 2 @@ -61,7 +61,7 @@ FT_BEGIN_HEADER /* hint flags */ - typedef enum + typedef enum PS_Hint_Flags_ { PS_HINT_FLAG_GHOST = 1, PS_HINT_FLAG_BOTTOM = 2 diff --git a/Build/source/libs/freetype2/src/psnames/psmodule.c b/Build/source/libs/freetype2/src/psnames/psmodule.c index 8d8c476a145..dbcfe44b196 100644 --- a/Build/source/libs/freetype2/src/psnames/psmodule.c +++ b/Build/source/libs/freetype2/src/psnames/psmodule.c @@ -4,7 +4,7 @@ /* */ /* PSNames module implementation (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,7 +26,7 @@ #include "psnamerr.h" -#ifndef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST @@ -180,6 +180,95 @@ } + /* support for old WGL4 fonts */ + +#define WGL_EXTRA_LIST_SIZE 8 + + static const FT_UInt32 ft_wgl_extra_unicodes[WGL_EXTRA_LIST_SIZE] = + { + 0x0394, + 0x03A9, + 0x2215, + 0x00AD, + 0x02C9, + 0x03BC, + 0x2219, + 0x00A0 + }; + + static const char ft_wgl_extra_glyph_names[] = + { + 'D','e','l','t','a',0, + 'O','m','e','g','a',0, + 'f','r','a','c','t','i','o','n',0, + 'h','y','p','h','e','n',0, + 'm','a','c','r','o','n',0, + 'm','u',0, + 'p','e','r','i','o','d','c','e','n','t','e','r','e','d',0, + 's','p','a','c','e',0 + }; + + static const FT_Int + ft_wgl_extra_glyph_name_offsets[WGL_EXTRA_LIST_SIZE] = + { + 0, + 6, + 12, + 21, + 28, + 35, + 38, + 53 + }; + + + static void + ps_check_wgl_name( const char* gname, + FT_UInt glyph, + FT_UInt* wgl_glyphs, + FT_UInt *states ) + { + FT_UInt n; + + + for ( n = 0; n < WGL_EXTRA_LIST_SIZE; n++ ) + { + if ( ft_strcmp( ft_wgl_extra_glyph_names + + ft_wgl_extra_glyph_name_offsets[n], gname ) == 0 ) + { + if ( states[n] == 0 ) + { + /* mark this WGL extra glyph as a candidate for the cmap */ + states[n] = 1; + wgl_glyphs[n] = glyph; + } + + return; + } + } + } + + + static void + ps_check_wgl_unicode( FT_UInt32 uni_char, + FT_UInt *states ) + { + FT_UInt n; + + + for ( n = 0; n < WGL_EXTRA_LIST_SIZE; n++ ) + { + if ( uni_char == ft_wgl_extra_unicodes[n] ) + { + /* disable this WGL extra glyph from being added to the cmap */ + states[n] = 2; + + return; + } + } + } + + /* Build a table that maps Unicode values to glyph indices. */ static FT_Error ps_unicodes_init( FT_Memory memory, @@ -191,12 +280,15 @@ { FT_Error error; + FT_UInt wgl_list_states[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + FT_UInt wgl_glyphs[WGL_EXTRA_LIST_SIZE]; + /* we first allocate the table */ table->num_maps = 0; table->maps = 0; - if ( !FT_NEW_ARRAY( table->maps, num_glyphs ) ) + if ( !FT_NEW_ARRAY( table->maps, num_glyphs + WGL_EXTRA_LIST_SIZE ) ) { FT_UInt n; FT_UInt count; @@ -213,10 +305,12 @@ if ( gname ) { + ps_check_wgl_name( gname, n, wgl_glyphs, wgl_list_states ); uni_char = ps_unicode_value( gname ); if ( BASE_GLYPH( uni_char ) != 0 ) { + ps_check_wgl_unicode( uni_char, wgl_list_states ); map->unicode = uni_char; map->glyph_index = n; map++; @@ -227,6 +321,19 @@ } } + for ( n = 0; n < WGL_EXTRA_LIST_SIZE; n++ ) + { + if ( wgl_list_states[n] == 1 ) + { + /* This glyph name has an additional WGL4 representation. */ + /* Add it to the cmap. */ + + map->unicode = ft_wgl_extra_unicodes[n]; + map->glyph_index = wgl_glyphs[n]; + map++; + } + } + /* now compress the table a bit */ count = (FT_UInt)( map - table->maps ); @@ -427,7 +534,7 @@ return ft_service_list_lookup( pscmaps_services, service_id ); } -#endif /* !FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES */ +#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ @@ -441,7 +548,7 @@ 0x10000L, /* driver version */ 0x20000L, /* driver requires FreeType 2 or above */ -#ifdef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES +#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES 0, (FT_Module_Constructor)0, (FT_Module_Destructor) 0, diff --git a/Build/source/libs/freetype2/src/raster/ftraster.c b/Build/source/libs/freetype2/src/raster/ftraster.c index 4cfca4ed035..86d77d4b712 100644 --- a/Build/source/libs/freetype2/src/raster/ftraster.c +++ b/Build/source/libs/freetype2/src/raster/ftraster.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2005, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -144,9 +144,7 @@ /* undefine FT_RASTER_OPTION_ANTI_ALIASING if you do not want to support */ /* 5-levels anti-aliasing */ -#ifdef FT_CONFIG_OPTION_5_GRAY_LEVELS -#define FT_RASTER_OPTION_ANTI_ALIASING -#endif +#undef FT_RASTER_OPTION_ANTI_ALIASING /* The size of the two-lines intermediate bitmap used */ /* for anti-aliasing, in bytes. */ @@ -543,6 +541,8 @@ #endif /* FT_STATIC_RASTER */ +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + static const char count_table[256] = { 0 , 1 , 1 , 2 , 1 , 2 , 2 , 3 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4, @@ -562,6 +562,8 @@ static const char count_table[256] = 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 , 5 , 6 , 6 , 7 , 6 , 7 , 7 , 8 }; +#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ + /*************************************************************************/ @@ -3172,8 +3174,6 @@ static const char count_table[256] = static void ft_black_init( PRaster raster ) { - FT_UNUSED( raster ); - #ifdef FT_RASTER_OPTION_ANTI_ALIASING FT_UInt n; @@ -3184,6 +3184,8 @@ static const char count_table[256] = raster->gray_width = RASTER_GRAY_LINES / 2; +#else + FT_UNUSED( raster ); #endif } @@ -3319,14 +3321,18 @@ static const char count_table[256] = if ( !raster || !raster->buffer || !raster->buffer_size ) return Raster_Err_Not_Ini; + if ( !outline ) + return Raster_Err_Invalid; + /* return immediately if the outline is empty */ if ( outline->n_points == 0 || outline->n_contours <= 0 ) return Raster_Err_None; - if ( !outline || !outline->contours || !outline->points ) + if ( !outline->contours || !outline->points ) return Raster_Err_Invalid; - if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 ) + if ( outline->n_points != + outline->contours[outline->n_contours - 1] + 1 ) return Raster_Err_Invalid; worker = raster->worker; @@ -3335,7 +3341,14 @@ static const char count_table[256] = if ( params->flags & FT_RASTER_FLAG_DIRECT ) return Raster_Err_Unsupported; - if ( !target_map || !target_map->buffer ) + if ( !target_map ) + return Raster_Err_Invalid; + + /* nothing to do */ + if ( !target_map->width || !target_map->rows ) + return Raster_Err_None; + + if ( !target_map->buffer ) return Raster_Err_Invalid; ras.outline = *outline; diff --git a/Build/source/libs/freetype2/src/sfnt/sfobjs.c b/Build/source/libs/freetype2/src/sfnt/sfobjs.c index cc901100d1d..c25b87d8dfd 100644 --- a/Build/source/libs/freetype2/src/sfnt/sfobjs.c +++ b/Build/source/libs/freetype2/src/sfnt/sfobjs.c @@ -4,7 +4,7 @@ /* */ /* SFNT object management (base). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -285,7 +285,7 @@ sfnt_find_encoding( int platform_id, int encoding_id ) { - typedef struct TEncoding + typedef struct TEncoding_ { int platform_id; int encoding_id; @@ -696,22 +696,60 @@ face->root.num_glyphs = face->max_profile.numGlyphs; - face->root.family_name = tt_face_get_name( face, - TT_NAME_ID_PREFERRED_FAMILY ); - if ( !face->root.family_name ) - face->root.family_name = tt_face_get_name( face, - TT_NAME_ID_FONT_FAMILY ); +#if 0 + /* Bit 8 of the `fsSelection' field in the `OS/2' table denotes */ + /* a WWS-only font face. `WWS' stands for `weight', width', and */ + /* `slope', a term used by Microsoft's Windows Presentation */ + /* Foundation (WPF). This flag will be introduced in version */ + /* 1.5 of the OpenType specification (but is already in use). */ + + if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 ) +#endif + { + face->root.family_name = + tt_face_get_name( face, TT_NAME_ID_PREFERRED_FAMILY ); + if ( !face->root.family_name ) + face->root.family_name = + tt_face_get_name( face, TT_NAME_ID_FONT_FAMILY ); + + face->root.style_name = + tt_face_get_name( face, TT_NAME_ID_PREFERRED_SUBFAMILY ); + if ( !face->root.style_name ) + face->root.style_name = + tt_face_get_name( face, TT_NAME_ID_FONT_SUBFAMILY ); + } +#if 0 + else + { + /* Support for `name' table ID 21 (WWS family) and 22 (WWS */ + /* subfamily) is still under consideration by Microsoft and */ + /* not implemented in the current version of WPF. */ + + face->root.family_name = + tt_face_get_name( face, TT_NAME_ID_WWS_FAMILY ); + if ( !face->root.family_name ) + face->root.family_name = + tt_face_get_name( face, TT_NAME_ID_PREFERRED_FAMILY ); + if ( !face->root.family_name ) + face->root.family_name = + tt_face_get_name( face, TT_NAME_ID_FONT_FAMILY ); + + face->root.style_name = + tt_face_get_name( face, TT_NAME_ID_WWS_SUBFAMILY ); + if ( !face->root.style_name ) + face->root.style_name = + tt_face_get_name( face, TT_NAME_ID_PREFERRED_SUBFAMILY ); + if ( !face->root.style_name ) + face->root.style_name = + tt_face_get_name( face, TT_NAME_ID_FONT_SUBFAMILY ); + } +#endif - face->root.style_name = tt_face_get_name( face, - TT_NAME_ID_PREFERRED_SUBFAMILY ); - if ( !face->root.style_name ) - face->root.style_name = tt_face_get_name( face, - TT_NAME_ID_FONT_SUBFAMILY ); /* now set up root fields */ { - FT_Face root = &face->root; - FT_Int32 flags = root->face_flags; + FT_Face root = &face->root; + FT_Int32 flags = root->face_flags; /*********************************************************************/ @@ -727,7 +765,7 @@ FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - if ( psnames_error == SFNT_Err_Ok && + if ( psnames_error == SFNT_Err_Ok && face->postscript.FormatType != 0x00030000L ) flags |= FT_FACE_FLAG_GLYPH_NAMES; #endif @@ -759,14 +797,21 @@ /* */ /* Compute style flags. */ /* */ + flags = 0; if ( has_outline == TRUE && face->os2.version != 0xFFFFU ) { - /* we have an OS/2 table; use the `fsSelection' field */ - if ( face->os2.fsSelection & 1 ) + /* We have an OS/2 table; use the `fsSelection' field. Bit 9 */ + /* indicates an oblique font face. This flag will be */ + /* introduced in version 1.5 of the OpenType specification (but */ + /* is already in use). */ + + if ( face->os2.fsSelection & 512 ) /* bit 9 */ + flags |= FT_STYLE_FLAG_ITALIC; + else if ( face->os2.fsSelection & 1 ) /* bit 0 */ flags |= FT_STYLE_FLAG_ITALIC; - if ( face->os2.fsSelection & 32 ) + if ( face->os2.fsSelection & 32 ) /* bit 5 */ flags |= FT_STYLE_FLAG_BOLD; } else @@ -1051,7 +1096,8 @@ face->gasp.numRanges = 0; /* freeing the name table */ - sfnt->free_name( face ); + if ( sfnt ) + sfnt->free_name( face ); /* freeing family and style name */ FT_FREE( face->root.family_name ); diff --git a/Build/source/libs/freetype2/src/sfnt/ttcmap.c b/Build/source/libs/freetype2/src/sfnt/ttcmap.c index 854d567d1af..b70b64c1f74 100644 --- a/Build/source/libs/freetype2/src/sfnt/ttcmap.c +++ b/Build/source/libs/freetype2/src/sfnt/ttcmap.c @@ -39,11 +39,13 @@ #define TT_PEEK_SHORT FT_PEEK_SHORT #define TT_PEEK_USHORT FT_PEEK_USHORT +#define TT_PEEK_UINT24 FT_PEEK_UOFF3 #define TT_PEEK_LONG FT_PEEK_LONG #define TT_PEEK_ULONG FT_PEEK_ULONG #define TT_NEXT_SHORT FT_NEXT_SHORT #define TT_NEXT_USHORT FT_NEXT_USHORT +#define TT_NEXT_UINT24 FT_NEXT_UOFF3 #define TT_NEXT_LONG FT_NEXT_LONG #define TT_NEXT_ULONG FT_NEXT_ULONG @@ -171,7 +173,9 @@ (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap0_char_index, - (FT_CMap_CharNextFunc) tt_cmap0_char_next + (FT_CMap_CharNextFunc) tt_cmap0_char_next, + + NULL, NULL, NULL, NULL, NULL }, 0, (TT_CMap_ValidateFunc) tt_cmap0_validate, @@ -544,7 +548,9 @@ (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap2_char_index, - (FT_CMap_CharNextFunc) tt_cmap2_char_next + (FT_CMap_CharNextFunc) tt_cmap2_char_next, + + NULL, NULL, NULL, NULL, NULL }, 2, (TT_CMap_ValidateFunc) tt_cmap2_validate, @@ -1320,7 +1326,9 @@ (FT_CMap_InitFunc) tt_cmap4_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap4_char_index, - (FT_CMap_CharNextFunc) tt_cmap4_char_next + (FT_CMap_CharNextFunc) tt_cmap4_char_next, + + NULL, NULL, NULL, NULL, NULL }, 4, (TT_CMap_ValidateFunc) tt_cmap4_validate, @@ -1481,7 +1489,9 @@ (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap6_char_index, - (FT_CMap_CharNextFunc) tt_cmap6_char_next + (FT_CMap_CharNextFunc) tt_cmap6_char_next, + + NULL, NULL, NULL, NULL, NULL }, 6, (TT_CMap_ValidateFunc) tt_cmap6_validate, @@ -1735,7 +1745,9 @@ (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap8_char_index, - (FT_CMap_CharNextFunc) tt_cmap8_char_next + (FT_CMap_CharNextFunc) tt_cmap8_char_next, + + NULL, NULL, NULL, NULL, NULL }, 8, (TT_CMap_ValidateFunc) tt_cmap8_validate, @@ -1884,7 +1896,9 @@ (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap10_char_index, - (FT_CMap_CharNextFunc) tt_cmap10_char_next + (FT_CMap_CharNextFunc) tt_cmap10_char_next, + + NULL, NULL, NULL, NULL, NULL }, 10, (TT_CMap_ValidateFunc) tt_cmap10_validate, @@ -2201,17 +2215,756 @@ (FT_CMap_InitFunc) tt_cmap12_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap12_char_index, - (FT_CMap_CharNextFunc) tt_cmap12_char_next + (FT_CMap_CharNextFunc) tt_cmap12_char_next, + + NULL, NULL, NULL, NULL, NULL }, 12, (TT_CMap_ValidateFunc) tt_cmap12_validate, (TT_CMap_Info_GetFunc) tt_cmap12_get_info }; - #endif /* TT_CONFIG_CMAP_FORMAT_12 */ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 14 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 14 */ + /* length 2 ULONG table length in bytes */ + /* numSelector 6 ULONG number of variation sel. records */ + /* */ + /* Followed by numSelector records, each of which looks like */ + /* */ + /* varSelector 0 UINT24 Unicode codepoint of sel. */ + /* defaultOff 3 ULONG offset to a default UVS table */ + /* describing any variants to be found in */ + /* the normal Unicode subtable. */ + /* nonDefOff 7 ULONG offset to a non-default UVS table */ + /* describing any variants not in the */ + /* standard cmap, with GIDs here */ + /* (either offset may be 0 NULL) */ + /* */ + /* Selectors are sorted by code point. */ + /* */ + /* A default Unicode Variation Selector (UVS) subtable is just a list of */ + /* ranges of code points which are to be found in the standard cmap. No */ + /* glyph IDs (GIDs) here. */ + /* */ + /* numRanges 0 ULONG number of ranges following */ + /* */ + /* A range looks like */ + /* */ + /* uniStart 0 UINT24 code point of the first character in */ + /* this range */ + /* additionalCnt 3 UBYTE count of additional characters in this */ + /* range (zero means a range of a single */ + /* character) */ + /* */ + /* Ranges are sorted by `uniStart'. */ + /* */ + /* A non-default Unicode Variation Selector (UVS) subtable is a list of */ + /* mappings from codepoint to GID. */ + /* */ + /* numMappings 0 ULONG number of mappings */ + /* */ + /* A range looks like */ + /* */ + /* uniStart 0 UINT24 code point of the first character in */ + /* this range */ + /* GID 3 USHORT and its GID */ + /* */ + /* Ranges are sorted by `uniStart'. */ + +#ifdef TT_CONFIG_CMAP_FORMAT_14 + + typedef struct TT_CMap14Rec_ + { + TT_CMapRec cmap; + FT_ULong num_selectors; + + /* This array is used to store the results of various + * cmap 14 query functions. The data is overwritten + * on each call to these functions. + */ + FT_UInt max_results; + FT_UInt32* results; + FT_Memory memory; + + } TT_CMap14Rec, *TT_CMap14; + + + FT_CALLBACK_DEF( void ) + tt_cmap14_done( TT_CMap14 cmap ) + { + FT_Memory memory = cmap->memory; + + + cmap->max_results = 0; + if ( memory != NULL && cmap->results != NULL ) + FT_FREE( cmap->results ); + } + + + static FT_Error + tt_cmap14_ensure( TT_CMap14 cmap, + FT_UInt num_results, + FT_Memory memory ) + { + FT_UInt old_max = cmap->max_results; + FT_Error error = 0; + + + if ( num_results > cmap->max_results ) + { + cmap->memory = memory; + + if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) ) + return error; + + cmap->max_results = num_results; + } + + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap14_init( TT_CMap14 cmap, + FT_Byte* table ) + { + cmap->cmap.data = table; + + table += 6; + cmap->num_selectors = FT_PEEK_ULONG( table ); + cmap->max_results = 0; + cmap->results = NULL; + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap14_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 2; + FT_ULong length = TT_NEXT_ULONG( p ); + FT_ULong num_selectors = TT_NEXT_ULONG( p ); + + + if ( table + length > valid->limit || length < 10 + 11 * num_selectors ) + FT_INVALID_TOO_SHORT; + + /* check selectors, they must be in increasing order */ + { + /* we start lastVarSel at 1 because a variant selector value of 0 + * isn't valid. + */ + FT_ULong n, lastVarSel = 1; + + + for ( n = 0; n < num_selectors; n++ ) + { + FT_ULong varSel = TT_NEXT_UINT24( p ); + FT_ULong defOff = TT_NEXT_ULONG( p ); + FT_ULong nondefOff = TT_NEXT_ULONG( p ); + + + if ( defOff >= length || nondefOff >= length ) + FT_INVALID_TOO_SHORT; + + if ( varSel < lastVarSel ) + FT_INVALID_DATA; + + lastVarSel = varSel + 1; + + /* check the default table (these glyphs should be reached */ + /* through the normal Unicode cmap, no GIDs, just check order) */ + if ( defOff != 0 ) + { + FT_Byte* defp = table + defOff; + FT_ULong numRanges = TT_NEXT_ULONG( defp ); + FT_ULong i; + FT_ULong lastBase = 0; + + + if ( defp + numRanges * 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + for ( i = 0; i < numRanges; ++i ) + { + FT_ULong base = TT_NEXT_UINT24( defp ); + FT_ULong cnt = FT_NEXT_BYTE( defp ); + + + if ( base + cnt >= 0x110000UL ) /* end of Unicode */ + FT_INVALID_DATA; + + if ( base < lastBase ) + FT_INVALID_DATA; + + lastBase = base + cnt + 1U; + } + } + + /* and the non-default table (these glyphs are specified here) */ + if ( nondefOff != 0 ) { + FT_Byte* ndp = table + nondefOff; + FT_ULong numMappings = TT_NEXT_ULONG( ndp ); + FT_ULong i, lastUni = 0; + + + if ( ndp + numMappings * 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + for ( i = 0; i < numMappings; ++i ) + { + FT_ULong uni = TT_NEXT_UINT24( ndp ); + FT_ULong gid = TT_NEXT_USHORT( ndp ); + + + if ( uni >= 0x110000UL ) /* end of Unicode */ + FT_INVALID_DATA; + + if ( uni < lastUni ) + FT_INVALID_DATA; + + lastUni = uni + 1U; + + if ( valid->level >= FT_VALIDATE_TIGHT && + gid >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + } + } + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap14_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_UNUSED( cmap ); + FT_UNUSED( char_code ); + + /* This can't happen */ + return 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap14_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UNUSED( cmap ); + + /* This can't happen */ + *pchar_code = 0; + return 0; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap14_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_UNUSED( cmap ); + + cmap_info->format = 14; + /* subtable 14 does not define a language field */ + cmap_info->language = 0xFFFFFFFFUL; + + return SFNT_Err_Ok; + } + + + static FT_UInt + tt_cmap14_char_map_def_binary( FT_Byte *base, + FT_UInt32 char_code ) + { + FT_UInt32 numRanges = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numRanges; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 4 * mid; + FT_ULong start = TT_NEXT_UINT24( p ); + FT_UInt cnt = FT_NEXT_BYTE( p ); + + + if ( char_code < start ) + max = mid; + else if ( char_code > start+cnt ) + min = mid + 1; + else + return TRUE; + } + + return FALSE; + } + + + static FT_UInt + tt_cmap14_char_map_nondef_binary( FT_Byte *base, + FT_UInt32 char_code ) + { + FT_UInt32 numMappings = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numMappings; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 5 * mid; + FT_UInt32 uni = TT_NEXT_UINT24( p ); + + + if ( char_code < uni ) + max = mid; + else if ( char_code > uni ) + min = mid + 1; + else + return TT_PEEK_USHORT( p ); + } + + return 0; + } + + + static FT_Byte* + tt_cmap14_find_variant( FT_Byte *base, + FT_UInt32 variantCode ) + { + FT_UInt32 numVar = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numVar; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 11 * mid; + FT_ULong varSel = TT_NEXT_UINT24( p ); + + + if ( variantCode < varSel ) + max = mid; + else if ( variantCode > varSel ) + min = mid + 1; + else + return p; + } + + return NULL; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap14_char_var_index( TT_CMap cmap, + TT_CMap ucmap, + FT_ULong charcode, + FT_ULong variantSelector) + { + FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); + FT_ULong defOff; + FT_ULong nondefOff; + + + if ( !p ) + return 0; + + defOff = TT_NEXT_ULONG( p ); + nondefOff = TT_PEEK_ULONG( p ); + + if ( defOff != 0 && + tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) + { + /* This is the default variant of this charcode. GID not stored */ + /* here; stored in the normal Unicode charmap instead. */ + return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode ); + } + + if ( nondefOff != 0 ) + return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, + charcode ); + + return 0; + } + + + FT_CALLBACK_DEF( FT_Int ) + tt_cmap14_char_var_isdefault( TT_CMap cmap, + FT_ULong charcode, + FT_ULong variantSelector ) + { + FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); + FT_ULong defOff; + FT_ULong nondefOff; + + + if ( !p ) + return -1; + + defOff = TT_NEXT_ULONG( p ); + nondefOff = TT_NEXT_ULONG( p ); + + if ( defOff != 0 && + tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) + return 1; + + if ( nondefOff != 0 && + tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, + charcode ) != 0 ) + return 0; + + return -1; + } + + + FT_CALLBACK_DEF( FT_UInt32* ) + tt_cmap14_variants( TT_CMap cmap, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14)cmap; + FT_UInt count = cmap14->num_selectors; + FT_Byte* p = cmap->data + 10; + FT_UInt32* result; + FT_UInt i; + + + if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) + return NULL; + + result = cmap14->results; + for ( i = 0; i < count; ++i ) + { + result[i] = TT_NEXT_UINT24( p ); + p += 8; + } + result[i] = 0; + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 * ) + tt_cmap14_char_variants( TT_CMap cmap, + FT_Memory memory, + FT_ULong charCode ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt count = cmap14->num_selectors; + FT_Byte* p = cmap->data + 10; + FT_UInt32* q; + + + if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) + return NULL; + + for ( q = cmap14->results; count > 0; --count ) + { + FT_UInt32 varSel = TT_NEXT_UINT24( p ); + FT_ULong defOff = TT_NEXT_ULONG( p ); + FT_ULong nondefOff = TT_NEXT_ULONG( p ); + + + if ( ( defOff != 0 && + tt_cmap14_char_map_def_binary( cmap->data + defOff, + charCode ) ) || + ( nondefOff != 0 && + tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, + charCode ) != 0 ) ) + { + q[0] = varSel; + q++; + } + } + q[0] = 0; + + return cmap14->results; + } + + + static FT_UInt + tt_cmap14_def_char_count( FT_Byte *p ) + { + FT_UInt32 numRanges = TT_NEXT_ULONG( p ); + FT_UInt tot = 0; + + + p += 3; /* point to the first 'cnt' field */ + for ( ; numRanges > 0; numRanges-- ) + { + tot += 1 + p[0]; + p += 4; + } + + return tot; + } + + + static FT_UInt32* + tt_cmap14_get_def_chars( TT_CMap cmap, + FT_Byte* p, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numRanges; + FT_UInt cnt; + FT_UInt32* q; + + + cnt = tt_cmap14_def_char_count( p ); + numRanges = TT_NEXT_ULONG( p ); + + if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) ) + return NULL; + + for ( q = cmap14->results; numRanges > 0; --numRanges ) + { + FT_UInt uni = TT_NEXT_UINT24( p ); + + + cnt = FT_NEXT_BYTE( p ) + 1; + do + { + q[0] = uni; + uni += 1; + q += 1; + } while ( --cnt != 0 ); + } + q[0] = 0; + + return cmap14->results; + } + + + static FT_UInt* + tt_cmap14_get_nondef_chars( TT_CMap cmap, + FT_Byte *p, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numMappings; + FT_UInt i; + FT_UInt32 *ret; + + + numMappings = TT_NEXT_ULONG( p ); + + if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) ) + return NULL; + + ret = cmap14->results; + for ( i = 0; i < numMappings; ++i ) + { + ret[i] = TT_NEXT_UINT24( p ); + p += 2; + } + ret[i] = 0; + + return ret; + } + + + FT_CALLBACK_DEF( FT_UInt32 * ) + tt_cmap14_variant_chars( TT_CMap cmap, + FT_Memory memory, + FT_ULong variantSelector ) + { + FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, + variantSelector ); + FT_UInt32 *ret; + FT_Int i; + FT_ULong defOff; + FT_ULong nondefOff; + + + if ( !p ) + return NULL; + + defOff = TT_NEXT_ULONG( p ); + nondefOff = TT_NEXT_ULONG( p ); + + if ( defOff == 0 && nondefOff == 0 ) + return NULL; + + if ( defOff == 0 ) + return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, + memory ); + else if ( nondefOff == 0 ) + return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, + memory ); + else + { + /* Both a default and a non-default glyph set? That's probably not */ + /* good font design, but the spec allows for it... */ + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numRanges; + FT_UInt32 numMappings; + FT_UInt32 duni; + FT_UInt32 dcnt; + FT_UInt32 nuni; + FT_Byte* dp; + FT_UInt di, ni, k; + + + p = cmap->data + nondefOff; + dp = cmap->data + defOff; + + numMappings = TT_NEXT_ULONG( p ); + dcnt = tt_cmap14_def_char_count( dp ); + numRanges = TT_NEXT_ULONG( dp ); + + if ( numMappings == 0 ) + return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, + memory ); + if ( dcnt == 0 ) + return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, + memory ); + + if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) ) + return NULL; + + ret = cmap14->results; + duni = TT_NEXT_UINT24( dp ); + dcnt = FT_NEXT_BYTE( dp ); + di = 1; + nuni = TT_NEXT_UINT24( p ); + p += 2; + ni = 1; + i = 0; + + for ( ;; ) + { + if ( nuni > duni + dcnt ) + { + for ( k = 0; k <= dcnt; ++k ) + ret[i++] = duni + k; + + ++di; + + if ( di > numRanges ) + break; + + duni = TT_NEXT_UINT24( dp ); + dcnt = FT_NEXT_BYTE( dp ); + } + else + { + if ( nuni < duni ) + ret[i++] = nuni; + /* If it is within the default range then ignore it -- */ + /* that should not have happened */ + ++ni; + if ( ni > numMappings ) + break; + + nuni = TT_NEXT_UINT24( p ); + p += 2; + } + } + + if ( ni <= numMappings ) + { + /* If we get here then we have run out of all default ranges. */ + /* We have read one non-default mapping which we haven't stored */ + /* and there may be others that need to be read. */ + ret[i++] = nuni; + while ( ni < numMappings ) + { + ret[i++] = TT_NEXT_UINT24( p ); + p += 2; + ++ni; + } + } + else if ( di <= numRanges ) + { + /* If we get here then we have run out of all non-default */ + /* mappings. We have read one default range which we haven't */ + /* stored and there may be others that need to be read. */ + for ( k = 0; k <= dcnt; ++k ) + ret[i++] = duni + k; + + while ( di < numRanges ) + { + duni = TT_NEXT_UINT24( dp ); + dcnt = FT_NEXT_BYTE( dp ); + + for ( k = 0; k <= dcnt; ++k ) + ret[i++] = duni + k; + ++di; + } + } + + ret[i] = 0; + + return ret; + } + } + + + FT_CALLBACK_TABLE_DEF + const TT_CMap_ClassRec tt_cmap14_class_rec = + { + { + sizeof ( TT_CMap14Rec ), + + (FT_CMap_InitFunc) tt_cmap14_init, + (FT_CMap_DoneFunc) tt_cmap14_done, + (FT_CMap_CharIndexFunc)tt_cmap14_char_index, + (FT_CMap_CharNextFunc) tt_cmap14_char_next, + + /* Format 14 extension functions */ + (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index, + (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault, + (FT_CMap_VariantListFunc) tt_cmap14_variants, + (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants, + (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars + }, + 14, + (TT_CMap_ValidateFunc)tt_cmap14_validate, + (TT_CMap_Info_GetFunc)tt_cmap14_get_info + }; + +#endif /* TT_CONFIG_CMAP_FORMAT_0 */ + + static const TT_CMap_Class tt_cmap_classes[] = { #ifdef TT_CONFIG_CMAP_FORMAT_0 @@ -2242,6 +2995,10 @@ &tt_cmap12_class_rec, #endif +#ifdef TT_CONFIG_CMAP_FORMAT_14 + &tt_cmap14_class_rec, +#endif + NULL, }; @@ -2318,6 +3075,10 @@ FT_CMap ttcmap; + /* It might make sense to store the single variation selector */ + /* cmap somewhere special. But it would have to be in the */ + /* public FT_FaceRec, and we can't change that. */ + if ( !FT_CMap_New( (FT_CMap_Class)clazz, cmap, &charmap, &ttcmap ) ) { @@ -2334,6 +3095,12 @@ break; } } + + if ( *pclazz == NULL ) + { + FT_ERROR(( "tt_face_build_cmaps:" )); + FT_ERROR(( " unsupported cmap sub-table ignored!\n" )); + } } } diff --git a/Build/source/libs/freetype2/src/sfnt/ttload.c b/Build/source/libs/freetype2/src/sfnt/ttload.c index abe0278a253..6b7c3426285 100644 --- a/Build/source/libs/freetype2/src/sfnt/ttload.c +++ b/Build/source/libs/freetype2/src/sfnt/ttload.c @@ -5,7 +5,7 @@ /* Load the basic TrueType tables, i.e., tables that can be either in */ /* TTF or OTF fonts (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -618,6 +618,15 @@ if ( maxProfile->maxFunctionDefs == 0 ) maxProfile->maxFunctionDefs = 64; + + /* we add 4 phantom points later */ + if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) ) + { + FT_ERROR(( "Too much twilight points in `maxp' table;\n" )); + FT_ERROR(( " some glyphs might be rendered incorrectly.\n" )); + + maxProfile->maxTwilightPoints = 0xFFFFU - 4; + } } FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs )); diff --git a/Build/source/libs/freetype2/src/sfnt/ttmtx.c b/Build/source/libs/freetype2/src/sfnt/ttmtx.c index 286bd0c311c..55f681abae1 100644 --- a/Build/source/libs/freetype2/src/sfnt/ttmtx.c +++ b/Build/source/libs/freetype2/src/sfnt/ttmtx.c @@ -431,7 +431,8 @@ { void* v = &face->vertical; void* h = &face->horizontal; - TT_HoriHeader* header = vertical ? (TT_HoriHeader*)v : h; + TT_HoriHeader* header = vertical ? (TT_HoriHeader*)v + : (TT_HoriHeader*)h; TT_LongMetrics longs_m; FT_UShort k = header->number_Of_HMetrics; diff --git a/Build/source/libs/freetype2/src/sfnt/ttsbit.c b/Build/source/libs/freetype2/src/sfnt/ttsbit.c index eff49dadd9a..8261ba55350 100644 --- a/Build/source/libs/freetype2/src/sfnt/ttsbit.c +++ b/Build/source/libs/freetype2/src/sfnt/ttsbit.c @@ -382,8 +382,9 @@ break; case 5: - error = Load_SBit_Const_Metrics( range, stream ) || - Load_SBit_Range_Codes( range, stream, 0 ); + error = Load_SBit_Const_Metrics( range, stream ); + if ( !error ) + error = Load_SBit_Range_Codes( range, stream, 0 ); break; default: diff --git a/Build/source/libs/freetype2/src/sfnt/ttsbit0.c b/Build/source/libs/freetype2/src/sfnt/ttsbit0.c index f8adc64a735..37c7a9bbefb 100644 --- a/Build/source/libs/freetype2/src/sfnt/ttsbit0.c +++ b/Build/source/libs/freetype2/src/sfnt/ttsbit0.c @@ -5,7 +5,7 @@ /* TrueType and OpenType embedded bitmap support (body). */ /* This is a heap-optimized version. */ /* */ -/* Copyright 2005, 2006, 2007 by */ +/* Copyright 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -207,7 +207,7 @@ } - typedef struct + typedef struct TT_SBitDecoderRec_ { TT_Face face; FT_Stream stream; diff --git a/Build/source/libs/freetype2/src/smooth/ftgrays.c b/Build/source/libs/freetype2/src/smooth/ftgrays.c index 5a4a544e5a5..add1dd24ab1 100644 --- a/Build/source/libs/freetype2/src/smooth/ftgrays.c +++ b/Build/source/libs/freetype2/src/smooth/ftgrays.c @@ -144,10 +144,10 @@ #include "ftsmerrs.h" -#define ErrRaster_Invalid_Mode Smooth_Err_Cannot_Render_Glyph -#define ErrRaster_Invalid_Outline Smooth_Err_Invalid_Outline -#define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory -#define ErrRaster_Invalid_Argument Smooth_Err_Bad_Argument +#define ErrRaster_Invalid_Mode Smooth_Err_Cannot_Render_Glyph +#define ErrRaster_Invalid_Outline Smooth_Err_Invalid_Outline +#define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory +#define ErrRaster_Invalid_Argument Smooth_Err_Bad_Argument #endif /* !_STANDALONE_ */ @@ -1659,7 +1659,7 @@ ras.count_ex = ras.max_ex - ras.min_ex; ras.count_ey = ras.max_ey - ras.min_ey; - /* simple heuristic used to speed-up the bezier decomposition -- see */ + /* simple heuristic used to speed up the bezier decomposition -- see */ /* the code in gray_render_conic() and gray_render_cubic() for more */ /* details */ ras.conic_level = 32; @@ -1796,11 +1796,14 @@ if ( !raster || !raster->buffer || !raster->buffer_size ) return ErrRaster_Invalid_Argument; + if ( !outline ) + return ErrRaster_Invalid_Outline; + /* return immediately if the outline is empty */ if ( outline->n_points == 0 || outline->n_contours <= 0 ) return 0; - if ( !outline || !outline->contours || !outline->points ) + if ( !outline->contours || !outline->points ) return ErrRaster_Invalid_Outline; if ( outline->n_points != @@ -1850,10 +1853,10 @@ gray_init_cells( worker, raster->buffer, raster->buffer_size ); - ras.outline = *outline; - ras.num_cells = 0; - ras.invalid = 1; - ras.band_size = raster->band_size; + ras.outline = *outline; + ras.num_cells = 0; + ras.invalid = 1; + ras.band_size = raster->band_size; ras.num_gray_spans = 0; if ( target_map ) diff --git a/Build/source/libs/freetype2/src/tools/apinames.c b/Build/source/libs/freetype2/src/tools/apinames.c index f08919bee6c..19aec500bf2 100644 --- a/Build/source/libs/freetype2/src/tools/apinames.c +++ b/Build/source/libs/freetype2/src/tools/apinames.c @@ -10,7 +10,7 @@ * accepted if you are using GCC for compilation (and probably by * other compilers too). * - * Author: David Turner, 2005, 2006 + * Author: David Turner, 2005, 2006, 2008 * * This code is explicitly placed into the public domain. * @@ -26,7 +26,7 @@ #define LINEBUFF_SIZE 1024 -typedef enum +typedef enum OutputFormat_ { OUTPUT_LIST = 0, /* output the list of names, one per line */ OUTPUT_WINDOWS_DEF, /* output a Windows .DEF file for Visual C++ or Mingw */ @@ -44,7 +44,7 @@ panic( const char* message ) } -typedef struct +typedef struct NameRec_ { char* name; unsigned int hash; @@ -191,7 +191,7 @@ names_dump( FILE* out, /* states of the line parser */ -typedef enum +typedef enum State_ { STATE_START = 0, /* waiting for FT_EXPORT keyword and return type */ STATE_TYPE /* type was read, waiting for function name */ diff --git a/Build/source/libs/freetype2/src/tools/docmaker/content.py b/Build/source/libs/freetype2/src/tools/docmaker/content.py index b14c52edefd..c10a4edb852 100644 --- a/Build/source/libs/freetype2/src/tools/docmaker/content.py +++ b/Build/source/libs/freetype2/src/tools/docmaker/content.py @@ -1,4 +1,4 @@ -# Content (c) 2002, 2004, 2006, 2007 David Turner <david@freetype.org> +# Content (c) 2002, 2004, 2006, 2007, 2008 David Turner <david@freetype.org> # # This file contains routines used to parse the content of documentation # comment blocks and build more structured objects out of them. @@ -34,6 +34,13 @@ re_code_end = re.compile( r"(\s*)}\s*$" ) re_identifier = re.compile( r'(\w*)' ) +# we collect macros ending in `_H'; while outputting the object data, we use +# this info together with the object's file location to emit the appropriate +# header file macro and name before the object itself +# +re_header_macro = re.compile( r'^#define\s{1,}(\w{1,}_H)\s{1,}<(.*)>' ) + + ############################################################################# # # The DocCode class is used to store source code lines. @@ -44,11 +51,11 @@ re_identifier = re.compile( r'(\w*)' ) # The object is filled line by line by the parser; it strips the leading # "margin" space from each input line before storing it in 'self.lines'. # -class DocCode: +class DocCode: - def __init__( self, margin, lines ): - self.lines = [] - self.words = None + def __init__( self, margin, lines ): + self.lines = [] + self.words = None # remove margin spaces for l in lines: @@ -56,15 +63,15 @@ class DocCode: l = l[margin:] self.lines.append( l ) - def dump( self, prefix = "", width=60 ): + def dump( self, prefix = "", width = 60 ): lines = self.dump_lines( 0, width ) for l in lines: print prefix + l - def dump_lines( self, margin=0, width=60 ): + def dump_lines( self, margin = 0, width = 60 ): result = [] for l in self.lines: - result.append( " "*margin + l ) + result.append( " " * margin + l ) return result @@ -75,34 +82,34 @@ class DocCode: # # 'self.words' contains the list of words that make up the paragraph # -class DocPara: +class DocPara: - def __init__( self, lines ): + def __init__( self, lines ): self.lines = None self.words = [] for l in lines: - l = string.strip(l) + l = string.strip( l ) self.words.extend( string.split( l ) ) - def dump( self, prefix = "", width = 60 ): + def dump( self, prefix = "", width = 60 ): lines = self.dump_lines( 0, width ) for l in lines: print prefix + l - def dump_lines( self, margin=0, width = 60 ): + def dump_lines( self, margin = 0, width = 60 ): cur = "" # current line col = 0 # current width result = [] for word in self.words: - ln = len(word) + ln = len( word ) if col > 0: - ln = ln+1 + ln = ln + 1 if col + ln > width: - result.append( " "*margin + cur ) + result.append( " " * margin + cur ) cur = word - col = len(word) + col = len( word ) else: if col > 0: cur = cur + " " @@ -110,31 +117,29 @@ class DocPara: col = col + ln if col > 0: - result.append( " "*margin + cur ) + result.append( " " * margin + cur ) return result - ############################################################################# # # The DocField class is used to store a list containing either DocPara or # DocCode objects. Each DocField also has an optional "name" which is used # when the object corresponds to a field or value definition # -class DocField: - - def __init__( self, name, lines ): +class DocField: + def __init__( self, name, lines ): self.name = name # can be None for normal paragraphs/sources - self.items = [] # list of items + self.items = [] # list of items - mode_none = 0 # start parsing mode - mode_code = 1 # parsing code sequences - mode_para = 3 # parsing normal paragraph + mode_none = 0 # start parsing mode + mode_code = 1 # parsing code sequences + mode_para = 3 # parsing normal paragraph - margin = -1 # current code sequence indentation + margin = -1 # current code sequence indentation cur_lines = [] # now analyze the markup lines to see if they contain paragraphs, @@ -142,13 +147,12 @@ class DocField: # start = 0 mode = mode_none - for l in lines: + for l in lines: # are we parsing a code sequence ? if mode == mode_code: - m = re_code_end.match( l ) - if m and len(m.group(1)) <= margin: + if m and len( m.group( 1 ) ) <= margin: # that's it, we finised the code sequence code = DocCode( 0, cur_lines ) self.items.append( code ) @@ -169,9 +173,8 @@ class DocField: cur_lines = [] # switch to code extraction mode - margin = len(m.group(1)) + margin = len( m.group( 1 ) ) mode = mode_code - else: if not string.split( l ) and cur_lines: # if the line is empty, we end the current paragraph, @@ -188,12 +191,11 @@ class DocField: # unexpected end of code sequence code = DocCode( margin, cur_lines ) self.items.append( code ) - elif cur_lines: para = DocPara( cur_lines ) self.items.append( para ) - def dump( self, prefix = "" ): + def dump( self, prefix = "" ): if self.field: print prefix + self.field + " ::" prefix = prefix + "----" @@ -205,9 +207,10 @@ class DocField: p.dump( prefix ) first = 0 - def dump_lines( self, margin=0, width=60 ): + def dump_lines( self, margin = 0, width = 60 ): result = [] nl = None + for p in self.items: if nl: result.append( "" ) @@ -217,17 +220,19 @@ class DocField: return result + + # this regular expression is used to detect field definitions # -re_field = re.compile( r"\s*(\w*|\w(\w|\.)*\w)\s*::" ) +re_field = re.compile( r"\s*(\w*|\w(\w|\.)*\w)\s*::" ) -class DocMarkup: +class DocMarkup: - def __init__( self, tag, lines ): - self.tag = string.lower(tag) - self.fields = [] + def __init__( self, tag, lines ): + self.tag = string.lower( tag ) + self.fields = [] cur_lines = [] field = None @@ -245,10 +250,10 @@ class DocMarkup: cur_lines = [] field = None - field = m.group(1) # record field name - ln = len(m.group(0)) - l = " "*ln + l[ln:] - cur_lines = [ l ] + field = m.group( 1 ) # record field name + ln = len( m.group( 0 ) ) + l = " " * ln + l[ln:] + cur_lines = [l] else: cur_lines.append( l ) @@ -256,51 +261,48 @@ class DocMarkup: f = DocField( field, cur_lines ) self.fields.append( f ) - def get_name( self ): + def get_name( self ): try: return self.fields[0].items[0].words[0] - except: return None - def get_start( self ): + def get_start( self ): try: result = "" for word in self.fields[0].items[0].words: result = result + " " + word return result[1:] - except: return "ERROR" - def dump( self, margin ): - print " "*margin + "<" + self.tag + ">" + def dump( self, margin ): + print " " * margin + "<" + self.tag + ">" for f in self.fields: f.dump( " " ) - print " "*margin + "</" + self.tag + ">" - + print " " * margin + "</" + self.tag + ">" -class DocChapter: +class DocChapter: - def __init__( self, block ): + def __init__( self, block ): self.block = block self.sections = [] if block: - self.name = block.name - self.title = block.get_markup_words( "title" ) - self.order = block.get_markup_words( "sections" ) + self.name = block.name + self.title = block.get_markup_words( "title" ) + self.order = block.get_markup_words( "sections" ) else: - self.name = "Other" - self.title = string.split( "Miscellaneous" ) - self.order = [] + self.name = "Other" + self.title = string.split( "Miscellaneous" ) + self.order = [] -class DocSection: +class DocSection: - def __init__( self, name = "Other" ): + def __init__( self, name = "Other" ): self.name = name self.blocks = {} self.block_names = [] # ordered block names in section @@ -311,14 +313,14 @@ class DocSection: self.title = "ERROR" self.chapter = None - def add_def( self, block ): + def add_def( self, block ): self.defs.append( block ) - def add_block( self, block ): + def add_block( self, block ): self.block_names.append( block.name ) - self.blocks[ block.name ] = block + self.blocks[block.name] = block - def process( self ): + def process( self ): # lookup one block that contains a valid section description for block in self.defs: title = block.get_markup_text( "title" ) @@ -329,49 +331,51 @@ class DocSection: self.order = block.get_markup_words( "order" ) return - def reorder( self ): - + def reorder( self ): self.block_names = sort_order_list( self.block_names, self.order ) -class ContentProcessor: - def __init__( self ): +class ContentProcessor: + + def __init__( self ): """initialize a block content processor""" self.reset() self.sections = {} # dictionary of documentation sections self.section = None # current documentation section - self.chapters = [] # list of chapters + self.chapters = [] # list of chapters - def set_section( self, section_name ): + self.headers = {} # dictionary of header macros + + def set_section( self, section_name ): """set current section during parsing""" if not self.sections.has_key( section_name ): section = DocSection( section_name ) - self.sections[ section_name ] = section - self.section = section + self.sections[section_name] = section + self.section = section else: - self.section = self.sections[ section_name ] + self.section = self.sections[section_name] - def add_chapter( self, block ): + def add_chapter( self, block ): chapter = DocChapter( block ) self.chapters.append( chapter ) - def reset( self ): + def reset( self ): """reset the content processor for a new block""" self.markups = [] self.markup = None self.markup_lines = [] - def add_markup( self ): + def add_markup( self ): """add a new markup section""" if self.markup and self.markup_lines: # get rid of last line of markup if it's empty marks = self.markup_lines - if len(marks) > 0 and not string.strip(marks[-1]): + if len( marks ) > 0 and not string.strip( marks[-1] ): self.markup_lines = marks[:-1] m = DocMarkup( self.markup, self.markup_lines ) @@ -381,8 +385,7 @@ class ContentProcessor: self.markup = None self.markup_lines = [] - - def process_content( self, content ): + def process_content( self, content ): """process a block content and return a list of DocMarkup objects corresponding to it""" markup = None @@ -394,9 +397,9 @@ class ContentProcessor: for t in re_markup_tags: m = t.match( line ) if m: - found = string.lower(m.group(1)) - prefix = len(m.group(0)) - line = " "*prefix + line[prefix:] # remove markup from line + found = string.lower( m.group( 1 ) ) + prefix = len( m.group( 0 ) ) + line = " " * prefix + line[prefix:] # remove markup from line break # is it the start of a new markup section ? @@ -404,7 +407,7 @@ class ContentProcessor: first = 0 self.add_markup() # add current markup content self.markup = found - if len(string.strip( line )) > 0: + if len( string.strip( line ) ) > 0: self.markup_lines.append( line ) elif first == 0: self.markup_lines.append( line ) @@ -413,28 +416,25 @@ class ContentProcessor: return self.markups - def parse_sources( self, source_processor ): blocks = source_processor.blocks - count = len(blocks) - for n in range(count): + count = len( blocks ) + for n in range( count ): source = blocks[n] if source.content: # this is a documentation comment, we need to catch # all following normal blocks in the "follow" list # follow = [] - m = n+1 + m = n + 1 while m < count and not blocks[m].content: follow.append( blocks[m] ) - m = m+1 + m = m + 1 doc_block = DocBlock( source, follow, self ) - def finish( self ): - # process all sections to extract their abstract, description # and ordered list of items # @@ -445,13 +445,13 @@ class ContentProcessor: # listed there for chap in self.chapters: for sec in chap.order: - if self.sections.has_key(sec): - section = self.sections[ sec ] + if self.sections.has_key( sec ): + section = self.sections[sec] section.chapter = chap section.reorder() chap.sections.append( section ) else: - sys.stderr.write( "WARNING: chapter '" + + sys.stderr.write( "WARNING: chapter '" + \ chap.name + "' in " + chap.block.location() + \ " lists unknown section '" + sec + "'\n" ) @@ -460,7 +460,7 @@ class ContentProcessor: others = [] for sec in self.sections.values(): if not sec.chapter: - others.append(sec) + others.append( sec ) # create a new special chapter for all remaining sections # when necessary @@ -472,18 +472,17 @@ class ContentProcessor: -class DocBlock: - - def __init__( self, source, follow, processor ): +class DocBlock: + def __init__( self, source, follow, processor ): processor.reset() - self.source = source - self.code = [] - self.type = "ERRTYPE" - self.name = "ERRNAME" - self.section = processor.section - self.markups = processor.process_content( source.content ) + self.source = source + self.code = [] + self.type = "ERRTYPE" + self.name = "ERRNAME" + self.section = processor.section + self.markups = processor.process_content( source.content ) # compute block type from first markup tag try: @@ -491,7 +490,6 @@ class DocBlock: except: pass - # compute block name from first markup paragraph try: markup = self.markups[0] @@ -499,20 +497,18 @@ class DocBlock: name = para.words[0] m = re_identifier.match( name ) if m: - name = m.group(1) + name = m.group( 1 ) self.name = name except: pass - # detect new section starts if self.type == "section": + # detect new section starts processor.set_section( self.name ) processor.section.add_def( self ) - - # detect new chapter elif self.type == "chapter": + # detect new chapter processor.add_chapter( self ) - else: processor.section.add_block( self ) @@ -523,6 +519,11 @@ class DocBlock: if b.format: break for l in b.lines: + # collect header macro definitions + m = re_header_macro.match( l ) + if m: + processor.headers[m.group( 2 )] = m.group( 1 ); + # we use "/* */" as a separator if re_source_sep.match( l ): break @@ -530,7 +531,7 @@ class DocBlock: # now strip the leading and trailing empty lines from the sources start = 0 - end = len( source )-1 + end = len( source ) - 1 while start < end and not string.strip( source[start] ): start = start + 1 @@ -538,25 +539,21 @@ class DocBlock: while start < end and not string.strip( source[end] ): end = end - 1 - source = source[start:end+1] + source = source[start:end + 1] self.code = source - - def location( self ): + def location( self ): return self.source.location() - - - def get_markup( self, tag_name ): + def get_markup( self, tag_name ): """return the DocMarkup corresponding to a given tag in a block""" for m in self.markups: - if m.tag == string.lower(tag_name): + if m.tag == string.lower( tag_name ): return m return None - - def get_markup_name( self, tag_name ): + def get_markup_name( self, tag_name ): """return the name of a given primary markup in a block""" try: m = self.get_markup( tag_name ) @@ -564,21 +561,18 @@ class DocBlock: except: return None - - def get_markup_words( self, tag_name ): + def get_markup_words( self, tag_name ): try: m = self.get_markup( tag_name ) return m.fields[0].items[0].words except: return [] - - def get_markup_text( self, tag_name ): + def get_markup_text( self, tag_name ): result = self.get_markup_words( tag_name ) return string.join( result ) - - def get_markup_items( self, tag_name ): + def get_markup_items( self, tag_name ): try: m = self.get_markup( tag_name ) return m.fields[0].items diff --git a/Build/source/libs/freetype2/src/tools/docmaker/docbeauty.py b/Build/source/libs/freetype2/src/tools/docmaker/docbeauty.py index 55c43297f1f..3ddf4a94a15 100644 --- a/Build/source/libs/freetype2/src/tools/docmaker/docbeauty.py +++ b/Build/source/libs/freetype2/src/tools/docmaker/docbeauty.py @@ -1,23 +1,24 @@ #!/usr/bin/env python # -# DocBeauty (c) 2003, 2004 David Turner <david@freetype.org> +# DocBeauty (c) 2003, 2004, 2008 David Turner <david@freetype.org> # # This program is used to beautify the documentation comments used # in the FreeType 2 public headers. # -from sources import * -from content import * -from utils import * +from sources import * +from content import * +from utils import * import utils import sys, os, time, string, getopt + content_processor = ContentProcessor() -def beautify_block( block ): +def beautify_block( block ): if block.content: content_processor.reset() @@ -30,7 +31,7 @@ def beautify_block( block ): first = 0 # now beautify the documentation "borders" themselves - lines = [ " /*************************************************************************" ] + lines = [" /*************************************************************************"] for l in text: lines.append( " *" + l ) lines.append( " */" ) @@ -38,9 +39,9 @@ def beautify_block( block ): block.lines = lines -def usage(): +def usage(): print "\nDocBeauty 0.1 Usage information\n" - print " docbeauty [options] file1 [ file2 ... ]\n" + print " docbeauty [options] file1 [file2 ...]\n" print "using the following options:\n" print " -h : print this page" print " -b : backup original files with the 'orig' extension" @@ -48,16 +49,15 @@ def usage(): print " --backup : same as -b" -def main( argv ): +def main( argv ): """main program loop""" global output_dir try: - opts, args = getopt.getopt( sys.argv[1:], - "hb", - [ "help", "backup" ] ) - + opts, args = getopt.getopt( sys.argv[1:], \ + "hb", \ + ["help", "backup"] ) except getopt.GetoptError: usage() sys.exit( 2 ) @@ -80,16 +80,19 @@ def main( argv ): do_backup = 1 # create context and processor - source_processor = SourceProcessor() + source_processor = SourceProcessor() # retrieve the list of files to process file_list = make_file_list( args ) for filename in file_list: source_processor.parse_file( filename ) + for block in source_processor.blocks: beautify_block( block ) + new_name = filename + ".new" ok = None + try: file = open( new_name, "wt" ) for block in source_processor.blocks: @@ -100,6 +103,7 @@ def main( argv ): except: ok = 0 + # if called from the command line # if __name__ == '__main__': diff --git a/Build/source/libs/freetype2/src/tools/docmaker/docmaker.py b/Build/source/libs/freetype2/src/tools/docmaker/docmaker.py index d34b6e8f96b..1d9de9fbff2 100644 --- a/Build/source/libs/freetype2/src/tools/docmaker/docmaker.py +++ b/Build/source/libs/freetype2/src/tools/docmaker/docmaker.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# DocMaker (c) 2002, 2004 David Turner <david@freetype.org> +# DocMaker (c) 2002, 2004, 2008 David Turner <david@freetype.org> # # This program is a re-write of the original DocMaker took used # to generate the API Reference of the FreeType font engine @@ -24,9 +24,9 @@ import utils import sys, os, time, string, glob, getopt -def usage(): +def usage(): print "\nDocMaker Usage information\n" - print " docmaker [options] file1 [ file2 ... ]\n" + print " docmaker [options] file1 [file2 ...]\n" print "using the following options:\n" print " -h : print this page" print " -t : set project title, as in '-t \"My Project\"'" @@ -38,16 +38,15 @@ def usage(): print " --prefix : same as -p, as in '--prefix=ft2'" -def main( argv ): +def main( argv ): """main program loop""" global output_dir try: - opts, args = getopt.getopt( sys.argv[1:], - "ht:o:p:", - [ "help", "title=", "output=", "prefix=" ] ) - + opts, args = getopt.getopt( sys.argv[1:], \ + "ht:o:p:", \ + ["help", "title=", "output=", "prefix="] ) except getopt.GetoptError: usage() sys.exit( 2 ) @@ -76,7 +75,7 @@ def main( argv ): if opt[0] in ( "-p", "--prefix" ): project_prefix = opt[1] - check_output( ) + check_output() # create context and processor source_processor = SourceProcessor() diff --git a/Build/source/libs/freetype2/src/tools/docmaker/formatter.py b/Build/source/libs/freetype2/src/tools/docmaker/formatter.py index 363410efc76..f62ce676c15 100644 --- a/Build/source/libs/freetype2/src/tools/docmaker/formatter.py +++ b/Build/source/libs/freetype2/src/tools/docmaker/formatter.py @@ -1,4 +1,4 @@ -# Formatter (c) 2002, 2004, 2007 David Turner <david@freetype.org> +# Formatter (c) 2002, 2004, 2007, 2008 David Turner <david@freetype.org> # from sources import * @@ -14,10 +14,9 @@ from utils import * # used to output -- you guessed it -- HTML. # -class Formatter: - - def __init__( self, processor ): +class Formatter: + def __init__( self, processor ): self.processor = processor self.identifiers = {} self.chapters = processor.chapters @@ -25,7 +24,7 @@ class Formatter: self.block_index = [] # store all blocks in a dictionary - self.blocks = [] + self.blocks = [] for section in self.sections: for block in section.blocks.values(): self.add_identifier( block.name, block ) @@ -36,26 +35,22 @@ class Formatter: for field in markup.fields: self.add_identifier( field.name, block ) - self.block_index = self.identifiers.keys() self.block_index.sort( index_sort ) - - def add_identifier( self, name, block ): + def add_identifier( self, name, block ): if self.identifiers.has_key( name ): - # duplicate name !! - sys.stderr.write( \ + # duplicate name! + sys.stderr.write( \ "WARNING: duplicate definition for '" + name + "' in " + \ block.location() + ", previous definition in " + \ - self.identifiers[ name ].location() + "\n" ) + self.identifiers[name].location() + "\n" ) else: self.identifiers[name] = block - # # Formatting the table of contents # - def toc_enter( self ): pass @@ -78,7 +73,6 @@ class Formatter: pass def toc_dump( self, toc_filename = None, index_filename = None ): - output = None if toc_filename: output = open_output( toc_filename ) @@ -93,7 +87,7 @@ class Formatter: self.toc_section_enter( section ) self.toc_section_exit( section ) - self.toc_chapter_exit ( chap ) + self.toc_chapter_exit( chap ) self.toc_index( index_filename ) @@ -105,7 +99,6 @@ class Formatter: # # Formatting the index # - def index_enter( self ): pass @@ -119,7 +112,6 @@ class Formatter: pass def index_dump( self, index_filename = None ): - output = None if index_filename: output = open_output( index_filename ) @@ -128,7 +120,7 @@ class Formatter: for name in self.block_index: self.index_name_enter( name ) - self.index_name_exit ( name ) + self.index_name_exit( name ) self.index_exit() @@ -162,9 +154,7 @@ class Formatter: def section_exit( self, section ): pass - def section_dump( self, section, section_filename = None ): - output = None if section_filename: output = open_output( section_filename ) @@ -172,33 +162,27 @@ class Formatter: self.section_enter( section ) for name in section.block_names: - block = self.identifiers[ name ] + block = self.identifiers[name] self.block_enter( block ) - for markup in block.markups[1:]: # always ignore first markup !! + for markup in block.markups[1:]: # always ignore first markup! self.markup_enter( markup, block ) for field in markup.fields: self.field_enter( field, markup, block ) - - self.field_exit ( field, markup, block ) + self.field_exit( field, markup, block ) self.markup_exit( markup, block ) self.block_exit( block ) - self.section_exit ( section ) + self.section_exit( section ) if output: close_output( output ) - - def section_dump_all( self ): + def section_dump_all( self ): for section in self.sections: self.section_dump( section ) - # - # Formatting a block - # - # eof diff --git a/Build/source/libs/freetype2/src/tools/docmaker/sources.py b/Build/source/libs/freetype2/src/tools/docmaker/sources.py index 09ff7f9970d..dcfbf7dae65 100644 --- a/Build/source/libs/freetype2/src/tools/docmaker/sources.py +++ b/Build/source/libs/freetype2/src/tools/docmaker/sources.py @@ -1,4 +1,4 @@ -# Sources (c) 2002, 2003, 2004, 2006, 2007 +# Sources (c) 2002, 2003, 2004, 2006, 2007, 2008 # David Turner <david@freetype.org> # # @@ -18,10 +18,8 @@ # the classes and methods found here only deal with text parsing # and basic documentation block extraction # -import fileinput, re, sys, os, string - - +import fileinput, re, sys, os, string @@ -36,11 +34,10 @@ import fileinput, re, sys, os, string ## note that the 'column' pattern must contain a group that will ## be used to "unbox" the content of documentation comment blocks ## -class SourceBlockFormat: +class SourceBlockFormat: - def __init__( self, id, start, column, end ): + def __init__( self, id, start, column, end ): """create a block pattern, used to recognize special documentation blocks""" - self.id = id self.start = re.compile( start, re.VERBOSE ) self.column = re.compile( column, re.VERBOSE ) @@ -61,9 +58,9 @@ class SourceBlockFormat: # start = r''' - \s* # any number of whitespace - /\*{2,}/ # followed by '/' and at least two asterisks then '/' - \s*$ # eventually followed by whitespace + \s* # any number of whitespace + /\*{2,}/ # followed by '/' and at least two asterisks then '/' + \s*$ # probably followed by whitespace ''' column = r''' @@ -71,11 +68,12 @@ column = r''' /\*{1} # followed by '/' and precisely one asterisk ([^*].*) # followed by anything (group 1) \*{1}/ # followed by one asterisk and a '/' - \s*$ # eventually followed by whitespace + \s*$ # probably followed by whitespace ''' re_source_block_format1 = SourceBlockFormat( 1, start, column, start ) + # # format 2 documentation comment blocks look like the following: # @@ -91,27 +89,28 @@ re_source_block_format1 = SourceBlockFormat( 1, start, column, start ) start = r''' \s* # any number of whitespace /\*{2,} # followed by '/' and at least two asterisks - \s*$ # eventually followed by whitespace + \s*$ # probably followed by whitespace ''' column = r''' - \s* # any number of whitespace - \*{1}(?!/) # followed by precisely one asterisk not followed by `/' - (.*) # then anything (group1) + \s* # any number of whitespace + \*{1}(?!/) # followed by precisely one asterisk not followed by `/' + (.*) # then anything (group1) ''' end = r''' - \s* # any number of whitespace - \*+/ # followed by at least one asterisk, then '/' + \s* # any number of whitespace + \*+/ # followed by at least one asterisk, then '/' ''' re_source_block_format2 = SourceBlockFormat( 2, start, column, end ) + # # the list of supported documentation block formats, we could add new ones # relatively easily # -re_source_block_formats = [ re_source_block_format1, re_source_block_format2 ] +re_source_block_formats = [re_source_block_format1, re_source_block_format2] # @@ -128,7 +127,7 @@ re_markup_tag2 = re.compile( r'''\s*@(\w*):''' ) # @xxxx: format # the list of supported markup tags, we could add new ones relatively # easily # -re_markup_tags = [ re_markup_tag1, re_markup_tag2 ] +re_markup_tags = [re_markup_tag1, re_markup_tag2] # # used to detect a cross-reference, after markup tags have been stripped @@ -175,6 +174,7 @@ re_source_keywords = re.compile( '''\\b ( typedef | \#else | \#endif ) \\b''', re.VERBOSE ) + ################################################################ ## ## SOURCE BLOCK CLASS @@ -198,8 +198,9 @@ re_source_keywords = re.compile( '''\\b ( typedef | ## (i.e. sources or ordinary comments with no starting ## markup tag) ## -class SourceBlock: - def __init__( self, processor, filename, lineno, lines ): +class SourceBlock: + + def __init__( self, processor, filename, lineno, lines ): self.processor = processor self.filename = filename self.lineno = lineno @@ -218,24 +219,22 @@ class SourceBlock: for line0 in self.lines: m = self.format.column.match( line0 ) if m: - lines.append( m.group(1) ) + lines.append( m.group( 1 ) ) # now, look for a markup tag for l in lines: - l = string.strip(l) - if len(l) > 0: + l = string.strip( l ) + if len( l ) > 0: for tag in re_markup_tags: if tag.match( l ): self.content = lines - return - - def location( self ): - return "(" + self.filename + ":" + repr(self.lineno) + ")" + return + def location( self ): + return "(" + self.filename + ":" + repr( self.lineno ) + ")" # debugging only - not used in normal operations - def dump( self ): - + def dump( self ): if self.content: print "{{{content start---" for l in self.content: @@ -245,12 +244,13 @@ class SourceBlock: fmt = "" if self.format: - fmt = repr(self.format.id) + " " + fmt = repr( self.format.id ) + " " for line in self.lines: print line + ################################################################ ## ## SOURCE PROCESSOR CLASS @@ -267,7 +267,7 @@ class SourceBlock: ## - normal sources lines, include comments ## ## -class SourceProcessor: +class SourceProcessor: def __init__( self ): """initialize a source processor""" @@ -281,39 +281,33 @@ class SourceProcessor: self.blocks = [] self.format = None - def parse_file( self, filename ): - """parse a C source file, and adds its blocks to the processor's list""" - + """parse a C source file, and add its blocks to the processor's list""" self.reset() self.filename = filename fileinput.close() - self.format = None - self.lineno = 0 - self.lines = [] + self.format = None + self.lineno = 0 + self.lines = [] for line in fileinput.input( filename ): - - # strip trailing newlines, important on Windows machines !! - if line[-1] == '\012': + # strip trailing newlines, important on Windows machines! + if line[-1] == '\012': line = line[0:-1] if self.format == None: self.process_normal_line( line ) - else: if self.format.end.match( line ): # that's a normal block end, add it to lines and # create a new block self.lines.append( line ) self.add_block_lines() - elif self.format.column.match( line ): # that's a normal column line, add it to 'lines' self.lines.append( line ) - else: # humm.. this is an unexpected block end, # create a new block, but don't process the line @@ -325,22 +319,18 @@ class SourceProcessor: # record the last lines self.add_block_lines() - - - def process_normal_line( self, line ): - """process a normal line and check if it's the start of a new block""" + def process_normal_line( self, line ): + """process a normal line and check whether it is the start of a new block""" for f in re_source_block_formats: - if f.start.match( line ): - self.add_block_lines() - self.format = f - self.lineno = fileinput.filelineno() + if f.start.match( line ): + self.add_block_lines() + self.format = f + self.lineno = fileinput.filelineno() self.lines.append( line ) - - - def add_block_lines( self ): - """add the current accumulated lines, and create a new block""" + def add_block_lines( self ): + """add the current accumulated lines and create a new block""" if self.lines != []: block = SourceBlock( self, self.filename, self.lineno, self.lines ) @@ -348,9 +338,8 @@ class SourceProcessor: self.format = None self.lines = [] - # debugging only, not used in normal operations - def dump( self ): + def dump( self ): """print all blocks in a processor""" for b in self.blocks: b.dump() diff --git a/Build/source/libs/freetype2/src/tools/docmaker/tohtml.py b/Build/source/libs/freetype2/src/tools/docmaker/tohtml.py index 04dfba3f46a..7e5c608660b 100644 --- a/Build/source/libs/freetype2/src/tools/docmaker/tohtml.py +++ b/Build/source/libs/freetype2/src/tools/docmaker/tohtml.py @@ -1,4 +1,4 @@ -# ToHTML (c) 2002, 2003, 2005, 2006, 2007 +# ToHTML (c) 2002, 2003, 2005, 2006, 2007, 2008 # David Turner <david@freetype.org> from sources import * @@ -7,8 +7,8 @@ from formatter import * import time + # The following defines the HTML header used by all generated pages. -# html_header_1 = """\ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> @@ -26,7 +26,9 @@ html_header_2= """ API Reference</title> p { text-align: justify; } h1 { text-align: center; } li { text-align: justify; } - td { padding: 0 0.5em 0 0.5em } + td { padding: 0 0.5em 0 0.5em; } + td.left { padding: 0 0.5em 0 0.5em; + text-align: left; } a:link { color: #0000EF; } a:visited { color: #51188E; } @@ -49,63 +51,57 @@ html_header_3=""" API Reference</h1></center> """ - # The HTML footer used by all generated pages. -# html_footer = """\ </body> </html>""" # The header and footer used for each section. -# section_title_header = "<center><h1>" section_title_footer = "</h1></center>" # The header and footer used for code segments. -# code_header = '<pre class="colored">' code_footer = '</pre>' # Paragraph header and footer. -# para_header = "<p>" para_footer = "</p>" # Block header and footer. -# block_header = '<table align=center width="75%"><tr><td>' block_footer_start = """\ </td></tr></table> <hr width="75%"> -<table align=center width="75%"><tr><td><font size=-2>[<a href=" +<table align=center width="75%"><tr><td><font size=-2>[<a href="\ """ block_footer_middle = """\ ">Index</a>]</font></td> <td width="100%"></td> -<td><font size=-2>[<a href=" +<td><font size=-2>[<a href="\ """ block_footer_end = """\ ">TOC</a>]</font></td></tr></table> """ # Description header/footer. -# description_header = '<table align=center width="87%"><tr><td>' description_footer = "</td></tr></table><br>" # Marker header/inter/footer combination. -# marker_header = '<table align=center width="87%" cellpadding=5><tr bgcolor="#EEEEFF"><td><em><b>' marker_inter = "</b></em></td></tr><tr><td>" marker_footer = "</td></tr></table>" +# Header location header/footer. +header_location_header = '<table align=center width="87%"><tr><td>' +header_location_footer = "</td></tr></table><br>" + # Source code extracts header/footer. -# source_header = '<table align=center width="87%"><tr bgcolor="#D6E8FF"><td><pre>\n' source_footer = "\n</pre></table><br>" # Chapter header/inter/footer. -# chapter_header = '<br><table align=center width="75%"><tr><td><h2>' chapter_inter = '</h2><ul class="empty"><li>' chapter_footer = '</li></ul></td></tr></table>' @@ -122,50 +118,45 @@ index_footer_end = """\ # source language keyword coloration/styling -# keyword_prefix = '<span class="keyword">' keyword_suffix = '</span>' section_synopsis_header = '<h2>Synopsis</h2>' section_synopsis_footer = '' + # Translate a single line of source to HTML. This will convert # a "<" into "<.", ">" into ">.", etc. -# -def html_quote( line ): - result = string.replace( line, "&", "&" ) +def html_quote( line ): + result = string.replace( line, "&", "&" ) result = string.replace( result, "<", "<" ) result = string.replace( result, ">", ">" ) return result # same as 'html_quote', but ignores left and right brackets -# -def html_quote0( line ): +def html_quote0( line ): return string.replace( line, "&", "&" ) -def dump_html_code( lines, prefix = "" ): +def dump_html_code( lines, prefix = "" ): # clean the last empty lines - # l = len( self.lines ) while l > 0 and string.strip( self.lines[l - 1] ) == "": l = l - 1 # The code footer should be directly appended to the last code # line to avoid an additional blank line. - # print prefix + code_header, - for line in self.lines[0 : l+1]: - print '\n' + prefix + html_quote(line), + for line in self.lines[0 : l + 1]: + print '\n' + prefix + html_quote( line ), print prefix + code_footer, -class HtmlFormatter(Formatter): - - def __init__( self, processor, project_title, file_prefix ): +class HtmlFormatter( Formatter ): + def __init__( self, processor, project_title, file_prefix ): Formatter.__init__( self, processor ) global html_header_1, html_header_2, html_header_3, html_footer @@ -175,6 +166,7 @@ class HtmlFormatter(Formatter): else: file_prefix = "" + self.headers = processor.headers self.project_title = project_title self.file_prefix = file_prefix self.html_header = html_header_1 + project_title + html_header_2 + \ @@ -189,11 +181,9 @@ class HtmlFormatter(Formatter): def make_section_url( self, section ): return self.file_prefix + section.name + ".html" - def make_block_url( self, block ): return self.make_section_url( block.section ) + "#" + block.name - def make_html_words( self, words ): """ convert a series of simple words into some HTML text """ line = "" @@ -204,16 +194,14 @@ class HtmlFormatter(Formatter): return line - def make_html_word( self, word ): """analyze a simple word to detect cross-references and styling""" # look for cross-references - # m = re_crossref.match( word ) if m: try: - name = m.group(1) - rest = m.group(2) + name = m.group( 1 ) + rest = m.group( 2 ) block = self.identifiers[name] url = self.make_block_url( block ) return '<a href="' + url + '">' + name + '</a>' + rest @@ -226,18 +214,17 @@ class HtmlFormatter(Formatter): # look for italics and bolds m = re_italic.match( word ) if m: - name = m.group(1) - rest = m.group(3) + name = m.group( 1 ) + rest = m.group( 3 ) return '<i>' + name + '</i>' + rest m = re_bold.match( word ) if m: - name = m.group(1) - rest = m.group(3) + name = m.group( 1 ) + rest = m.group( 3 ) return '<b>' + name + '</b>' + rest - return html_quote(word) - + return html_quote( word ) def make_html_para( self, words ): """ convert a paragraph's words into tagged HTML text, handle xrefs """ @@ -247,13 +234,12 @@ class HtmlFormatter(Formatter): for word in words[1:]: line = line + " " + self.make_html_word( word ) # convert `...' quotations into real left and right single quotes - line = re.sub( r"(^|\W)`(.*?)'(\W|$)", - r'\1‘\2’\3', + line = re.sub( r"(^|\W)`(.*?)'(\W|$)", \ + r'\1‘\2’\3', \ line ) return para_header + line + para_footer - def make_html_code( self, lines ): """ convert a code sequence to HTML """ line = code_header + '\n' @@ -262,7 +248,6 @@ class HtmlFormatter(Formatter): return line + code_footer - def make_html_items( self, items ): """ convert a field's content into some valid HTML """ lines = [] @@ -274,59 +259,54 @@ class HtmlFormatter(Formatter): return string.join( lines, '\n' ) - def print_html_items( self, items ): print self.make_html_items( items ) - - def print_html_field( self, field ): + def print_html_field( self, field ): if field.name: - print "<table><tr valign=top><td><p><b>"+field.name+"</b></p></td><td>" + print "<table><tr valign=top><td><b>" + field.name + "</b></td><td>" print self.make_html_items( field.items ) if field.name: print "</td></tr></table>" - - def html_source_quote( self, line, block_name = None ): + def html_source_quote( self, line, block_name = None ): result = "" while line: m = re_source_crossref.match( line ) if m: - name = m.group(2) - prefix = html_quote( m.group(1) ) - length = len( m.group(0) ) + name = m.group( 2 ) + prefix = html_quote( m.group( 1 ) ) + length = len( m.group( 0 ) ) if name == block_name: # this is the current block name, if any result = result + prefix + '<b>' + name + '</b>' - - elif re_source_keywords.match(name): + elif re_source_keywords.match( name ): # this is a C keyword result = result + prefix + keyword_prefix + name + keyword_suffix - - elif self.identifiers.has_key(name): + elif self.identifiers.has_key( name ): # this is a known identifier block = self.identifiers[name] result = result + prefix + '<a href="' + \ - self.make_block_url(block) + '">' + name + '</a>' + self.make_block_url( block ) + '">' + name + '</a>' else: - result = result + html_quote(line[:length]) + result = result + html_quote( line[:length] ) line = line[length:] else: - result = result + html_quote(line) + result = result + html_quote( line ) line = [] return result - - def print_html_field_list( self, fields ): + def print_html_field_list( self, fields ): + print "<p></p>" print "<table cellpadding=3 border=0>" for field in fields: - if len(field.name) > 22: - print "<tr valign=top><td colspan=0><b>"+field.name+"</b></td></tr>" + if len( field.name ) > 22: + print "<tr valign=top><td colspan=0><b>" + field.name + "</b></td></tr>" print "<tr valign=top><td></td><td>" else: print "<tr valign=top><td><b>" + field.name + "</b></td><td>" @@ -335,8 +315,7 @@ class HtmlFormatter(Formatter): print "</td></tr>" print "</table>" - - def print_html_markup( self, markup ): + def print_html_markup( self, markup ): table_fields = [] for field in markup.fields: if field.name: @@ -345,7 +324,6 @@ class HtmlFormatter(Formatter): # all of them as a single table # table_fields.append( field ) - else: if table_fields: self.print_html_field_list( table_fields ) @@ -359,7 +337,6 @@ class HtmlFormatter(Formatter): # # Formatting the index # - def index_enter( self ): print self.html_header self.index_items = {} @@ -370,16 +347,15 @@ class HtmlFormatter(Formatter): self.index_items[name] = url def index_exit( self ): - # block_index already contains the sorted list of index names count = len( self.block_index ) - rows = (count + self.columns - 1) / self.columns + rows = ( count + self.columns - 1 ) / self.columns print "<table align=center border=0 cellpadding=0 cellspacing=0>" - for r in range(rows): + for r in range( rows ): line = "<tr>" - for c in range(self.columns): - i = r + c*rows + for c in range( self.columns ): + i = r + c * rows if i < count: bname = self.block_index[r + c * rows] url = self.index_items[bname] @@ -391,14 +367,13 @@ class HtmlFormatter(Formatter): print "</table>" - print index_footer_start + \ + print index_footer_start + \ self.file_prefix + "toc.html" + \ index_footer_end self.index_items = {} def index_dump( self, index_filename = None ): - if index_filename == None: index_filename = self.file_prefix + "index.html" @@ -412,11 +387,11 @@ class HtmlFormatter(Formatter): print "<center><h1>Table of Contents</h1></center>" def toc_chapter_enter( self, chapter ): - print chapter_header + string.join(chapter.title) + chapter_inter + print chapter_header + string.join( chapter.title ) + chapter_inter print "<table cellpadding=5>" def toc_section_enter( self, section ): - print "<tr valign=top><td>" + print '<tr valign=top><td class="left">' print '<a href="' + self.make_section_url( section ) + '">' + \ section.title + '</a></td><td>' @@ -430,7 +405,9 @@ class HtmlFormatter(Formatter): print chapter_footer def toc_index( self, index_filename ): - print chapter_header + '<a href="' + index_filename + '">Global Index</a>' + chapter_inter + chapter_footer + print chapter_header + \ + '<a href="' + index_filename + '">Global Index</a>' + \ + chapter_inter + chapter_footer def toc_exit( self ): print self.html_footer @@ -459,7 +436,7 @@ class HtmlFormatter(Formatter): if len( b.name ) > maxwidth: maxwidth = len( b.name ) - width = 70 # XXX magic number + width = 70 # XXX magic number if maxwidth <> 0: # print section synopsis print section_synopsis_header @@ -501,12 +478,26 @@ class HtmlFormatter(Formatter): # dump the block C source lines now if block.code: + header = '' + for f in self.headers.keys(): + if block.source.filename.find( f ) >= 0: + header = self.headers[f] + ' (' + f + ')' + break; + +# if not header: +# sys.stderr.write( \ +# 'WARNING: No header macro for ' + block.source.filename + '.\n' ) + + if header: + print header_location_header + print 'Defined in ' + header + '.' + print header_location_footer + print source_header for l in block.code: print self.html_source_quote( l, block.name ) print source_footer - def markup_enter( self, markup, block ): if markup.tag == "description": print description_header @@ -523,15 +514,13 @@ class HtmlFormatter(Formatter): def block_exit( self, block ): print block_footer_start + self.file_prefix + "index.html" + \ - block_footer_middle + self.file_prefix + "toc.html" + \ + block_footer_middle + self.file_prefix + "toc.html" + \ block_footer_end - def section_exit( self, section ): print html_footer - - def section_dump_all( self ): + def section_dump_all( self ): for section in self.sections: self.section_dump( section, self.file_prefix + section.name + '.html' ) diff --git a/Build/source/libs/freetype2/src/tools/docmaker/utils.py b/Build/source/libs/freetype2/src/tools/docmaker/utils.py index e751c563186..1d96658c7d5 100644 --- a/Build/source/libs/freetype2/src/tools/docmaker/utils.py +++ b/Build/source/libs/freetype2/src/tools/docmaker/utils.py @@ -1,4 +1,4 @@ -# Utils (c) 2002, 2004, 2007 David Turner <david@freetype.org> +# Utils (c) 2002, 2004, 2007, 2008 David Turner <david@freetype.org> # import string, sys, os, glob @@ -11,7 +11,7 @@ output_dir = None # This function is used to sort the index. It is a simple lexicographical # sort, except that it places capital letters before lowercase ones. # -def index_sort( s1, s2 ): +def index_sort( s1, s2 ): if not s1: return -1 @@ -41,9 +41,10 @@ def index_sort( s1, s2 ): return 0 + # Sort input_list, placing the elements of order_list in front. # -def sort_order_list( input_list, order_list ): +def sort_order_list( input_list, order_list ): new_list = order_list[:] for id in input_list: if not id in order_list: @@ -51,12 +52,11 @@ def sort_order_list( input_list, order_list ): return new_list - # Open the standard output to a given project documentation file. Use # "output_dir" to determine the filename location if necessary and save the # old stdout in a tuple that is returned by this function. # -def open_output( filename ): +def open_output( filename ): global output_dir if output_dir and output_dir != "": @@ -71,25 +71,26 @@ def open_output( filename ): # Close the output that was returned by "close_output". # -def close_output( output ): +def close_output( output ): output[0].close() sys.stdout = output[1] # Check output directory. # -def check_output( ): +def check_output(): global output_dir if output_dir: if output_dir != "": if not os.path.isdir( output_dir ): - sys.stderr.write( "argument" + " '" + output_dir + "' " + + sys.stderr.write( "argument" + " '" + output_dir + "' " + \ "is not a valid directory" ) sys.exit( 2 ) else: output_dir = None -def file_exists( pathname ): + +def file_exists( pathname ): """checks that a given file exists""" result = 1 try: @@ -102,9 +103,8 @@ def file_exists( pathname ): return result -def make_file_list( args = None ): +def make_file_list( args = None ): """builds a list of input files from command-line arguments""" - file_list = [] # sys.stderr.write( repr( sys.argv[1 :] ) + '\n' ) diff --git a/Build/source/libs/freetype2/src/truetype/ttgload.c b/Build/source/libs/freetype2/src/truetype/ttgload.c index ae476a41711..f6d6f9fcd53 100644 --- a/Build/source/libs/freetype2/src/truetype/ttgload.c +++ b/Build/source/libs/freetype2/src/truetype/ttgload.c @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -267,7 +267,11 @@ if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit ) goto Invalid_Outline; - cont[0] = prev_cont = FT_NEXT_USHORT( p ); + prev_cont = FT_NEXT_USHORT( p ); + + if ( n_contours > 0 ) + cont[0] = prev_cont; + for ( cont++; cont < cont_limit; cont++ ) { cont[0] = FT_NEXT_USHORT( p ); @@ -639,6 +643,26 @@ /* save original point position in org */ if ( n_ins > 0 ) FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points ); + + /* Reset graphics state. */ + loader->exec->GS = ((TT_Size)loader->size)->GS; + + /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */ + /* completely refer to the (already) hinted subglyphs. */ + if ( is_composite ) + { + loader->exec->metrics.x_scale = 1 << 16; + loader->exec->metrics.y_scale = 1 << 16; + + FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points ); + } + else + { + loader->exec->metrics.x_scale = + ((TT_Size)loader->size)->metrics.x_scale; + loader->exec->metrics.y_scale = + ((TT_Size)loader->size)->metrics.y_scale; + } #endif /* round pp2 and pp4 */ @@ -702,7 +726,7 @@ FT_GlyphLoader gloader = loader->gloader; FT_Error error = TT_Err_Ok; FT_Outline* outline; - FT_UInt n_points; + FT_Int n_points; outline = &gloader->current.outline; @@ -729,7 +753,7 @@ /* Deltas apply to the unscaled data. */ FT_Vector* deltas; FT_Memory memory = loader->face->memory; - FT_UInt i; + FT_Int i; error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), @@ -1084,7 +1108,10 @@ #endif - if ( recurse_count > face->max_profile.maxComponentDepth ) + /* some fonts have an incorrect value of `maxComponentDepth', */ + /* thus we allow depth 1 to catch the majority of them */ + if ( recurse_count > 1 && + recurse_count > face->max_profile.maxComponentDepth ) { error = TT_Err_Invalid_Composite; goto Exit; @@ -1214,10 +1241,24 @@ offset = tt_face_get_location( face, glyph_index, (FT_UInt*)&loader->byte_len ); - if ( loader->byte_len == 0 ) + if ( loader->byte_len > 0 ) + { + error = face->access_glyph_frame( loader, glyph_index, + loader->glyf_offset + offset, + loader->byte_len ); + if ( error ) + goto Exit; + + opened_frame = 1; + + /* read first glyph header */ + error = face->read_glyph_header( loader ); + if ( error ) + goto Exit; + } + + if ( loader->byte_len == 0 || loader->n_contours == 0 ) { - /* as described by Frederic Loyer, these are spaces or */ - /* the unknown glyph. */ loader->bbox.xMin = 0; loader->bbox.xMax = 0; loader->bbox.yMin = 0; @@ -1260,19 +1301,6 @@ goto Exit; } - error = face->access_glyph_frame( loader, glyph_index, - loader->glyf_offset + offset, - loader->byte_len ); - if ( error ) - goto Exit; - - opened_frame = 1; - - /* read first glyph header */ - error = face->read_glyph_header( loader ); - if ( error ) - goto Exit; - TT_LOADER_SET_PP( loader ); /***********************************************************************/ @@ -1281,7 +1309,7 @@ /* if it is a simple glyph, load it */ - if ( loader->n_contours >= 0 ) + if ( loader->n_contours > 0 ) { error = face->read_simple_glyph( loader ); if ( error ) @@ -1390,20 +1418,15 @@ /*********************************************************************/ { - FT_UInt n, num_base_points; - FT_SubGlyph subglyph = 0; + FT_UInt n, num_base_points; + FT_SubGlyph subglyph = 0; - FT_UInt num_points = start_point; - FT_UInt num_subglyphs = gloader->current.num_subglyphs; - FT_UInt num_base_subgs = gloader->base.num_subglyphs; + FT_UInt num_points = start_point; + FT_UInt num_subglyphs = gloader->current.num_subglyphs; + FT_UInt num_base_subgs = gloader->base.num_subglyphs; - FT_Stream old_stream = loader->stream; + FT_Stream old_stream = loader->stream; - TT_GraphicsState saved_GS; - - - if ( loader->exec ) - saved_GS = loader->exec->GS; FT_GlyphLoader_Add( gloader ); @@ -1413,10 +1436,6 @@ FT_Vector pp[4]; - /* reinitialize graphics state */ - if ( loader->exec ) - loader->exec->GS = saved_GS; - /* Each time we call load_truetype_glyph in this loop, the */ /* value of `gloader.base.subglyphs' can change due to table */ /* reallocations. We thus need to recompute the subglyph */ diff --git a/Build/source/libs/freetype2/src/truetype/ttgxvar.c b/Build/source/libs/freetype2/src/truetype/ttgxvar.c index 0dc2c4f3e4a..0b3adbccf4b 100644 --- a/Build/source/libs/freetype2/src/truetype/ttgxvar.c +++ b/Build/source/libs/freetype2/src/truetype/ttgxvar.c @@ -4,7 +4,7 @@ /* */ /* TrueType GX Font Variation loader */ /* */ -/* Copyright 2004, 2005, 2006, 2007 by */ +/* Copyright 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -337,7 +337,8 @@ } - typedef struct GX_GVar_Head_ { + typedef struct GX_GVar_Head_ + { FT_Long version; FT_UShort axisCount; FT_UShort globalCoordCount; @@ -564,7 +565,8 @@ /*************************************************************************/ - typedef struct GX_FVar_Head_ { + typedef struct GX_FVar_Head_ + { FT_Long version; FT_UShort offsetToData; FT_UShort countSizePairs; @@ -576,7 +578,8 @@ } GX_FVar_Head; - typedef struct fvar_axis { + typedef struct fvar_axis_ + { FT_ULong axisTag; FT_ULong minValue; FT_ULong defaultValue; @@ -754,7 +757,7 @@ } ns = mmvar->namedstyle; - for ( i = 0; i < fvar_head.instanceCount; ++i ) + for ( i = 0; i < fvar_head.instanceCount; ++i, ++ns ) { if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) ) goto Exit; diff --git a/Build/source/libs/freetype2/src/truetype/ttinterp.c b/Build/source/libs/freetype2/src/truetype/ttinterp.c index 85c8529ac73..f9c36560ed7 100644 --- a/Build/source/libs/freetype2/src/truetype/ttinterp.c +++ b/Build/source/libs/freetype2/src/truetype/ttinterp.c @@ -4,7 +4,7 @@ /* */ /* TrueType bytecode interpreter (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -4821,7 +4821,28 @@ if ( CUR.opcode & 1 ) D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); else - D = CUR_Func_dualproj( CUR.zp0.org + L, CUR.zp1.org + K ); + { + FT_Vector* vec1 = CUR.zp0.orus + L; + FT_Vector* vec2 = CUR.zp1.orus + K; + + + if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) + { + /* this should be faster */ + D = CUR_Func_dualproj( vec1, vec2 ); + D = TT_MULFIX( D, CUR.metrics.x_scale ); + } + else + { + FT_Vector vec; + + + vec.x = TT_MULFIX( vec1->x - vec2->x, CUR.metrics.x_scale ); + vec.y = TT_MULFIX( vec1->y - vec2->y, CUR.metrics.y_scale ); + + D = CUR_fast_dualproj( &vec ); + } + } } args[0] = D; @@ -5428,7 +5449,7 @@ /* XXX: this is probably wrong... at least it prevents memory */ /* corruption when zp2 is the twilight zone */ - if ( last_point > CUR.zp2.n_points ) + if ( BOUNDS( last_point, CUR.zp2.n_points ) ) { if ( CUR.zp2.n_points > 0 ) last_point = (FT_UShort)(CUR.zp2.n_points - 1); @@ -6211,9 +6232,13 @@ org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base ); cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base ); - new_dist = ( old_range != 0 ) - ? TT_MULDIV( org_dist, cur_range, old_range ) - : cur_dist; + + if ( org_dist ) + new_dist = ( old_range != 0 ) + ? TT_MULDIV( org_dist, cur_range, old_range ) + : cur_dist; + else + new_dist = 0; CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist ); } @@ -6257,7 +6282,7 @@ /* Local variables for Ins_IUP: */ - typedef struct + typedef struct IUP_WorkerRec_ { FT_Vector* orgs; /* original and current coordinate */ FT_Vector* curs; /* arrays */ @@ -6434,6 +6459,9 @@ end_point = CUR.pts.contours[contour] - CUR.pts.first_point; first_point = point; + if ( CUR.pts.n_points <= end_point ) + end_point = CUR.pts.n_points; + while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 ) point++; diff --git a/Build/source/libs/freetype2/src/truetype/ttobjs.c b/Build/source/libs/freetype2/src/truetype/ttobjs.c index 0294a1b7e66..801559fe499 100644 --- a/Build/source/libs/freetype2/src/truetype/ttobjs.c +++ b/Build/source/libs/freetype2/src/truetype/ttobjs.c @@ -230,17 +230,22 @@ if ( !face->root.internal->incremental_interface ) error = tt_face_load_loca( face, stream ); if ( !error ) - error = tt_face_load_cvt( face, stream ) || - tt_face_load_fpgm( face, stream ) || - tt_face_load_prep( face, stream ); + error = tt_face_load_cvt( face, stream ); + if ( !error ) + error = tt_face_load_fpgm( face, stream ); + if ( !error ) + error = tt_face_load_prep( face, stream ); #else if ( !error ) - error = tt_face_load_loca( face, stream ) || - tt_face_load_cvt( face, stream ) || - tt_face_load_fpgm( face, stream ) || - tt_face_load_prep( face, stream ); + error = tt_face_load_loca( face, stream ); + if ( !error ) + error = tt_face_load_cvt( face, stream ); + if ( !error ) + error = tt_face_load_fpgm( face, stream ); + if ( !error ) + error = tt_face_load_prep( face, stream ); #endif @@ -694,8 +699,9 @@ error = tt_size_run_prep( size ); if ( !error ) - size->cvt_ready = 1; + size->cvt_ready = 1; } + Exit: return error; } diff --git a/Build/source/libs/freetype2/src/type1/t1load.c b/Build/source/libs/freetype2/src/type1/t1load.c index 55177eed438..9d7c748b390 100644 --- a/Build/source/libs/freetype2/src/type1/t1load.c +++ b/Build/source/libs/freetype2/src/type1/t1load.c @@ -4,7 +4,7 @@ /* */ /* Type 1 font loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -674,7 +674,7 @@ for ( n = 0; n < num_designs; n++ ) { - T1_TokenRec axis_tokens[T1_MAX_MM_DESIGNS]; + T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; T1_Token token; FT_Int axis, n_axis; @@ -687,6 +687,15 @@ if ( n == 0 ) { + if ( n_axis <= 0 || n_axis > T1_MAX_MM_AXIS ) + { + FT_ERROR(( "parse_blend_design_positions:" )); + FT_ERROR(( " invalid number of axes: %d\n", + n_axis )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + num_axis = n_axis; error = t1_allocate_blend( face, num_designs, num_axis ); if ( error ) @@ -1397,7 +1406,10 @@ FT_Byte* temp; - if ( size <= face->type1.private_dict.lenIV ) + /* some fonts define empty subr records -- this is not totally */ + /* compliant to the specification (which says they should at */ + /* least contain a `return'), but we support them anyway */ + if ( size < face->type1.private_dict.lenIV ) { error = T1_Err_Invalid_File_Format; goto Fail; diff --git a/Build/source/libs/freetype2/src/type1/t1objs.c b/Build/source/libs/freetype2/src/type1/t1objs.c index 3d08336c600..40b258fce94 100644 --- a/Build/source/libs/freetype2/src/type1/t1objs.c +++ b/Build/source/libs/freetype2/src/type1/t1objs.c @@ -4,7 +4,7 @@ /* */ /* Type 1 objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -298,7 +298,6 @@ FT_UNUSED( num_params ); FT_UNUSED( params ); - FT_UNUSED( face_index ); FT_UNUSED( stream ); @@ -361,7 +360,10 @@ root->family_name = info->family_name; /* assume "Regular" style if we don't know better */ root->style_name = (char *)"Regular"; - if ( root->family_name ) + + if ( info->weight ) + root->style_name = info->weight; + else if ( root->family_name ) { char* full = info->full_name; char* family = root->family_name; diff --git a/Build/source/libs/freetype2/src/type1/t1parse.c b/Build/source/libs/freetype2/src/type1/t1parse.c index 1b252c74833..36f5c82c86f 100644 --- a/Build/source/libs/freetype2/src/type1/t1parse.c +++ b/Build/source/libs/freetype2/src/type1/t1parse.c @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -65,14 +65,16 @@ /*************************************************************************/ + /* see Adobe Technical Note 5040.Download_Fonts.pdf */ + static FT_Error read_pfb_tag( FT_Stream stream, FT_UShort *atag, - FT_Long *asize ) + FT_ULong *asize ) { FT_Error error; FT_UShort tag; - FT_Long size; + FT_ULong size; *atag = 0; @@ -82,7 +84,7 @@ { if ( tag == 0x8001U || tag == 0x8002U ) { - if ( !FT_READ_LONG_LE( size ) ) + if ( !FT_READ_ULONG_LE( size ) ) *asize = size; } @@ -100,22 +102,25 @@ { FT_Error error; FT_UShort tag; - FT_Long size; + FT_ULong dummy; if ( FT_STREAM_SEEK( 0 ) ) goto Exit; - error = read_pfb_tag( stream, &tag, &size ); + error = read_pfb_tag( stream, &tag, &dummy ); if ( error ) goto Exit; + /* We assume that the first segment in a PFB is always encoded as */ + /* text. This might be wrong (and the specification doesn't insist */ + /* on that), but we have never seen a counterexample. */ if ( tag != 0x8001U && FT_STREAM_SEEK( 0 ) ) goto Exit; if ( !FT_FRAME_ENTER( header_length ) ) { - error = 0; + error = T1_Err_Ok; if ( ft_memcmp( stream->cursor, header_string, header_length ) != 0 ) error = T1_Err_Unknown_File_Format; @@ -136,7 +141,7 @@ { FT_Error error; FT_UShort tag; - FT_Long size; + FT_ULong size; psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); @@ -170,19 +175,19 @@ /* Here a short summary of what is going on: */ /* */ /* When creating a new Type 1 parser, we try to locate and load */ - /* the base dictionary if this is possible (i.e. for PFB */ + /* the base dictionary if this is possible (i.e., for PFB */ /* files). Otherwise, we load the whole font into memory. */ /* */ /* When `loading' the base dictionary, we only setup pointers */ /* in the case of a memory-based stream. Otherwise, we */ /* allocate and load the base dictionary in it. */ /* */ - /* parser->in_pfb is set if we are in a binary (".pfb") font. */ + /* parser->in_pfb is set if we are in a binary (`.pfb') font. */ /* parser->in_memory is set if we have a memory stream. */ /* */ - /* try to compute the size of the base dictionary; */ - /* look for a Postscript binary file tag, i.e 0x8001 */ + /* try to compute the size of the base dictionary; */ + /* look for a Postscript binary file tag, i.e., 0x8001 */ if ( FT_STREAM_SEEK( 0L ) ) goto Exit; @@ -217,7 +222,7 @@ } else { - /* read segment in memory - this is clumsy, but so does the format */ + /* read segment in memory -- this is clumsy, but so does the format */ if ( FT_ALLOC( parser->base_dict, size ) || FT_STREAM_READ( parser->base_dict, size ) ) goto Exit; @@ -260,7 +265,7 @@ FT_Stream stream = parser->stream; FT_Memory memory = parser->root.memory; FT_Error error = T1_Err_Ok; - FT_Long size; + FT_ULong size; if ( parser->in_pfb ) @@ -299,7 +304,7 @@ goto Fail; } - if ( FT_STREAM_SEEK( start_pos ) || + if ( FT_STREAM_SEEK( start_pos ) || FT_ALLOC( parser->private_dict, parser->private_len ) ) goto Fail; @@ -409,7 +414,7 @@ goto Exit; } - size = (FT_Long)( parser->base_len - ( cur - parser->base_dict ) ); + size = parser->base_len - ( cur - parser->base_dict ); if ( parser->in_memory ) { diff --git a/Build/source/libs/freetype2/src/type1/t1parse.h b/Build/source/libs/freetype2/src/type1/t1parse.h index 6fa4ca624a2..fb1c8a88308 100644 --- a/Build/source/libs/freetype2/src/type1/t1parse.h +++ b/Build/source/libs/freetype2/src/type1/t1parse.h @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -64,10 +64,10 @@ FT_BEGIN_HEADER FT_Stream stream; FT_Byte* base_dict; - FT_Long base_len; + FT_ULong base_len; FT_Byte* private_dict; - FT_Long private_len; + FT_ULong private_len; FT_Bool in_pfb; FT_Bool in_memory; diff --git a/Build/source/libs/freetype2/src/type42/t42parse.c b/Build/source/libs/freetype2/src/type42/t42parse.c index 7148379644f..7d8c267ced3 100644 --- a/Build/source/libs/freetype2/src/type42/t42parse.c +++ b/Build/source/libs/freetype2/src/type42/t42parse.c @@ -4,7 +4,7 @@ /* */ /* Type 42 font parser (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by Roberto Alameda. */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008 by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -471,7 +471,7 @@ } - typedef enum + typedef enum T42_Load_Status_ { BEFORE_START, BEFORE_TABLE_DIR, diff --git a/Build/source/libs/freetype2/src/winfonts/winfnt.c b/Build/source/libs/freetype2/src/winfonts/winfnt.c index 4aa974410f3..833fb888a2a 100644 --- a/Build/source/libs/freetype2/src/winfonts/winfnt.c +++ b/Build/source/libs/freetype2/src/winfonts/winfnt.c @@ -4,7 +4,7 @@ /* */ /* FreeType font driver for Windows FNT/FON files */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* Copyright 2003 Huw D M Davies for Codeweavers */ /* Copyright 2007 Dmitry Timoshkov for Codeweavers */ @@ -363,6 +363,8 @@ error = FNT_Err_Bad_Argument; goto Exit; } + else if ( face_index < 0 ) + goto Exit; if ( FT_NEW( face->font ) ) goto Exit; @@ -652,7 +654,9 @@ (FT_CMap_InitFunc) fnt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)fnt_cmap_char_index, - (FT_CMap_CharNextFunc) fnt_cmap_char_next + (FT_CMap_CharNextFunc) fnt_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL }; static FT_CMap_Class const fnt_cmap_class = &fnt_cmap_class_rec; @@ -690,18 +694,14 @@ /* try to load font from a DLL */ error = fnt_face_get_dll_font( face, face_index ); + if ( !error && face_index < 0 ) + goto Exit; + if ( error == FNT_Err_Unknown_File_Format ) { /* this didn't work; try to load a single FNT font */ FNT_Font font; - - if ( face_index > 0 ) - { - error = FNT_Err_Bad_Argument; - goto Exit; - } - if ( FT_NEW( face->font ) ) goto Exit; @@ -712,6 +712,14 @@ font->fnt_size = stream->size; error = fnt_font_load( font, stream ); + + if ( !error ) + { + if ( face_index > 0 ) + error = FNT_Err_Bad_Argument; + else if ( face_index < 0 ) + goto Exit; + } } if ( error ) |