From 76b72c03e83773add873dbc20b0de657cff52c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Thu, 25 Jan 2007 19:12:34 +0000 Subject: [PATCH] updated freetype to 2.3.0 git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19960 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../libs/freetype2/freetype/config/ftheader.h | 69 +- .../libs/freetype2/freetype/config/ftoption.h | 42 +- .../libs/freetype2/freetype/config/ftstdlib.h | 10 +- headers/libs/freetype2/freetype/freetype.h | 16 +- headers/libs/freetype2/freetype/ftbitmap.h | 2 +- headers/libs/freetype2/freetype/ftchapters.h | 3 + headers/libs/freetype2/freetype/ftgasp.h | 113 ++ headers/libs/freetype2/freetype/ftincrem.h | 10 +- headers/libs/freetype2/freetype/ftlcdfil.h | 166 ++ headers/libs/freetype2/freetype/ftotval.h | 8 +- headers/libs/freetype2/freetype/ftoutln.h | 8 +- headers/libs/freetype2/freetype/ftwinfnt.h | 8 +- headers/libs/freetype2/freetype/ftxf86.h | 42 +- .../libs/freetype2/freetype/internal/ftcalc.h | 28 +- .../freetype2/freetype/internal/ftgloadr.h | 1 + .../libs/freetype2/freetype/internal/ftobjs.h | 25 +- .../freetype2/freetype/internal/ftstream.h | 2 +- .../freetype2/freetype/internal/ftvalid.h | 4 +- .../libs/freetype2/freetype/internal/psaux.h | 174 +- .../freetype/internal/services/svkern.h | 4 +- .../freetype/internal/services/svotval.h | 14 +- .../freetype/internal/services/svpscmap.h | 23 +- .../freetype/internal/services/svttcmap.h | 8 +- .../freetype/internal/services/svxf86nm.h | 2 +- .../libs/freetype2/freetype/internal/sfnt.h | 6 +- .../freetype2/freetype/internal/t1types.h | 13 +- .../freetype2/freetype/internal/tttypes.h | 29 +- headers/libs/freetype2/freetype/t1tables.h | 11 +- headers/libs/freetype2/freetype/tttables.h | 4 +- src/libs/freetype2/autofit/afangles.c | 377 ++--- src/libs/freetype2/autofit/afcjk.c | 4 +- src/libs/freetype2/autofit/afhints.c | 236 ++- src/libs/freetype2/autofit/afhints.h | 23 + src/libs/freetype2/autofit/aflatin.c | 218 ++- src/libs/freetype2/autofit/afloader.c | 13 +- src/libs/freetype2/autofit/afmodule.c | 10 +- src/libs/freetype2/autofit/aftypes.h | 15 +- src/libs/freetype2/base/Jamfile | 2 +- src/libs/freetype2/base/ftapi.c | 18 +- src/libs/freetype2/base/ftbase.c | 14 +- src/libs/freetype2/base/ftbitmap.c | 15 +- src/libs/freetype2/base/ftcalc.c | 208 ++- src/libs/freetype2/base/ftdbgmem.c | 4 +- src/libs/freetype2/base/ftgasp.c | 61 + src/libs/freetype2/base/ftgloadr.c | 39 +- src/libs/freetype2/base/ftgxval.c | 6 +- src/libs/freetype2/base/ftlcdfil.c | 351 ++++ src/libs/freetype2/base/ftmac.c | 518 +----- src/libs/freetype2/base/ftmm.c | 2 +- src/libs/freetype2/base/ftobjs.c | 138 +- src/libs/freetype2/base/ftotval.c | 4 +- src/libs/freetype2/base/ftoutln.c | 147 +- src/libs/freetype2/base/ftrfork.c | 2 +- src/libs/freetype2/base/ftsynth.c | 7 +- src/libs/freetype2/base/ftutil.c | 8 +- src/libs/freetype2/base/rules.mk | 8 +- src/libs/freetype2/bdf/README | 10 +- src/libs/freetype2/bdf/bdf.c | 2 +- src/libs/freetype2/bdf/bdf.h | 2 +- src/libs/freetype2/bdf/bdfdrivr.c | 15 +- src/libs/freetype2/bdf/bdflib.c | 15 +- src/libs/freetype2/bdf/module.mk | 2 +- src/libs/freetype2/cache/ftccmap.c | 8 +- src/libs/freetype2/cff/cffcmap.c | 19 +- src/libs/freetype2/cff/cffcmap.h | 4 +- src/libs/freetype2/cff/cffdrivr.c | 52 +- src/libs/freetype2/cff/cffgload.c | 53 +- src/libs/freetype2/cff/cffload.c | 1494 +++++------------ src/libs/freetype2/cff/cffload.h | 7 +- src/libs/freetype2/cff/cffobjs.c | 8 +- src/libs/freetype2/cff/cffobjs.h | 4 +- src/libs/freetype2/cff/cfftypes.h | 18 +- src/libs/freetype2/cid/cidgload.c | 219 +-- src/libs/freetype2/cid/cidload.c | 8 +- src/libs/freetype2/cid/cidparse.c | 32 +- src/libs/freetype2/cid/cidtoken.h | 94 +- src/libs/freetype2/gzip/ftgzip.c | 68 + src/libs/freetype2/gzip/inftrees.c | 3 + src/libs/freetype2/otvalid/otvmod.c | 50 +- src/libs/freetype2/pcf/README | 10 +- src/libs/freetype2/pcf/module.mk | 2 +- src/libs/freetype2/pcf/pcfdrivr.c | 23 +- src/libs/freetype2/pcf/pcfread.c | 202 ++- src/libs/freetype2/pcf/pcfutil.c | 10 +- src/libs/freetype2/pfr/Jamfile | 2 +- src/libs/freetype2/pfr/pfrcmap.c | 8 +- src/libs/freetype2/pfr/pfrcmap.h | 2 +- src/libs/freetype2/pfr/pfrload.h | 8 +- src/libs/freetype2/pfr/pfrobjs.c | 50 +- src/libs/freetype2/psaux/psconv.c | 83 +- src/libs/freetype2/psaux/psconv.h | 36 - src/libs/freetype2/psaux/psobjs.c | 309 +++- src/libs/freetype2/psaux/t1cmap.c | 3 +- src/libs/freetype2/psaux/t1decode.c | 409 ++++- src/libs/freetype2/pshinter/pshalgo.c | 522 ++++-- src/libs/freetype2/psnames/psmodule.c | 14 +- src/libs/freetype2/raster/ftraster.c | 160 +- src/libs/freetype2/sfnt/rules.mk | 2 +- src/libs/freetype2/sfnt/sfdriver.c | 30 +- src/libs/freetype2/sfnt/sfobjs.c | 66 +- src/libs/freetype2/sfnt/ttcmap.c | 36 +- src/libs/freetype2/sfnt/ttkern.c | 204 +-- src/libs/freetype2/sfnt/ttkern.h | 8 +- src/libs/freetype2/sfnt/ttload.c | 10 +- src/libs/freetype2/sfnt/ttmtx.c | 102 +- src/libs/freetype2/sfnt/ttsbit.c | 18 +- src/libs/freetype2/sfnt/ttsbit.h | 6 +- src/libs/freetype2/sfnt/ttsbit0.c | 9 +- src/libs/freetype2/sfnt/ttsbit0.h | 7 - src/libs/freetype2/smooth/ftgrays.c | 844 ++++------ src/libs/freetype2/smooth/ftsmooth.c | 151 +- src/libs/freetype2/truetype/truetype.c | 4 +- src/libs/freetype2/truetype/ttdriver.c | 20 +- src/libs/freetype2/truetype/ttgload.c | 227 ++- src/libs/freetype2/truetype/ttgload.h | 4 +- src/libs/freetype2/truetype/ttgxvar.h | 4 +- src/libs/freetype2/truetype/ttinterp.c | 340 ++-- src/libs/freetype2/truetype/ttobjs.c | 316 ++-- src/libs/freetype2/truetype/ttobjs.h | 20 +- src/libs/freetype2/truetype/ttpload.c | 273 +-- src/libs/freetype2/type1/t1afm.c | 23 +- src/libs/freetype2/type1/t1gload.c | 49 +- src/libs/freetype2/type1/t1load.c | 279 +-- src/libs/freetype2/type1/t1load.h | 11 +- src/libs/freetype2/type1/t1objs.c | 10 + src/libs/freetype2/type1/t1objs.h | 2 +- src/libs/freetype2/type1/t1parse.c | 8 +- src/libs/freetype2/type1/t1tokens.h | 114 +- src/libs/freetype2/type42/t42drivr.c | 2 +- src/libs/freetype2/type42/t42objs.c | 3 + src/libs/freetype2/type42/t42objs.h | 4 +- src/libs/freetype2/type42/t42parse.c | 40 +- src/libs/freetype2/winfonts/winfnt.c | 3 +- 133 files changed, 5954 insertions(+), 4628 deletions(-) create mode 100644 headers/libs/freetype2/freetype/ftgasp.h create mode 100644 headers/libs/freetype2/freetype/ftlcdfil.h create mode 100644 src/libs/freetype2/base/ftgasp.c create mode 100644 src/libs/freetype2/base/ftlcdfil.c delete mode 100644 src/libs/freetype2/sfnt/ttsbit0.h diff --git a/headers/libs/freetype2/freetype/config/ftheader.h b/headers/libs/freetype2/freetype/config/ftheader.h index 7d663d9943..b957d05bed 100644 --- a/headers/libs/freetype2/freetype/config/ftheader.h +++ b/headers/libs/freetype2/freetype/config/ftheader.h @@ -4,7 +4,7 @@ /* */ /* Build macros of the FreeType 2 library. */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -88,7 +88,7 @@ /* limited to the infamous 8.3 naming rule required by DOS (and */ /* `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h'). */ /* */ - /* The second reason is that is allows for more flexibility in the */ + /* The second reason is that it allows for more flexibility in the */ /* way FreeType 2 is installed on a given system. */ /* */ /*************************************************************************/ @@ -222,7 +222,7 @@ * FT_IMAGE_H * * @description: - * A macro used in #include statements to name the file containing types + * A macro used in #include statements to name the file containing type * definitions related to glyph images (i.e., bitmaps, outlines, * scan-converter parameters). * @@ -282,7 +282,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * API used to manage multiple @FT_Size objects per face. + * API which manages multiple @FT_Size objects per face. * */ #define FT_SIZES_H @@ -334,10 +334,9 @@ * * @description: * A macro used in #include statements to name the file containing the - * enumeration values used to identify name strings, languages, - * encodings, etc. This file really contains a _large_ set of constant - * macro definitions, taken from the TrueType and OpenType - * specifications. + * enumeration values which identify name strings, languages, encodings, + * etc. This file really contains a _large_ set of constant macro + * definitions, taken from the TrueType and OpenType specifications. * */ #define FT_TRUETYPE_IDS_H @@ -363,7 +362,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * definitions of TrueType four-byte `tags' used to identify blocks in + * definitions of TrueType four-byte `tags' which identify blocks in * SFNT-based font formats (i.e., TrueType and OpenType). * */ @@ -377,7 +376,8 @@ * * @description: * A macro used in #include statements to name the file containing the - * definitions of an API to access BDF-specific strings from a face. + * definitions of an API which accesses BDF-specific strings from a + * face. * */ #define FT_BDF_H @@ -390,7 +390,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * definitions of an API to support for gzip-compressed files. + * definitions of an API which supports gzip-compressed files. * */ #define FT_GZIP_H @@ -403,7 +403,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * definitions of an API to support for LZW-compressed files. + * definitions of an API which supports LZW-compressed files. * */ #define FT_LZW_H @@ -416,7 +416,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * definitions of an API to support Windows FNT files. + * definitions of an API which supports Windows FNT files. * */ #define FT_WINFONTS_H @@ -484,7 +484,7 @@ * `glyph image' API of the FreeType 2 cache sub-system. * * It is used to define a cache for @FT_Glyph elements. You can also - * see the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need to + * use the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need to * store small glyph bitmaps, as it will use less memory. * * This macro is deprecated. Simply include @FT_CACHE_H to have all @@ -568,7 +568,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * optional FreeType 2 API used to access embedded `name' strings in + * optional FreeType 2 API which accesses embedded `name' strings in * SFNT-based font formats (i.e., TrueType and OpenType). * */ @@ -582,7 +582,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * optional FreeType 2 API used to validate OpenType tables (BASE, GDEF, + * optional FreeType 2 API which validates OpenType tables (BASE, GDEF, * GPOS, GSUB, JSTF). * */ @@ -596,7 +596,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * optional FreeType 2 API used to validate TrueTypeGX/AAT tables (feat, + * optional FreeType 2 API which validates TrueTypeGX/AAT tables (feat, * mort, morx, bsln, just, kern, opbd, trak, prop). * */ @@ -610,7 +610,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API used to access PFR-specific data. + * FreeType 2 API which accesses PFR-specific data. * */ #define FT_PFR_H @@ -623,7 +623,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API used to stroke outline path. + * FreeType 2 API which provides functions to stroke outline paths. */ #define FT_STROKER_H @@ -635,7 +635,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API used to perform artificial obliquing and emboldening. + * FreeType 2 API which performs artificial obliquing and emboldening. */ #define FT_SYNTHESIS_H @@ -647,7 +647,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API used to provide functions specific to the XFree86 and + * FreeType 2 API which provides functions specific to the XFree86 and * X.Org X11 servers. */ #define FT_XFREE86_H @@ -660,11 +660,36 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API used to perform trigonometric computations (e.g., + * FreeType 2 API which performs trigonometric computations (e.g., * cosines and arc tangents). */ #define FT_TRIGONOMETRY_H + + /************************************************************************* + * + * @macro: + * FT_LCD_FILTER_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType 2 API which performs color filtering for subpixel rendering. + */ +#define FT_LCD_FILTER_H + + + /************************************************************************* + * + * @macro: + * FT_GASP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType 2 API which returns entries from the TrueType GASP table. + */ +#define FT_GASP_H + + /* */ #define FT_ERROR_DEFINITIONS_H diff --git a/headers/libs/freetype2/freetype/config/ftoption.h b/headers/libs/freetype2/freetype/config/ftoption.h index 8a2a79f956..6b7c6c94db 100644 --- a/headers/libs/freetype2/freetype/config/ftoption.h +++ b/headers/libs/freetype2/freetype/config/ftoption.h @@ -4,7 +4,7 @@ /* */ /* User-selectable configuration macros (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -75,6 +75,26 @@ FT_BEGIN_HEADER /*************************************************************************/ + /*************************************************************************/ + /* */ + /* Uncomment the line below if you want to activate sub-pixel rendering */ + /* (a.k.a. LCD rendering, or ClearType) in this build of the library. */ + /* */ + /* Note that this feature is covered by several Microsoft patents */ + /* and should not be activated in any default build of the library. */ + /* */ + /* This macro has no impact on the FreeType API, only on its */ + /* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */ + /* FT_Render_Glyph still generates a bitmap that is 3 times larger than */ + /* the original size; the difference will be that each triplet of */ + /* subpixels has R=G=B. */ + /* */ + /* This is done to allow FreeType clients to run unmodified, forcing */ + /* them to display normal gray-level anti-aliased glyphs. */ + /* */ +#define FT_CONFIG_OPTION_SUBPIXEL_RENDERING + + /*************************************************************************/ /* */ /* Many compilers provide a non-ANSI 64-bit data type that can be used */ @@ -448,7 +468,7 @@ FT_BEGIN_HEADER /* FT_PARAM_TAG_UNPATENTED_HINTING; or when the debug hook */ /* FT_DEBUG_HOOK_UNPATENTED_HINTING is globally activated. */ /* */ -//#define TT_CONFIG_OPTION_UNPATENTED_HINTING +#define TT_CONFIG_OPTION_UNPATENTED_HINTING /*************************************************************************/ @@ -572,13 +592,7 @@ FT_BEGIN_HEADER #define AF_CONFIG_OPTION_CJK - /* */ - - /* - * This temporary macro is used to control various optimizations for - * reducing the heap footprint of memory-mapped TrueType files. - */ -#define FT_OPTIMIZE_MEMORY + /* */ /* @@ -594,6 +608,16 @@ FT_BEGIN_HEADER #define FT_CONFIG_OPTION_OLD_INTERNALS + /* + * This variable is defined if either unpatented or native TrueType + * hinting is requested by the definitions above. + */ +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#define TT_USE_BYTECODE_INTERPRETER +#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING +#define TT_USE_BYTECODE_INTERPRETER +#endif + FT_END_HEADER diff --git a/headers/libs/freetype2/freetype/config/ftstdlib.h b/headers/libs/freetype2/freetype/config/ftstdlib.h index aaba8b3b1b..970a50f7bc 100644 --- a/headers/libs/freetype2/freetype/config/ftstdlib.h +++ b/headers/libs/freetype2/freetype/config/ftstdlib.h @@ -168,12 +168,12 @@ #include -#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */ - /* jmp_buf is defined as a macro */ - /* on certain platforms */ +#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */ + /* jmp_buf is defined as a macro */ + /* on certain platforms */ -#define ft_longjmp longjmp /* likewise */ -#define ft_setjmp setjmp /* same thing here */ +#define ft_longjmp longjmp +#define ft_setjmp( b ) setjmp( *(jmp_buf*) &(b) ) /* same thing here */ /* the following is only used for debugging purposes, i.e., if */ diff --git a/headers/libs/freetype2/freetype/freetype.h b/headers/libs/freetype2/freetype/freetype.h index 8f5755d63c..59543856f1 100644 --- a/headers/libs/freetype2/freetype/freetype.h +++ b/headers/libs/freetype2/freetype/freetype.h @@ -4,7 +4,7 @@ /* */ /* FreeType high-level API and common types (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -913,7 +913,9 @@ FT_BEGIN_HEADER FT_Generic generic; - /*# the following are only relevant to scalable outlines */ + /*# The following member variables (down to `underline_thickness') */ + /*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size */ + /*# for bitmap fonts. */ FT_BBox bbox; FT_UShort units_per_EM; @@ -1270,6 +1272,8 @@ FT_BEGIN_HEADER /* glyphs. As this would be a definite performance hit, it is up to */ /* client applications to perform such computations. */ /* */ + /* The FT_Size_Metrics structure is valid for bitmap fonts also. */ + /* */ typedef struct FT_Size_Metrics_ { FT_UShort x_ppem; /* horizontal pixels per EM */ @@ -1795,6 +1799,9 @@ FT_BEGIN_HEADER /* */ /* FreeType error code. 0 means success. */ /* */ + /* */ + /* You must not deallocate the memory before calling @FT_Done_Face. */ + /* */ FT_EXPORT( FT_Error ) FT_New_Memory_Face( FT_Library library, const FT_Byte* file_base, @@ -3306,8 +3313,8 @@ FT_BEGIN_HEADER * macros. */ #define FREETYPE_MAJOR 2 -#define FREETYPE_MINOR 2 -#define FREETYPE_PATCH 1 +#define FREETYPE_MINOR 3 +#define FREETYPE_PATCH 0 /*************************************************************************/ @@ -3345,7 +3352,6 @@ FT_BEGIN_HEADER FT_Int *aminor, FT_Int *apatch ); - /* */ diff --git a/headers/libs/freetype2/freetype/ftbitmap.h b/headers/libs/freetype2/freetype/ftbitmap.h index 39b22c0a2f..337d888eaf 100644 --- a/headers/libs/freetype2/freetype/ftbitmap.h +++ b/headers/libs/freetype2/freetype/ftbitmap.h @@ -3,7 +3,7 @@ /* ftbitmap.h */ /* */ /* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */ -/* bitmaps into 8bpp format (specification). */ +/* bitmaps into 8bpp format (specification). */ /* */ /* Copyright 2004, 2005, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ diff --git a/headers/libs/freetype2/freetype/ftchapters.h b/headers/libs/freetype2/freetype/ftchapters.h index 477daa5b96..bd812c8e65 100644 --- a/headers/libs/freetype2/freetype/ftchapters.h +++ b/headers/libs/freetype2/freetype/ftchapters.h @@ -56,6 +56,8 @@ /* bdf_fonts */ /* pfr_fonts */ /* winfnt_fonts */ +/* font_formats */ +/* gasp_table */ /* */ /***************************************************************************/ @@ -93,5 +95,6 @@ /* module_management */ /* gzip */ /* lzw */ +/* lcd_filtering */ /* */ /***************************************************************************/ diff --git a/headers/libs/freetype2/freetype/ftgasp.h b/headers/libs/freetype2/freetype/ftgasp.h new file mode 100644 index 0000000000..97cd330145 --- /dev/null +++ b/headers/libs/freetype2/freetype/ftgasp.h @@ -0,0 +1,113 @@ +/***************************************************************************/ +/* */ +/* ftgasp.h */ +/* */ +/* Access of TrueType's `gasp' table (specification). */ +/* */ +/* Copyright 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#ifndef _FT_GASP_H_ +#define _FT_GASP_H_ + +#include +#include FT_FREETYPE_H + + /*************************************************************************** + * + * @section: + * gasp_table + * + * @title: + * Gasp Table + * + * @abstract: + * Retrieving TrueType `gasp' table entries + * + * @description: + * The function @FT_Get_Gasp can be used to query a TrueType or OpenType + * font for specific entries in their `gasp' table, if any. This is + * mainly useful when implementing native TrueType hinting with the + * bytecode interpreter to duplicate the Windows text rendering results. + */ + + /************************************************************************* + * + * @enum: + * FT_GASP_XXX + * + * @description: + * A list of values and/or bit-flags returned by the @FT_Get_Gasp + * function. + * + * @values: + * FT_GASP_NO_TABLE :: + * This special value means that there is no GASP table in this face. + * It is up to the client to decide what to do. + * + * FT_GASP_DO_GRIDFIT :: + * Grid-fitting and hinting should be performed at the specified ppem. + * This *really* means TrueType bytecode interpretation. + * + * FT_GASP_DO_GRAY :: + * Anti-aliased rendering should be performed at the specified ppem. + * + * FT_GASP_SYMMETRIC_SMOOTHING :: + * Smoothing along multiple axes must be used with ClearType. + * + * FT_GASP_SYMMETRIC_GRIDFIT :: + * Grid-fitting must be used with ClearType's symmetric smoothing. + * + * @note: + * `ClearType' is Microsoft's implementation of LCD rendering, partly + * protected by patents. + * + * @since: + * 2.3.0 + */ +#define FT_GASP_NO_TABLE -1 +#define FT_GASP_DO_GRIDFIT 0x01 +#define FT_GASP_DO_GRAY 0x02 +#define FT_GASP_SYMMETRIC_SMOOTHING 0x08 +#define FT_GASP_SYMMETRIC_GRIDFIT 0x10 + + + /************************************************************************* + * + * @func: + * FT_Get_Gasp + * + * @description: + * Read the `gasp' table from a TrueType or OpenType font file and + * return the entry corresponding to a given character pixel size. + * + * @input: + * face :: The source face handle. + * ppem :: The vertical character pixel size. + * + * @return: + * Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE is there is no + * `gasp' table in the face. + * + * @since: + * 2.3.0 + */ + FT_EXPORT( FT_Int ) + FT_Get_Gasp( FT_Face face, + FT_UInt ppem ); + +/* */ + +#endif /* _FT_GASP_H_ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/ftincrem.h b/headers/libs/freetype2/freetype/ftincrem.h index d7f4427cb7..9e1915f1c2 100644 --- a/headers/libs/freetype2/freetype/ftincrem.h +++ b/headers/libs/freetype2/freetype/ftincrem.h @@ -229,11 +229,11 @@ FT_BEGIN_HEADER * * @struct: * FT_Incremental_FuncsRec - * + * * @description: * A table of functions for accessing fonts that load data * incrementally. Used in @FT_Incremental_InterfaceRec. - * + * * @fields: * get_glyph_data :: * The function to get glyph data. Must not be null. @@ -243,7 +243,7 @@ FT_BEGIN_HEADER * * get_glyph_metrics :: * The function to get glyph metrics. May be null if the font does - * not provide overriding glyph metrics. + * not provide overriding glyph metrics. */ typedef struct FT_Incremental_FuncsRec_ { @@ -293,7 +293,7 @@ FT_BEGIN_HEADER { const FT_Incremental_FuncsRec* funcs; FT_Incremental object; - + } FT_Incremental_InterfaceRec; @@ -321,7 +321,7 @@ FT_BEGIN_HEADER */ #define FT_PARAM_TAG_INCREMENTAL FT_MAKE_TAG( 'i', 'n', 'c', 'r' ) - /* */ + /* */ FT_END_HEADER diff --git a/headers/libs/freetype2/freetype/ftlcdfil.h b/headers/libs/freetype2/freetype/ftlcdfil.h new file mode 100644 index 0000000000..9a61377a39 --- /dev/null +++ b/headers/libs/freetype2/freetype/ftlcdfil.h @@ -0,0 +1,166 @@ +/***************************************************************************/ +/* */ +/* ftlcdfil.h */ +/* */ +/* FreeType API for color filtering of subpixel bitmap glyphs */ +/* (specification). */ +/* */ +/* Copyright 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __FT_LCD_FILTER_H__ +#define __FT_LCD_FILTER_H__ + +#include +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + /*************************************************************************** + * + * @section: + * lcd_filtering + * + * @title: + * LCD Filtering + * + * @abstract: + * Reduce color fringes of LCD-optimized bitmaps. + * + * @description: + * The @FT_Library_SetLcdFilter API can be used to specify a low-pass + * filter which is then applied to LCD-optimized bitmaps generated + * through @FT_Render_Glyph. This is useful to reduce color fringes + * which would occur with unfiltered rendering. + * + * Note that no filter is active by default, and that this function is + * *not* implemented in default builds of the library. You need to + * #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your `ftoption.h' file + * in order to activate it. + */ + + + /**************************************************************************** + * + * @func: + * FT_LcdFilter + * + * @description: + * A list of values to identify various types of LCD filters. + * + * @values: + * FT_LCD_FILTER_NONE :: + * Do not perform filtering. When used with subpixel rendering, this + * results in sometimes severe color fringes. + * + * FT_LCD_FILTER_DEFAULT :: + * The default filter reduces color fringes considerably, at the cost + * of a slight blurriness in the output. + * + * FT_LCD_FILTER_LIGHT :: + * The light filter is a variant that produces less blurriness at the + * cost of slightly more color fringes than the default one. It might + * be better, depending on taste, your monitor, or your personal vision. + * + * FT_LCD_FILTER_LEGACY :: + * This filter corresponds to the original libXft color filter. It + * provides high contrast output but can exhibit really bad color + * fringes if glyphs are not extremely well hinted to the pixel grid. + * In other words, it only works well if the TrueType bytecode + * interpreter is enabled *and* high-quality hinted fonts are used. + * + * This filter is only provided for comparison purposes, and might be + * disabled or stay unsupported in the future. + * + * @since: + * 2.3.0 + */ + typedef enum + { + FT_LCD_FILTER_NONE = 0, + FT_LCD_FILTER_DEFAULT = 1, + FT_LCD_FILTER_LIGHT = 2, + FT_LCD_FILTER_LEGACY = 16, + + FT_LCD_FILTER_MAX /* do not remove */ + + } FT_LcdFilter; + + + /************************************************************************** + * + * @func: + * FT_Library_SetLcdFilter + * + * @description: + * This function is used to apply color filtering to LCD decimated + * bitmaps, like the ones used when calling @FT_Render_Glyph with + * @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V. + * + * @input: + * library :: + * A handle to the target library instance. + * + * filter :: + * The filter type. + * + * You can use @FT_LCD_FILTER_NONE here to disable this feature, or + * @FT_LCD_FILTER_DEFAULT to use a default filter that should work + * well on most LCD screens. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * This feature is always disabled by default. Clients must make an + * explicit call to this function with a `filter' value other than + * @FT_LCD_FILTER_NONE in order to enable it. + * + * Due to *PATENTS* covering subpixel rendering, this function doesn't + * do anything except returning `FT_Err_Unimplemented_Feature' if the + * configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not + * defined in your build of the library, which should correspond to all + * default builds of FreeType. + * + * The filter affects glyph bitmaps rendered through @FT_Render_Glyph, + * @FT_Outline_Get_Bitmap, @FT_Load_Glyph, and @FT_Load_Char. + * + * It does _not_ affect the output of @FT_Outline_Render and + * @FT_Outline_Get_Bitmap. + * + * If this feature is activated, the dimensions of LCD glyph bitmaps are + * either larger or taller than the dimensions of the corresponding + * outline with regards to the pixel grid. For example, for + * @FT_RENDER_MODE_LCD, the filter adds up to 3 pixels to the left, and + * up to 3 pixels to the right. + * + * The bitmap offset values are adjusted correctly, so clients shouldn't + * need to modify their layout and glyph positioning code when enabling + * the filter. + * + * @since: + * 2.3.0 + */ + FT_EXPORT( FT_Error ) + FT_Library_SetLcdFilter( FT_Library library, + FT_LcdFilter filter ); + + /* */ + + +FT_END_HEADER + +#endif /* __FT_LCD_FILTER_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/ftotval.h b/headers/libs/freetype2/freetype/ftotval.h index 2bddc6b584..7c488fdf46 100644 --- a/headers/libs/freetype2/freetype/ftotval.h +++ b/headers/libs/freetype2/freetype/ftotval.h @@ -154,10 +154,10 @@ FT_BEGIN_HEADER FT_EXPORT( FT_Error ) FT_OpenType_Validate( FT_Face face, FT_UInt validation_flags, - FT_Bytes *BASE_table, - FT_Bytes *GDEF_table, - FT_Bytes *GPOS_table, - FT_Bytes *GSUB_table, + FT_Bytes *BASE_table, + FT_Bytes *GDEF_table, + FT_Bytes *GPOS_table, + FT_Bytes *GSUB_table, FT_Bytes *JSTF_table ); /* */ diff --git a/headers/libs/freetype2/freetype/ftoutln.h b/headers/libs/freetype2/freetype/ftoutln.h index aa1085a430..c35bb2eb7e 100644 --- a/headers/libs/freetype2/freetype/ftoutln.h +++ b/headers/libs/freetype2/freetype/ftoutln.h @@ -442,13 +442,13 @@ FT_BEGIN_HEADER * * @enum: * FT_Orientation - * + * * @description: * A list of values used to describe an outline's contour orientation. * * The TrueType and Postscript specifications use different conventions * to determine whether outline contours should be filled or unfilled. - * + * * @values: * FT_ORIENTATION_TRUETYPE :: * According to the TrueType specification, clockwise contours must @@ -480,7 +480,7 @@ FT_BEGIN_HEADER FT_ORIENTATION_FILL_RIGHT = FT_ORIENTATION_TRUETYPE, FT_ORIENTATION_FILL_LEFT = FT_ORIENTATION_POSTSCRIPT, FT_ORIENTATION_NONE - + } FT_Orientation; @@ -488,7 +488,7 @@ FT_BEGIN_HEADER * * @function: * FT_Outline_Get_Orientation - * + * * @description: * This function analyzes a glyph outline and tries to compute its * fill orientation (see @FT_Orientation). This is done by computing diff --git a/headers/libs/freetype2/freetype/ftwinfnt.h b/headers/libs/freetype2/freetype/ftwinfnt.h index 5849b00337..a0063cc735 100644 --- a/headers/libs/freetype2/freetype/ftwinfnt.h +++ b/headers/libs/freetype2/freetype/ftwinfnt.h @@ -64,7 +64,7 @@ FT_BEGIN_HEADER * * @values: * FT_WinFNT_ID_DEFAULT :: - * This is used for font enumeration and font creation as a + * This is used for font enumeration and font creation as a * `don't care' value. Valid font files don't contain this value. * When querying for information about the character set of the font * that is currently selected into a specified device context, this @@ -95,7 +95,7 @@ FT_BEGIN_HEADER * Windows have. It is one of the OEM codepages from * * http://www.microsoft.com/globaldev/reference/cphome.mspx, - * + * * and is used for the `DOS boxes', to support legacy applications. * A German Windows version for example usually uses ANSI codepage * 1252 and OEM codepage 850. @@ -130,10 +130,10 @@ FT_BEGIN_HEADER * * FT_WinFNT_ID_CP1253 :: * A superset of Greek ISO 8859-7 (with minor modifications). - * + * * FT_WinFNT_ID_CP1254 :: * A superset of Turkish ISO 8859-9. - * + * * FT_WinFNT_ID_CP1255 :: * A superset of Hebrew ISO 8859-8 (with some modifications). * diff --git a/headers/libs/freetype2/freetype/ftxf86.h b/headers/libs/freetype2/freetype/ftxf86.h index 3362883cbc..bf1c6938cc 100644 --- a/headers/libs/freetype2/freetype/ftxf86.h +++ b/headers/libs/freetype2/freetype/ftxf86.h @@ -4,7 +4,7 @@ /* */ /* Support functions for X11. */ /* */ -/* Copyright 2002, 2003, 2004 by */ +/* Copyright 2002, 2003, 2004, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,24 +31,44 @@ FT_BEGIN_HEADER - /* this comment is intentionally disabled for now, to prevent this */ - /* function from appearing in the API Reference. */ - /*@***********************************************************************/ + /*************************************************************************/ /* */ - /* */ - /* FT_Get_X11_Font_Format */ + /*
*/ + /* font_formats */ + /* */ + /* */ + /* Font Formats */ + /* */ + /* <Abstract> */ + /* Getting the font format. */ /* */ /* <Description> */ - /* Return a string describing the format of a given face as an X11 */ - /* FONT_PROPERTY. It should only be used by the FreeType 2 font */ - /* backend of the XFree86 font server. */ + /* The single function in this section can be used to get the font */ + /* format. Note that this information is not needed normally; */ + /* however, there are special cases (like in PDF devices) where it is */ + /* important to differentiate, inspite of FreeType's uniform API. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_X11_Font_Format */ + /* */ + /* <Description> */ + /* Return a string describing the format of a given face, using values */ + /* which can be used as an X11 FONT_PROPERTY. Possible values are */ + /* `TrueType', `Type 1', `BDF', `PCF', `Type 42', `CID Type 1', `CFF', */ + /* `PFR', and `Windows FNT'. */ /* */ /* <Input> */ - /* face :: Input face handle. */ + /* face :: */ + /* Input face handle. */ /* */ /* <Return> */ - /* Font format string. NULL in case of error. */ + /* Font format string. NULL in case of error. */ /* */ FT_EXPORT( const char* ) FT_Get_X11_Font_Format( FT_Face face ); diff --git a/headers/libs/freetype2/freetype/internal/ftcalc.h b/headers/libs/freetype2/freetype/internal/ftcalc.h index 53d7a67703..c7e9901eba 100644 --- a/headers/libs/freetype2/freetype/internal/ftcalc.h +++ b/headers/libs/freetype2/freetype/internal/ftcalc.h @@ -78,7 +78,7 @@ FT_BEGIN_HEADER /*************************************************************************/ -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER /*************************************************************************/ /* */ @@ -108,7 +108,31 @@ FT_BEGIN_HEADER FT_Long b, FT_Long c ); -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + + /* + * Return -1, 0, or +1, depending on the orientation of a given corner. + * We use the Cartesian coordinate system, with positive vertical values + * going upwards. The function returns +1 if the corner turns to the + * left, -1 to the right, and 0 for undecidable cases. + */ + FT_BASE( FT_Int ) + ft_corner_orientation( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ); + + /* + * Return TRUE if a corner is flat or nearly flat. This is equivalent to + * saying that the angle difference between the `in' and `out' vectors is + * very small. + */ + FT_BASE( FT_Int ) + ft_corner_is_flat( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ); #define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) diff --git a/headers/libs/freetype2/freetype/internal/ftgloadr.h b/headers/libs/freetype2/freetype/internal/ftgloadr.h index b2e35fee3b..9f47c0b8c8 100644 --- a/headers/libs/freetype2/freetype/internal/ftgloadr.h +++ b/headers/libs/freetype2/freetype/internal/ftgloadr.h @@ -69,6 +69,7 @@ FT_BEGIN_HEADER { FT_Outline outline; /* outline */ FT_Vector* extra_points; /* extra points table */ + FT_Vector* extra_points2; /* second extra points table */ FT_UInt num_subglyphs; /* number of subglyphs */ FT_SubGlyph subglyphs; /* subglyphs */ diff --git a/headers/libs/freetype2/freetype/internal/ftobjs.h b/headers/libs/freetype2/freetype/internal/ftobjs.h index 133f360076..2f497582c2 100644 --- a/headers/libs/freetype2/freetype/internal/ftobjs.h +++ b/headers/libs/freetype2/freetype/internal/ftobjs.h @@ -29,6 +29,7 @@ #include <ft2build.h> #include FT_RENDER_H #include FT_SIZES_H +#include FT_LCD_FILTER_H #include FT_INTERNAL_MEMORY_H #include FT_INTERNAL_GLYPH_LOADER_H #include FT_INTERNAL_DRIVER_H @@ -211,6 +212,12 @@ FT_BEGIN_HEADER /* this data when first opened. This field exists only if */ /* @FT_CONFIG_OPTION_INCREMENTAL is defined. */ /* */ + /* ignore_unpatented_hinter :: */ + /* This boolean flag instructs the glyph loader to ignore the */ + /* native font hinter, if one is found. This is exclusively used */ + /* in the case when the unpatented hinter is compiled within the */ + /* library. */ + /* */ typedef struct FT_Face_InternalRec_ { #ifdef FT_CONFIG_OPTION_OLD_INTERNALS @@ -227,6 +234,8 @@ FT_BEGIN_HEADER FT_Incremental_InterfaceRec* incremental_interface; #endif + FT_Bool ignore_unpatented_hinter; + } FT_Face_InternalRec; @@ -621,12 +630,17 @@ FT_BEGIN_HEADER /* Set this debug hook to a non-null pointer to force unpatented hinting */ - /* for all faces when both TT_CONFIG_OPTION_BYTECODE_INTERPRETER and */ - /* TT_CONFIG_OPTION_UNPATENTED_HINTING are defined. this is only used */ + /* for all faces when both TT_USE_BYTECODE_INTERPRETER and */ + /* TT_CONFIG_OPTION_UNPATENTED_HINTING are defined. This is only used */ /* during debugging. */ #define FT_DEBUG_HOOK_UNPATENTED_HINTING 1 + typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap, + FT_Render_Mode render_mode, + FT_Library library ); + + /*************************************************************************/ /* */ /* <Struct> */ @@ -700,6 +714,13 @@ FT_BEGIN_HEADER FT_DebugHook_Func debug_hooks[4]; +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + FT_LcdFilter lcd_filter; + FT_Int lcd_extra; /* number of extra pixels */ + FT_Byte lcd_weights[7]; /* filter weights, if any */ + FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */ +#endif + } FT_LibraryRec; diff --git a/headers/libs/freetype2/freetype/internal/ftstream.h b/headers/libs/freetype2/freetype/internal/ftstream.h index c49d8fc01a..a91eb72d96 100644 --- a/headers/libs/freetype2/freetype/internal/ftstream.h +++ b/headers/libs/freetype2/freetype/internal/ftstream.h @@ -414,7 +414,7 @@ FT_BEGIN_HEADER /* */ /* Useful to optimize access to memory-based streams transparently. */ /* */ - /* All extracted frames must be `freed` with a call to the function */ + /* All extracted frames must be `freed' with a call to the function */ /* FT_Stream_ReleaseFrame(). */ /* */ FT_BASE( FT_Error ) diff --git a/headers/libs/freetype2/freetype/internal/ftvalid.h b/headers/libs/freetype2/freetype/internal/ftvalid.h index d52ff2f3b2..00cd85e7bb 100644 --- a/headers/libs/freetype2/freetype/internal/ftvalid.h +++ b/headers/libs/freetype2/freetype/internal/ftvalid.h @@ -39,7 +39,7 @@ FT_BEGIN_HEADER /*************************************************************************/ /* handle to a validation object */ - typedef struct FT_ValidatorRec_* FT_Validator; + typedef struct FT_ValidatorRec_ volatile* FT_Validator; /*************************************************************************/ @@ -98,6 +98,8 @@ FT_BEGIN_HEADER const FT_Byte* limit, FT_ValidationLevel level ); + /* Do not use this. It's broken and will cause your validator to crash */ + /* if you run it on an invalid font. */ FT_BASE( FT_Int ) ft_validator_run( FT_Validator valid ); diff --git a/headers/libs/freetype2/freetype/internal/psaux.h b/headers/libs/freetype2/freetype/internal/psaux.h index d2e4910009..4baf7a094a 100644 --- a/headers/libs/freetype2/freetype/internal/psaux.h +++ b/headers/libs/freetype2/freetype/internal/psaux.h @@ -154,6 +154,7 @@ FT_BEGIN_HEADER T1_TOKEN_TYPE_ANY, T1_TOKEN_TYPE_STRING, T1_TOKEN_TYPE_ARRAY, + T1_TOKEN_TYPE_KEY, /* aka `name' */ /* do not remove */ T1_TOKEN_TYPE_MAX @@ -199,6 +200,9 @@ FT_BEGIN_HEADER T1_FIELD_LOCATION_FONT_INFO, T1_FIELD_LOCATION_PRIVATE, T1_FIELD_LOCATION_BBOX, + T1_FIELD_LOCATION_LOADER, + T1_FIELD_LOCATION_FACE, + T1_FIELD_LOCATION_BLEND, /* do not remove */ T1_FIELD_LOCATION_MAX @@ -224,86 +228,96 @@ FT_BEGIN_HEADER /* array */ FT_UInt count_offset; /* offset of element count for */ /* arrays */ + FT_UInt dict; /* where we expect it */ } T1_FieldRec; +#define T1_FIELD_DICT_FONTDICT ( 1 << 0 ) /* also FontInfo and FDArray */ +#define T1_FIELD_DICT_PRIVATE ( 1 << 1 ) -#define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname ) \ - { \ - _ident, T1CODE, _type, \ - 0, \ - FT_FIELD_OFFSET( _fname ), \ - FT_FIELD_SIZE( _fname ), \ - 0, 0 \ + + +#define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname, _dict ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE( _fname ), \ + 0, 0, \ + _dict \ }, -#define T1_NEW_CALLBACK_FIELD( _ident, _reader ) \ - { \ - _ident, T1CODE, T1_FIELD_TYPE_CALLBACK, \ - (T1_Field_ParseFunc)_reader, \ - 0, 0, \ - 0, 0 \ +#define T1_NEW_CALLBACK_FIELD( _ident, _reader, _dict ) \ + { \ + _ident, T1CODE, T1_FIELD_TYPE_CALLBACK, \ + (T1_Field_ParseFunc)_reader, \ + 0, 0, \ + 0, 0, \ + _dict \ }, -#define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max ) \ - { \ - _ident, T1CODE, _type, \ - 0, \ - FT_FIELD_OFFSET( _fname ), \ - FT_FIELD_SIZE_DELTA( _fname ), \ - _max, \ - FT_FIELD_OFFSET( num_ ## _fname ) \ +#define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max, _dict ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE_DELTA( _fname ), \ + _max, \ + FT_FIELD_OFFSET( num_ ## _fname ), \ + _dict \ }, -#define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max ) \ - { \ - _ident, T1CODE, _type, \ - 0, \ - FT_FIELD_OFFSET( _fname ), \ - FT_FIELD_SIZE_DELTA( _fname ), \ - _max, 0 \ +#define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max, _dict ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE_DELTA( _fname ), \ + _max, 0, \ + _dict \ }, -#define T1_FIELD_BOOL( _ident, _fname ) \ - T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname ) +#define T1_FIELD_BOOL( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname, _dict ) -#define T1_FIELD_NUM( _ident, _fname ) \ - T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname ) +#define T1_FIELD_NUM( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname, _dict ) -#define T1_FIELD_FIXED( _ident, _fname ) \ - T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED, _fname ) +#define T1_FIELD_FIXED( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED, _fname, _dict ) -#define T1_FIELD_FIXED_1000( _ident, _fname ) \ - T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname ) +#define T1_FIELD_FIXED_1000( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname, \ + _dict ) -#define T1_FIELD_STRING( _ident, _fname ) \ - T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname ) +#define T1_FIELD_STRING( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname, _dict ) -#define T1_FIELD_KEY( _ident, _fname ) \ - T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname ) +#define T1_FIELD_KEY( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname, _dict ) -#define T1_FIELD_BBOX( _ident, _fname ) \ - T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BBOX, _fname ) +#define T1_FIELD_BBOX( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BBOX, _fname, _dict ) -#define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax ) \ +#define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax, _dict ) \ T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \ - _fname, _fmax ) + _fname, _fmax, _dict ) -#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax ) \ +#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax, _dict ) \ T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \ - _fname, _fmax ) + _fname, _fmax, _dict ) -#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax ) \ +#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax, _dict ) \ T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \ - _fname, _fmax ) + _fname, _fmax, _dict ) -#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax ) \ +#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax, _dict ) \ T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \ - _fname, _fmax ) + _fname, _fmax, _dict ) -#define T1_FIELD_CALLBACK( _ident, _name ) \ - T1_NEW_CALLBACK_FIELD( _ident, _name ) +#define T1_FIELD_CALLBACK( _ident, _name, _dict ) \ + T1_NEW_CALLBACK_FIELD( _ident, _name, _dict ) /*************************************************************************/ @@ -683,6 +697,9 @@ FT_BEGIN_HEADER T1_Decoder_Callback parse_callback; T1_Decoder_FuncsRec funcs; + FT_Int* buildchar; + FT_UInt len_buildchar; + } T1_DecoderRec; @@ -712,8 +729,10 @@ FT_BEGIN_HEADER } AFM_Parser_FuncsRec; + typedef struct AFM_StreamRec_* AFM_Stream; + /*************************************************************************/ /* */ /* <Struct> */ @@ -801,6 +820,57 @@ FT_BEGIN_HEADER /* backwards-compatible type definition */ typedef PSAux_ServiceRec PSAux_Interface; + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Some convenience functions *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define IS_PS_NEWLINE( ch ) \ + ( (ch) == '\r' || \ + (ch) == '\n' ) + +#define IS_PS_SPACE( ch ) \ + ( (ch) == ' ' || \ + IS_PS_NEWLINE( ch ) || \ + (ch) == '\t' || \ + (ch) == '\f' || \ + (ch) == '\0' ) + +#define IS_PS_SPECIAL( ch ) \ + ( (ch) == '/' || \ + (ch) == '(' || (ch) == ')' || \ + (ch) == '<' || (ch) == '>' || \ + (ch) == '[' || (ch) == ']' || \ + (ch) == '{' || (ch) == '}' || \ + (ch) == '%' ) + +#define IS_PS_DELIM( ch ) \ + ( IS_PS_SPACE( ch ) || \ + IS_PS_SPECIAL( ch ) ) + +#define IS_PS_DIGIT( ch ) \ + ( (ch) >= '0' && (ch) <= '9' ) + +#define IS_PS_XDIGIT( ch ) \ + ( IS_PS_DIGIT( ch ) || \ + ( (ch) >= 'A' && (ch) <= 'F' ) || \ + ( (ch) >= 'a' && (ch) <= 'f' ) ) + +#define IS_PS_BASE85( ch ) \ + ( (ch) >= '!' && (ch) <= 'u' ) + +#define IS_PS_TOKEN( cur, limit, token ) \ + ( (char)(cur)[0] == (token)[0] && \ + ( (cur) + sizeof ( (token) ) == (limit) || \ + ( (cur) + sizeof( (token) ) < (limit) && \ + IS_PS_DELIM( (cur)[sizeof ( (token) ) - 1] ) ) ) && \ + ft_strncmp( (char*)(cur), (token), sizeof ( (token) ) - 1 ) == 0 ) + + FT_END_HEADER #endif /* __PSAUX_H__ */ diff --git a/headers/libs/freetype2/freetype/internal/services/svkern.h b/headers/libs/freetype2/freetype/internal/services/svkern.h index 169b36dded..1488adf493 100644 --- a/headers/libs/freetype2/freetype/internal/services/svkern.h +++ b/headers/libs/freetype2/freetype/internal/services/svkern.h @@ -36,12 +36,12 @@ FT_BEGIN_HEADER FT_DEFINE_SERVICE( Kerning ) { - FT_Kerning_TrackGetFunc get_track; + FT_Kerning_TrackGetFunc get_track; }; /* */ - + FT_END_HEADER diff --git a/headers/libs/freetype2/freetype/internal/services/svotval.h b/headers/libs/freetype2/freetype/internal/services/svotval.h index 88da778871..970bbd5759 100644 --- a/headers/libs/freetype2/freetype/internal/services/svotval.h +++ b/headers/libs/freetype2/freetype/internal/services/svotval.h @@ -29,13 +29,13 @@ FT_BEGIN_HEADER typedef FT_Error - (*otv_validate_func)( FT_Face face, - FT_UInt ot_flags, - FT_Bytes *base, - FT_Bytes *gdef, - FT_Bytes *gpos, - FT_Bytes *gsub, - FT_Bytes *jstf ); + (*otv_validate_func)( FT_Face volatile face, + FT_UInt ot_flags, + FT_Bytes *base, + FT_Bytes *gdef, + FT_Bytes *gpos, + FT_Bytes *gsub, + FT_Bytes *jstf ); FT_DEFINE_SERVICE( OTvalidate ) diff --git a/headers/libs/freetype2/freetype/internal/services/svpscmap.h b/headers/libs/freetype2/freetype/internal/services/svpscmap.h index 8f418a83a1..c4e25ed635 100644 --- a/headers/libs/freetype2/freetype/internal/services/svpscmap.h +++ b/headers/libs/freetype2/freetype/internal/services/svpscmap.h @@ -75,15 +75,24 @@ FT_BEGIN_HEADER * NULL if invalid index. */ typedef const char* - (*PS_Glyph_NameFunc)( FT_Pointer data, - FT_UInt string_index ); + (*PS_GetGlyphNameFunc)( FT_Pointer data, + FT_UInt string_index ); + + /* + * A function used to release the glyph name returned by + * PS_GetGlyphNameFunc, when needed + */ + typedef void + (*PS_FreeGlyphNameFunc)( FT_Pointer data, + const char* name ); typedef FT_Error - (*PS_Unicodes_InitFunc)( FT_Memory memory, - PS_Unicodes unicodes, - FT_UInt num_glyphs, - PS_Glyph_NameFunc get_glyph_name, - FT_Pointer glyph_data ); + (*PS_Unicodes_InitFunc)( FT_Memory memory, + PS_Unicodes unicodes, + FT_UInt num_glyphs, + PS_GetGlyphNameFunc get_glyph_name, + PS_FreeGlyphNameFunc free_glyph_name, + FT_Pointer glyph_data ); typedef FT_UInt (*PS_Unicodes_CharIndexFunc)( PS_Unicodes unicodes, diff --git a/headers/libs/freetype2/freetype/internal/services/svttcmap.h b/headers/libs/freetype2/freetype/internal/services/svttcmap.h index f92fcd0e2c..1ef96b4fca 100644 --- a/headers/libs/freetype2/freetype/internal/services/svttcmap.h +++ b/headers/libs/freetype2/freetype/internal/services/svttcmap.h @@ -18,11 +18,11 @@ /* */ /***************************************************************************/ -/* Development of this service is support of +/* Development of this service is support of Information-technology Promotion Agency, Japan. */ #ifndef __SVTTCMAP_H__ -#define __SVTTCMAP_H__ +#define __SVTTCMAP_H__ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -64,8 +64,8 @@ FT_BEGIN_HEADER FT_DEFINE_SERVICE( TTCMaps ) { TT_CMap_Info_GetFunc get_cmap_info; - }; - + }; + /* */ diff --git a/headers/libs/freetype2/freetype/internal/services/svxf86nm.h b/headers/libs/freetype2/freetype/internal/services/svxf86nm.h index 3a33abcd8d..ca5d884a83 100644 --- a/headers/libs/freetype2/freetype/internal/services/svxf86nm.h +++ b/headers/libs/freetype2/freetype/internal/services/svxf86nm.h @@ -45,7 +45,7 @@ FT_BEGIN_HEADER /* */ - + FT_END_HEADER diff --git a/headers/libs/freetype2/freetype/internal/sfnt.h b/headers/libs/freetype2/freetype/internal/sfnt.h index b88607a08d..7e8f6847c9 100644 --- a/headers/libs/freetype2/freetype/internal/sfnt.h +++ b/headers/libs/freetype2/freetype/internal/sfnt.h @@ -738,13 +738,13 @@ FT_BEGIN_HEADER /* the table directory */ TT_Load_Table_Func load_font_dir; TT_Load_Metrics_Func load_hmtx; - + TT_Load_Table_Func load_eblc; TT_Free_Table_Func free_eblc; - + TT_Set_SBit_Strike_Func set_sbit_strike; TT_Load_Strike_Metrics_Func load_strike_metrics; - + TT_Get_Metrics_Func get_metrics; } SFNT_Interface; diff --git a/headers/libs/freetype2/freetype/internal/t1types.h b/headers/libs/freetype2/freetype/internal/t1types.h index 65d9ca92e8..047c6d59df 100644 --- a/headers/libs/freetype2/freetype/internal/t1types.h +++ b/headers/libs/freetype2/freetype/internal/t1types.h @@ -203,11 +203,22 @@ FT_BEGIN_HEADER #ifdef FT_CONFIG_OPTION_OLD_INTERNALS PS_Unicodes unicode_map; -#endif +#endif /* support for Multiple Masters fonts */ PS_Blend blend; + /* undocumented, optional: indices of subroutines that express */ + /* the NormalizeDesignVector and the ConvertDesignVector procedure, */ + /* respectively, as Type 2 charstrings; -1 if keywords not present */ + FT_Int ndv_idx; + FT_Int cdv_idx; + + /* undocumented, optional: has the same meaning as len_buildchar */ + /* for Type 2 fonts; manipulated by othersubrs 19, 24, and 25 */ + FT_UInt len_buildchar; + FT_Int* buildchar; + /* since version 2.1 - interface to PostScript hinter */ const void* pshinter; diff --git a/headers/libs/freetype2/freetype/internal/tttypes.h b/headers/libs/freetype2/freetype/internal/tttypes.h index 5235cc0d20..8179cca816 100644 --- a/headers/libs/freetype2/freetype/internal/tttypes.h +++ b/headers/libs/freetype2/freetype/internal/tttypes.h @@ -5,7 +5,7 @@ /* Basic SFNT/TrueType type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -1395,7 +1395,6 @@ FT_BEGIN_HEADER /* since version 2.2 */ -#ifdef FT_OPTIMIZE_MEMORY FT_Byte* horz_metrics; FT_ULong horz_metrics_size; @@ -1420,12 +1419,15 @@ FT_BEGIN_HEADER FT_UInt num_kern_tables; FT_UInt32 kern_avail_bits; FT_UInt32 kern_order_bits; -#endif #ifdef TT_CONFIG_OPTION_BDF TT_BDFRec bdf; #endif /* TT_CONFIG_OPTION_BDF */ + /* since 2.3.0 */ + FT_ULong horz_metrics_offset; + FT_ULong vert_metrics_offset; + } TT_FaceRec; @@ -1458,19 +1460,24 @@ FT_BEGIN_HEADER /* */ /* contours :: The contours end points. */ /* */ + /* first_point :: Offset of the current subglyph's first point. */ + /* */ typedef struct TT_GlyphZoneRec_ { FT_Memory memory; FT_UShort max_points; FT_UShort max_contours; - FT_UShort n_points; /* number of points in zone */ - FT_Short n_contours; /* number of contours */ + FT_UShort n_points; /* number of points in zone */ + FT_Short n_contours; /* number of contours */ - FT_Vector* org; /* original point coordinates */ - FT_Vector* cur; /* current point coordinates */ + FT_Vector* org; /* original point coordinates */ + FT_Vector* cur; /* current point coordinates */ + FT_Vector* orus; /* original (unscaled) point coordinates */ - FT_Byte* tags; /* current touch flags */ - FT_UShort* contours; /* contour end points */ + FT_Byte* tags; /* current touch flags */ + FT_UShort* contours; /* contour end points */ + + FT_UShort first_point; /* offset of first (#0) point */ } TT_GlyphZoneRec, *TT_GlyphZone; @@ -1521,6 +1528,10 @@ FT_BEGIN_HEADER FT_Vector pp3; FT_Vector pp4; + /* since version 2.2.1 */ + FT_Byte* cursor; + FT_Byte* limit; + } TT_LoaderRec; diff --git a/headers/libs/freetype2/freetype/t1tables.h b/headers/libs/freetype2/freetype/t1tables.h index 1815250a4f..250629d252 100644 --- a/headers/libs/freetype2/freetype/t1tables.h +++ b/headers/libs/freetype2/freetype/t1tables.h @@ -5,7 +5,7 @@ /* Basic Type 1/Type 2 tables definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -256,6 +256,15 @@ FT_BEGIN_HEADER FT_BBox* bboxes [T1_MAX_MM_DESIGNS + 1]; + /* since 2.3.0 */ + + /* undocumented, optional: the default design instance; */ + /* corresponds to default_weight_vector -- */ + /* num_default_design_vector == 0 means it is not present */ + /* in the font and associated metrics files */ + FT_UInt default_design_vector[T1_MAX_MM_DESIGNS]; + FT_UInt num_default_design_vector; + } PS_BlendRec, *PS_Blend; diff --git a/headers/libs/freetype2/freetype/tttables.h b/headers/libs/freetype2/freetype/tttables.h index 251d67717b..d6e690f880 100644 --- a/headers/libs/freetype2/freetype/tttables.h +++ b/headers/libs/freetype2/freetype/tttables.h @@ -619,7 +619,7 @@ FT_BEGIN_HEADER * to access the whole font file. Otherwise, you can use one of the * definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new * one with @FT_MAKE_TAG. - * + * * offset :: * The starting offset in the table (or file if tag == 0). * @@ -630,7 +630,7 @@ FT_BEGIN_HEADER * * @inout: * length :: - * If the `length' parameter is NULL, then try to load the whole table. + * If the `length' parameter is NULL, then try to load the whole table. * Return an error code if it fails. * * Else, if `*length' is 0, exit immediately while returning the diff --git a/src/libs/freetype2/autofit/afangles.c b/src/libs/freetype2/autofit/afangles.c index 94a84862b7..e2360d157d 100644 --- a/src/libs/freetype2/autofit/afangles.c +++ b/src/libs/freetype2/autofit/afangles.c @@ -5,7 +5,7 @@ /* Routines used to compute vector angles with limited accuracy */ /* and very high speed. It also contains sorting routines (body). */ /* */ -/* Copyright 2003, 2004, 2005 by */ +/* Copyright 2003, 2004, 2005, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,7 +20,123 @@ #include "aftypes.h" -#if 1 +#if 0 + + FT_LOCAL_DEF( FT_Int ) + af_corner_is_flat( FT_Pos x_in, + FT_Pos y_in, + FT_Pos x_out, + FT_Pos y_out ) + { + FT_Pos ax = x_in; + FT_Pos ay = y_in; + + FT_Pos d_in, d_out, d_corner; + + + if ( ax < 0 ) + ax = -ax; + if ( ay < 0 ) + ay = -ay; + d_in = ax + ay; + + ax = x_out; + if ( ax < 0 ) + ax = -ax; + ay = y_out; + if ( ay < 0 ) + ay = -ay; + d_out = ax + ay; + + ax = x_out + x_in; + if ( ax < 0 ) + ax = -ax; + ay = y_out + y_in; + if ( ay < 0 ) + ay = -ay; + d_corner = ax + ay; + + return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); + } + + + FT_LOCAL_DEF( FT_Int ) + af_corner_orientation( FT_Pos x_in, + FT_Pos y_in, + FT_Pos x_out, + FT_Pos y_out ) + { + FT_Pos delta; + + + delta = x_in * y_out - y_in * x_out; + + if ( delta == 0 ) + return 0; + else + return 1 - 2 * ( delta < 0 ); + } + +#endif + + + /* + * We are not using `af_angle_atan' anymore, but we keep the source + * code below just in case... + */ + + +#if 0 + + + /* + * The trick here is to realize that we don't need a very accurate angle + * approximation. We are going to use the result of `af_angle_atan' to + * only compare the sign of angle differences, or check whether its + * magnitude is very small. + * + * The approximation + * + * dy * PI / (|dx|+|dy|) + * + * should be enough, and much faster to compute. + */ + FT_LOCAL_DEF( AF_Angle ) + af_angle_atan( FT_Fixed dx, + FT_Fixed dy ) + { + AF_Angle angle; + FT_Fixed ax = dx; + FT_Fixed ay = dy; + + + if ( ax < 0 ) + ax = -ax; + if ( ay < 0 ) + ay = -ay; + + ax += ay; + + if ( ax == 0 ) + angle = 0; + else + { + angle = ( AF_ANGLE_PI2 * dy ) / ( ax + ay ); + if ( dx < 0 ) + { + if ( angle >= 0 ) + angle = AF_ANGLE_PI - angle; + else + angle = -AF_ANGLE_PI - angle; + } + } + + return angle; + } + + +#elif 0 + /* the following table has been automatically generated with */ /* the `mather.py' Python script */ @@ -124,222 +240,6 @@ } -#else /* 0 */ - -/* - * a python script used to generate the following table - * - -import sys, math - -units = 256 -scale = units/math.pi -comma = "" - -print "" -print "table of arctan( 1/2^n ) for PI = " + repr( units / 65536.0 ) + " units" - -r = [-1] + range( 32 ) - -for n in r: - if n >= 0: - x = 1.0 / ( 2.0 ** n ) # tangent value - else: - x = 2.0 ** ( -n ) - - angle = math.atan( x ) # arctangent - angle2 = angle * scale # arctangent in FT_Angle units - - # determine which integer value for angle gives the best tangent - lo = int( angle2 ) - hi = lo + 1 - tlo = math.tan( lo / scale ) - thi = math.tan( hi / scale ) - - errlo = abs( tlo - x ) - errhi = abs( thi - x ) - - angle2 = hi - if errlo < errhi: - angle2 = lo - - if angle2 <= 0: - break - - sys.stdout.write( comma + repr( int( angle2 ) ) ) - comma = ", " - -* -* end of python script -*/ - - - /* this table was generated for AF_ANGLE_PI = 256 */ -#define AF_ANGLE_MAX_ITERS 8 -#define AF_TRIG_MAX_ITERS 8 - - static const FT_Fixed - af_angle_arctan_table[9] = - { - 90, 64, 38, 20, 10, 5, 3, 1, 1 - }; - - - static FT_Int - af_angle_prenorm( FT_Vector* vec ) - { - FT_Fixed x, y, z; - FT_Int shift; - - - x = vec->x; - y = vec->y; - - z = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y ); - shift = 0; - - if ( z < ( 1L << 27 ) ) - { - do - { - shift++; - z <<= 1; - } while ( z < ( 1L << 27 ) ); - - vec->x = x << shift; - vec->y = y << shift; - } - else if ( z > ( 1L << 28 ) ) - { - do - { - shift++; - z >>= 1; - } while ( z > ( 1L << 28 ) ); - - vec->x = x >> shift; - vec->y = y >> shift; - shift = -shift; - } - return shift; - } - - - static void - af_angle_pseudo_polarize( FT_Vector* vec ) - { - FT_Fixed theta; - FT_Fixed yi, i; - FT_Fixed x, y; - const FT_Fixed *arctanptr; - - - x = vec->x; - y = vec->y; - - /* Get the vector into the right half plane */ - theta = 0; - if ( x < 0 ) - { - x = -x; - y = -y; - theta = AF_ANGLE_PI; - } - - if ( y > 0 ) - theta = -theta; - - arctanptr = af_angle_arctan_table; - - if ( y < 0 ) - { - /* Rotate positive */ - yi = y + ( x << 1 ); - x = x - ( y << 1 ); - y = yi; - theta -= *arctanptr++; /* Subtract angle */ - } - else - { - /* Rotate negative */ - yi = y - ( x << 1 ); - x = x + ( y << 1 ); - y = yi; - theta += *arctanptr++; /* Add angle */ - } - - i = 0; - do - { - if ( y < 0 ) - { - /* Rotate positive */ - yi = y + ( x >> i ); - x = x - ( y >> i ); - y = yi; - theta -= *arctanptr++; - } - else - { - /* Rotate negative */ - yi = y - ( x >> i ); - x = x + ( y >> i ); - y = yi; - theta += *arctanptr++; - } - } while ( ++i < AF_TRIG_MAX_ITERS ); - -#if 0 - /* round theta */ - if ( theta >= 0 ) - theta = FT_PAD_ROUND( theta, 2 ); - else - theta = -FT_PAD_ROUND( -theta, 2 ); -#endif - - vec->x = x; - vec->y = theta; - } - - - /* cf. documentation in fttrigon.h */ - - FT_LOCAL_DEF( AF_Angle ) - af_angle_atan( FT_Fixed dx, - FT_Fixed dy ) - { - FT_Vector v; - - - if ( dx == 0 && dy == 0 ) - return 0; - - v.x = dx; - v.y = dy; - af_angle_prenorm( &v ); - af_angle_pseudo_polarize( &v ); - - return v.y; - } - - - FT_LOCAL_DEF( AF_Angle ) - af_angle_diff( AF_Angle angle1, - AF_Angle angle2 ) - { - AF_Angle delta = angle2 - angle1; - - - delta %= AF_ANGLE_2PI; - if ( delta < 0 ) - delta += AF_ANGLE_2PI; - - if ( delta > AF_ANGLE_PI ) - delta -= AF_ANGLE_2PI; - - return delta; - } - #endif /* 0 */ @@ -389,45 +289,4 @@ for n in r: } -#ifdef TEST - -#include <stdio.h> -#include <math.h> - -int main( void ) -{ - int angle; - int dist; - - - for ( dist = 100; dist < 1000; dist++ ) - { - for ( angle = AF_ANGLE_PI; angle < AF_ANGLE_2PI * 4; angle++ ) - { - double a = ( angle * 3.1415926535 ) / ( 1.0 * AF_ANGLE_PI ); - int dx, dy, angle1, angle2, delta; - - - dx = dist * cos( a ); - dy = dist * sin( a ); - - angle1 = ( ( atan2( dy, dx ) * AF_ANGLE_PI ) / 3.1415926535 ); - angle2 = af_angle_atan( dx, dy ); - delta = ( angle2 - angle1 ) % AF_ANGLE_2PI; - if ( delta < 0 ) - delta = -delta; - - if ( delta >= 2 ) - { - printf( "dist:%4d angle:%4d => (%4d,%4d) angle1:%4d angle2:%4d\n", - dist, angle, dx, dy, angle1, angle2 ); - } - } - } - return 0; -} - -#endif /* TEST */ - - /* END */ diff --git a/src/libs/freetype2/autofit/afcjk.c b/src/libs/freetype2/autofit/afcjk.c index 6a020e3f4a..2d01111661 100644 --- a/src/libs/freetype2/autofit/afcjk.c +++ b/src/libs/freetype2/autofit/afcjk.c @@ -1437,7 +1437,9 @@ static const AF_Script_UniRangeRec af_cjk_uniranges[] = { - { 0x0100, 0xFFFF }, +#if 0 + { 0x0100, 0xFFFF }, /* why this? */ +#endif { 0x2E80, 0x2EFF }, /* CJK Radicals Supplement */ { 0x2F00, 0x2FDF }, /* Kangxi Radicals */ { 0x3000, 0x303F }, /* CJK Symbols and Punctuation */ diff --git a/src/libs/freetype2/autofit/afhints.c b/src/libs/freetype2/autofit/afhints.c index b011c15b07..65a46620d3 100644 --- a/src/libs/freetype2/autofit/afhints.c +++ b/src/libs/freetype2/autofit/afhints.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006 by */ +/* Copyright 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, */ @@ -18,6 +18,7 @@ #include "afhints.h" #include "aferrors.h" +#include FT_INTERNAL_CALC_H FT_LOCAL_DEF( FT_Error ) @@ -53,7 +54,9 @@ } segment = axis->segments + axis->num_segments++; +#if 0 FT_ZERO( segment ); +#endif Exit: *asegment = segment; @@ -188,8 +191,7 @@ void af_glyph_hints_dump_segments( AF_GlyphHints hints ) { - AF_Point points = hints->points; - FT_Int dimension; + FT_Int dimension; for ( dimension = 1; dimension >= 0; dimension-- ) @@ -203,19 +205,18 @@ printf ( "Table of %s segments:\n", dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" ); printf ( " [ index | pos | dir | link | serif |" - " numl | first | start ]\n" ); + " height | extra ]\n" ); for ( seg = segments; seg < limit; seg++ ) { - printf ( " [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n", + printf ( " [ %5d | %4d | %5s | %4d | %5d | %5d | %5d ]\n", seg - segments, (int)seg->pos, - af_dir_str( seg->dir ), + af_dir_str( (AF_Direction)seg->dir ), AF_INDEX_NUM( seg->link, segments ), AF_INDEX_NUM( seg->serif, segments ), - (int)seg->num_linked, - seg->first - points, - seg->last - points ); + seg->height, + seg->height - ( seg->max_coord - seg->min_coord ) ); } printf( "\n" ); } @@ -251,7 +252,7 @@ " %5d | %c | %5.2f | %5.2f ]\n", edge - edges, (int)edge->fpos, - af_dir_str( edge->dir ), + af_dir_str( (AF_Direction)edge->dir ), AF_INDEX_NUM( edge->link, edges ), AF_INDEX_NUM( edge->serif, edges ), edge->blue_edge ? 'y' : 'n', @@ -262,8 +263,32 @@ } } -#endif /* AF_DEBUG */ +#else /* !AF_DEBUG */ + /* these empty stubs are only used to link the `ftgrid' test program */ + /* when debugging is disabled */ + + void + af_glyph_hints_dump_points( AF_GlyphHints hints ) + { + FT_UNUSED( hints ); + } + + + void + af_glyph_hints_dump_segments( AF_GlyphHints hints ) + { + FT_UNUSED( hints ); + } + + + void + af_glyph_hints_dump_edges( AF_GlyphHints hints ) + { + FT_UNUSED( hints ); + } + +#endif /* !AF_DEBUG */ /* compute the direction value of a given vector */ @@ -271,51 +296,48 @@ af_direction_compute( FT_Pos dx, FT_Pos dy ) { + #if 1 - AF_Direction dir = AF_DIR_NONE; + + FT_Pos ll, ss; /* long and short arm lengths */ + AF_Direction dir; /* candidate direction */ - /* atan(1/12) == 4.7 degrees */ - - if ( dx < 0 ) + if ( dy >= dx ) { - if ( dy < 0 ) + if ( dy >= -dx ) { - if ( -dx * 12 < -dy ) - dir = AF_DIR_DOWN; - - else if ( -dy * 12 < -dx ) - dir = AF_DIR_LEFT; + dir = AF_DIR_UP; + ll = dy; + ss = dx; } - else /* dy >= 0 */ + else { - if ( -dx * 12 < dy ) - dir = AF_DIR_UP; - - else if ( dy * 12 < -dx ) - dir = AF_DIR_LEFT; + dir = AF_DIR_LEFT; + ll = -dx; + ss = dy; } } - else /* dx >= 0 */ + else /* dy < dx */ { - if ( dy < 0 ) + if ( dy >= -dx ) { - if ( dx * 12 < -dy ) - dir = AF_DIR_DOWN; - - else if ( -dy * 12 < dx ) - dir = AF_DIR_RIGHT; + dir = AF_DIR_RIGHT; + ll = dx; + ss = dy; } - else /* dy >= 0 */ + else { - if ( dx * 12 < dy ) - dir = AF_DIR_UP; - - else if ( dy * 12 < dx ) - dir = AF_DIR_RIGHT; + dir = AF_DIR_DOWN; + ll = dy; + ss = dx; } } + ss *= 12; + if ( FT_ABS(ll) <= FT_ABS(ss) ) + dir = AF_DIR_NONE; + return dir; #else /* 0 */ @@ -348,6 +370,122 @@ /* compute all inflex points in a given glyph */ + +#if 1 + + static void + af_glyph_hints_compute_inflections( AF_GlyphHints hints ) + { + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; + + + /* do each contour separately */ + for ( ; contour < contour_limit; contour++ ) + { + AF_Point point = contour[0]; + AF_Point first = point; + AF_Point start = point; + AF_Point end = point; + AF_Point before; + AF_Point after; + FT_Pos in_x, in_y, out_x, out_y; + AF_Angle orient_prev, orient_cur; + FT_Int finished = 0; + + + /* compute first segment in contour */ + first = point; + + start = end = first; + do + { + end = end->next; + if ( end == first ) + goto Skip; + + in_x = end->fx - start->fx; + in_y = end->fy - start->fy; + + } while ( in_x == 0 && in_y == 0 ); + + /* extend the segment start whenever possible */ + before = start; + do + { + do + { + start = before; + before = before->prev; + if ( before == first ) + goto Skip; + + out_x = start->fx - before->fx; + out_y = start->fy - before->fy; + + } while ( out_x == 0 && out_y == 0 ); + + orient_prev = ft_corner_orientation( in_x, in_y, out_x, out_y ); + + } while ( orient_prev == 0 ); + + first = start; + + in_x = out_x; + in_y = out_y; + + /* now process all segments in the contour */ + do + { + /* first, extend current segment's end whenever possible */ + after = end; + do + { + do + { + end = after; + after = after->next; + if ( after == first ) + finished = 1; + + out_x = after->fx - end->fx; + out_y = after->fy - end->fy; + + } while ( out_x == 0 && out_y == 0 ); + + orient_cur = ft_corner_orientation( in_x, in_y, out_x, out_y ); + + } while ( orient_cur == 0 ); + + if ( ( orient_prev + orient_cur ) == 0 ) + { + /* we have an inflection point here */ + do + { + start->flags |= AF_FLAG_INFLECTION; + start = start->next; + + } while ( start != end ); + + start->flags |= AF_FLAG_INFLECTION; + } + + start = end; + end = after; + + orient_prev = orient_cur; + in_x = out_x; + in_y = out_y; + + } while ( !finished ); + + Skip: + ; + } + } + +#else /* old code */ + static void af_glyph_hints_compute_inflections( AF_GlyphHints hints ) { @@ -455,6 +593,8 @@ } } +#endif /* old code */ + FT_LOCAL_DEF( void ) af_glyph_hints_init( AF_GlyphHints hints, @@ -702,6 +842,17 @@ } else if ( point->out_dir == point->in_dir ) { + +#if 1 + + if ( point->out_dir != AF_DIR_NONE ) + goto Is_Weak_Point; + + if ( ft_corner_is_flat( in_x, in_y, out_x, out_y ) ) + goto Is_Weak_Point; + +#else /* old code */ + AF_Angle angle_in, angle_out, delta; @@ -715,6 +866,9 @@ if ( delta < 2 && delta > -2 ) goto Is_Weak_Point; + +#endif /* old code */ + } else if ( point->in_dir == -point->out_dir ) goto Is_Weak_Point; @@ -1152,7 +1306,7 @@ AF_Point points = hints->points; AF_Point points_limit = points + hints->num_points; AF_Point point; - + if ( dim == AF_DIMENSION_HORZ ) { diff --git a/src/libs/freetype2/autofit/afhints.h b/src/libs/freetype2/autofit/afhints.h index cb27b8f974..c889aad76e 100644 --- a/src/libs/freetype2/autofit/afhints.h +++ b/src/libs/freetype2/autofit/afhints.h @@ -125,6 +125,7 @@ FT_BEGIN_HEADER FT_Short pos; /* position of segment */ FT_Short min_coord; /* minimum coordinate of segment */ FT_Short max_coord; /* maximum coordinate of segment */ + FT_Short height; /* the hinted segment height */ AF_Edge edge; /* the segment's parent edge */ AF_Segment edge_next; /* link to next segment in parent edge */ @@ -213,6 +214,24 @@ FT_BEGIN_HEADER #define AF_HINTS_TEST_SCALER( h, f ) ( (h)->scaler_flags & (f) ) #define AF_HINTS_TEST_OTHER( h, f ) ( (h)->other_flags & (f) ) + +#ifdef AF_DEBUG + +#define AF_HINTS_DO_HORIZONTAL( h ) \ + ( !_af_debug_disable_horz_hints && \ + !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) ) + +#define AF_HINTS_DO_VERTICAL( h ) \ + ( !_af_debug_disable_vert_hints && \ + !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) ) + +#define AF_HINTS_DO_ADVANCE( h ) \ + !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE ) + +#define AF_HINTS_DO_BLUES( h ) ( !_af_debug_disable_blue_hints ) + +#else /* !AF_DEBUG */ + #define AF_HINTS_DO_HORIZONTAL( h ) \ !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) @@ -222,6 +241,10 @@ FT_BEGIN_HEADER #define AF_HINTS_DO_ADVANCE( h ) \ !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE ) +#define AF_HINTS_DO_BLUES( h ) 1 + +#endif /* !AF_DEBUG */ + FT_LOCAL( AF_Direction ) af_direction_compute( FT_Pos dx, diff --git a/src/libs/freetype2/autofit/aflatin.c b/src/libs/freetype2/autofit/aflatin.c index 2351f23f12..fbb9e15d0d 100644 --- a/src/libs/freetype2/autofit/aflatin.c +++ b/src/libs/freetype2/autofit/aflatin.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for latin script (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006 by */ +/* Copyright 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, */ @@ -471,7 +471,7 @@ if ( blue ) { FT_Pos scaled = FT_MulFix( blue->shoot.org, scaler->y_scale ); - FT_Pos fitted = FT_PIX_ROUND( scaled ); + FT_Pos fitted = ( scaled + 40 ) & ~63; if ( scaled != fitted ) @@ -590,6 +590,7 @@ FT_Memory memory = hints->memory; FT_Error error = AF_Err_Ok; AF_Segment segment = NULL; + AF_SegmentRec seg0; AF_Point* contour = hints->contours; AF_Point* contour_limit = contour + hints->num_contours; AF_Direction major_dir, segment_dir; @@ -601,6 +602,11 @@ FT_Pos max_coord = -32000; #endif + + FT_ZERO( &seg0 ); + seg0.score = 32000; + seg0.flags = AF_EDGE_NORMAL; + major_dir = (AF_Direction)FT_ABS( axis->major_dir ); segment_dir = major_dir; @@ -717,6 +723,8 @@ segment->min_coord = (FT_Short)min_pos; segment->max_coord = (FT_Short)max_pos; + segment->height = (FT_Short)( segment->max_coord - + segment->min_coord ); on_edge = 0; segment = NULL; @@ -742,15 +750,12 @@ if ( error ) goto Exit; + segment[0] = seg0; segment->dir = (FT_Char)segment_dir; - segment->flags = AF_EDGE_NORMAL; min_pos = max_pos = point->u; segment->first = point; segment->last = point; segment->contour = contour; - segment->score = 32000; - segment->len = 0; - segment->link = NULL; on_edge = 1; #ifdef AF_HINT_METRICS @@ -767,6 +772,58 @@ } /* contours */ + + /* now slightly increase the height of segments when this makes */ + /* sense -- this is used to better detect and ignore serifs */ + { + AF_Segment segments = axis->segments; + AF_Segment segments_end = segments + axis->num_segments; + + + for ( segment = segments; segment < segments_end; segment++ ) + { + AF_Point first = segment->first; + AF_Point last = segment->last; + FT_Pos first_v = first->v; + FT_Pos last_v = last->v; + + + if ( first == last ) + continue; + + if ( first_v < last_v ) + { + AF_Point p; + + + p = first->prev; + if ( p->v < first_v ) + segment->height = (FT_Short)( segment->height + + ( ( first_v - p->v ) >> 1 ) ); + + p = last->next; + if ( p->v > last_v ) + segment->height = (FT_Short)( segment->height + + ( ( p->v - last_v ) >> 1 ) ); + } + else + { + AF_Point p; + + + p = first->prev; + if ( p->v > first_v ) + segment->height = (FT_Short)( segment->height + + ( ( p->v - first_v ) >> 1 ) ); + + p = last->next; + if ( p->v < last_v ) + segment->height = (FT_Short)( segment->height + + ( ( last_v - p->v ) >> 1 ) ); + } + } + } + #ifdef AF_HINT_METRICS /* we need to ensure that there are edges on the left-most and */ /* right-most points of the glyph in order to hint the metrics; */ @@ -810,14 +867,11 @@ if ( error ) goto Exit; + segment[0] = seg0; segment->dir = segment_dir; - segment->flags = AF_EDGE_NORMAL; segment->first = min_point; segment->last = min_point; segment->pos = min_pos; - segment->score = 32000; - segment->len = 0; - segment->link = NULL; segment = NULL; } @@ -830,14 +884,11 @@ if ( error ) goto Exit; + segment[0] = seg0; segment->dir = segment_dir; - segment->flags = AF_EDGE_NORMAL; segment->first = max_point; segment->last = max_point; segment->pos = max_pos; - segment->score = 32000; - segment->len = 0; - segment->link = NULL; segment = NULL; } @@ -865,7 +916,7 @@ if ( len_threshold == 0 ) len_threshold = 1; - len_score = AF_LATIN_CONSTANT( hints->metrics, 3000 ); + len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 ); /* now compare each segment to the others */ for ( seg1 = segments; seg1 < segment_limit; seg1++ ) @@ -926,7 +977,6 @@ if ( seg2 ) { - seg2->num_linked++; if ( seg2->link != seg1 ) { seg1->link = 0; @@ -953,6 +1003,7 @@ AF_Direction up_dir; FT_Fixed scale; FT_Pos edge_distance_threshold; + FT_Pos segment_length_threshold; axis->num_edges = 0; @@ -963,6 +1014,16 @@ up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP : AF_DIR_RIGHT; + /* + * We ignore all segments that are less than 1 pixels in length, + * to avoid many problems with serif fonts. We compute the + * corresponding threshold in font units. + */ + if ( dim == AF_DIMENSION_HORZ ) + segment_length_threshold = FT_DivFix( 96, hints->y_scale ); + else + segment_length_threshold = 0; + /*********************************************************************/ /* */ /* We will begin by generating a sorted table of edges for the */ @@ -993,6 +1054,9 @@ FT_Int ee; + if ( seg->height < segment_length_threshold ) + continue; + /* look for an edge corresponding to the segment */ for ( ee = 0; ee < axis->num_edges; ee++ ) { @@ -1110,9 +1174,11 @@ /* check for links -- if seg->serif is set, then seg->link must */ /* be ignored */ - is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge ); + is_serif = (FT_Bool)( seg->serif && + seg->serif->edge && + seg->serif->edge != edge ); - if ( seg->link || is_serif ) + if ( ( seg->link && seg->link->edge != NULL ) || is_serif ) { AF_Edge edge2; AF_Segment seg2; @@ -1524,6 +1590,8 @@ else { /* strong hinting process: snap the stem width to integer pixels */ + FT_Pos org_dist = dist; + dist = af_latin_snap_width( axis->widths, axis->width_count, dist ); @@ -1559,7 +1627,28 @@ dist = ( dist + 64 ) >> 1; else if ( dist < 128 ) + { + /* We only round to an integer width if the corresponding */ + /* distortion is less than 1/4 pixel. Otherwise this */ + /* makes everything worse since the diagonals, which are */ + /* not hinted, appear a lot bolder or thinner than the */ + /* vertical stems. */ + + FT_Int delta; + + dist = ( dist + 22 ) & ~63; + delta = dist - org_dist; + if ( delta < 0 ) + delta = -delta; + + if (delta >= 16) + { + dist = org_dist; + if ( dist < 48 ) + dist = ( dist + 64 ) >> 1; + } + } else /* round otherwise to prevent color fringes in LCD mode */ dist = ( dist + 32 ) & ~63; @@ -1592,6 +1681,11 @@ stem_edge->pos = base_edge->pos + fitted_width; + + AF_LOG(( "LINK: edge %d (opos=%.2f) linked to (%.2f), " + "dist was %.2f, now %.2f\n", + stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0, + stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 )); } @@ -1633,7 +1727,7 @@ /* we begin by aligning all stems relative to the blue zone */ /* if needed -- that's only for horizontal edges */ - if ( dim == AF_DIMENSION_VERT ) + if ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_BLUES( hints ) ) { for ( edge = edges; edge < edge_limit; edge++ ) { @@ -1662,6 +1756,11 @@ if ( !edge1 ) continue; + AF_LOG(( "BLUE: edge %d (opos=%.2f) snapped to (%.2f), " + "was (%.2f)\n", + edge1-edges, edge1->opos / 64.0, blue->fit / 64.0, + edge1->pos / 64.0 )); + edge1->pos = blue->fit; edge1->flags |= AF_EDGE_DONE; @@ -1697,8 +1796,10 @@ /* now align the stem */ /* this should not happen, but it's better to be safe */ - if ( edge2->blue_edge || edge2 < edge ) + if ( edge2->blue_edge ) { + AF_LOG(( "ASSERTION FAILED for edge %d\n", edge2-edges )); + af_latin_align_linked_edge( hints, dim, edge2, edge ); edge->flags |= AF_EDGE_DONE; continue; @@ -1743,12 +1844,16 @@ cur_pos1 += d_off; edge->pos = cur_pos1 - cur_len / 2; - edge2->pos = cur_pos1 + cur_len / 2; - + edge2->pos = edge->pos + cur_len; } else edge->pos = FT_PIX_ROUND( edge->opos ); + AF_LOG(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f) " + "snapped to (%.2f) (%.2f)\n", + edge-edges, edge->opos / 64.0, + edge2-edges, edge2->opos / 64.0, + edge->pos / 64.0, edge2->pos / 64.0 )); anchor = edge; edge->flags |= AF_EDGE_DONE; @@ -1770,7 +1875,10 @@ (AF_Edge_Flags)edge->flags, (AF_Edge_Flags)edge2->flags ); - if ( cur_len < 96 ) + if ( edge2->flags & AF_EDGE_DONE ) + edge->pos = edge2->pos - cur_len; + + else if ( cur_len < 96 ) { FT_Pos u_off, d_off; @@ -1800,6 +1908,12 @@ edge->pos = cur_pos1 - cur_len / 2; edge2->pos = cur_pos1 + cur_len / 2; + + AF_LOG(( "STEM: %d (opos=%.2f) to %d (opos=%.2f) " + "snapped to (%.2f) and (%.2f)\n", + edge-edges, edge->opos / 64.0, + edge2-edges, edge2->opos / 64.0, + edge->pos / 64.0, edge2->pos / 64.0 )); } else { @@ -1824,13 +1938,23 @@ edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2; edge2->pos = edge->pos + cur_len; + + AF_LOG(( "STEM: %d (opos=%.2f) to %d (opos=%.2f) " + "snapped to (%.2f) and (%.2f)\n", + edge-edges, edge->opos / 64.0, + edge2-edges, edge2->opos / 64.0, + edge->pos / 64.0, edge2->pos / 64.0 )); } edge->flags |= AF_EDGE_DONE; edge2->flags |= AF_EDGE_DONE; if ( edge > edges && edge->pos < edge[-1].pos ) + { + AF_LOG(( "BOUND: %d (pos=%.2f) to (%.2f)\n", + edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); edge->pos = edge[-1].pos; + } } } @@ -1904,19 +2028,63 @@ */ for ( edge = edges; edge < edge_limit; edge++ ) { + FT_Pos delta; + + if ( edge->flags & AF_EDGE_DONE ) continue; + delta = 1000; + if ( edge->serif ) + { + delta = edge->serif->opos - edge->opos; + if ( delta < 0 ) + delta = -delta; + } + + if ( delta < 64 + 16 ) + { af_latin_align_serif_edge( hints, edge->serif, edge ); + AF_LOG(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f) " + "aligned to (%.2f)\n", + edge-edges, edge->opos / 64.0, + edge->serif - edges, edge->serif->opos / 64.0, + edge->pos / 64.0 )); + } else if ( !anchor ) { + AF_LOG(( "SERIF_ANCHOR: edge %d (opos=%.2f) snapped to (%.2f)\n", + edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); edge->pos = FT_PIX_ROUND( edge->opos ); anchor = edge; } else - edge->pos = anchor->pos + - FT_PIX_ROUND( edge->opos - anchor->opos ); + { + AF_Edge before, after; + + + for ( before = edge - 1; before >= edges; before-- ) + if ( before->flags & AF_EDGE_DONE ) + break; + + for ( after = edge + 1; after < edge_limit; after++ ) + if ( after->flags & AF_EDGE_DONE ) + break; + + if ( before >= edges && before < edge && + after < edge_limit && after > edge ) + edge->pos = before->pos + + FT_MulDiv( edge->opos - before->opos, + after->pos - before->pos, + after->opos - before->opos ); + else + edge->pos = anchor->pos + + FT_PIX_ROUND( edge->opos - anchor->opos ); + + AF_LOG(( "SERIF_LINK: edge %d (opos=%.2f) snapped to (%.2f)\n", + edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); + } edge->flags |= AF_EDGE_DONE; diff --git a/src/libs/freetype2/autofit/afloader.c b/src/libs/freetype2/autofit/afloader.c index 01b4f57305..5157158f98 100644 --- a/src/libs/freetype2/autofit/afloader.c +++ b/src/libs/freetype2/autofit/afloader.c @@ -30,7 +30,9 @@ FT_ZERO( loader ); af_glyph_hints_init( &loader->hints, memory ); - +#ifdef AF_DEBUG + _af_debug_hints = &loader->hints; +#endif return FT_GlyphLoader_New( memory, &loader->gloader ); } @@ -71,6 +73,9 @@ loader->face = NULL; loader->globals = NULL; +#ifdef AF_DEBUG + _af_debug_hints = NULL; +#endif FT_GlyphLoader_Done( loader->gloader ); loader->gloader = NULL; } @@ -201,6 +206,12 @@ loader->pp1.x = FT_PIX_ROUND( pp1x_uh ); loader->pp2.x = FT_PIX_ROUND( pp2x_uh ); + if ( loader->pp1.x >= new_lsb ) + loader->pp1.x -= 64; + + if ( loader->pp2.x <= pp2x_uh ) + loader->pp2.x += 64; + slot->lsb_delta = loader->pp1.x - pp1x_uh; slot->rsb_delta = loader->pp2.x - pp2x_uh; } diff --git a/src/libs/freetype2/autofit/afmodule.c b/src/libs/freetype2/autofit/afmodule.c index ee6bc1a87c..cd5e1cc218 100644 --- a/src/libs/freetype2/autofit/afmodule.c +++ b/src/libs/freetype2/autofit/afmodule.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter module implementation (body). */ /* */ -/* Copyright 2003, 2004, 2005 by */ +/* Copyright 2003, 2004, 2005, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,6 +19,14 @@ #include "afmodule.h" #include "afloader.h" +#ifdef AF_DEBUG + int _af_debug; + int _af_debug_disable_horz_hints; + int _af_debug_disable_vert_hints; + int _af_debug_disable_blue_hints; + void* _af_debug_hints; +#endif + #include FT_INTERNAL_OBJECTS_H diff --git a/src/libs/freetype2/autofit/aftypes.h b/src/libs/freetype2/autofit/aftypes.h index f6e94e1ce4..a78585d1a6 100644 --- a/src/libs/freetype2/autofit/aftypes.h +++ b/src/libs/freetype2/autofit/aftypes.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter types (specification only). */ /* */ -/* Copyright 2003, 2004, 2005, 2006 by */ +/* Copyright 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, */ @@ -59,14 +59,19 @@ FT_BEGIN_HEADER #ifdef AF_DEBUG #include <stdio.h> +#define AF_LOG( x ) do { if ( _af_debug ) printf x; } while ( 0 ) -#define AF_LOG( x ) printf x +extern int _af_debug; +extern int _af_debug_disable_horz_hints; +extern int _af_debug_disable_vert_hints; +extern int _af_debug_disable_blue_hints; +extern void* _af_debug_hints; -#else +#else /* !AF_DEBUG */ #define AF_LOG( x ) do ; while ( 0 ) /* nothing */ -#endif /* AF_DEBUG */ +#endif /* !AF_DEBUG */ /*************************************************************************/ @@ -118,6 +123,7 @@ FT_BEGIN_HEADER #define AF_ANGLE_PI4 ( AF_ANGLE_PI / 4 ) +#if 0 /* * compute the angle of a given 2-D vector */ @@ -126,7 +132,6 @@ FT_BEGIN_HEADER FT_Pos dy ); -#if 0 /* * compute `angle2 - angle1'; the result is always within * the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1] diff --git a/src/libs/freetype2/base/Jamfile b/src/libs/freetype2/base/Jamfile index 9e1c18f340..d1571d4d17 100644 --- a/src/libs/freetype2/base/Jamfile +++ b/src/libs/freetype2/base/Jamfile @@ -38,7 +38,7 @@ UseFreeTypeHeaders ; local _sources = system init glyph mm bdf bbox debug xf86 type1 pfr stroke winfnt otval bitmap synth - gxval + gxval lcdfil gasp ; FT2_Library $(FT2_LIB) : ft$(_sources).c ; diff --git a/src/libs/freetype2/base/ftapi.c b/src/libs/freetype2/base/ftapi.c index 1ef3005e28..8914d1f4e9 100644 --- a/src/libs/freetype2/base/ftapi.c +++ b/src/libs/freetype2/base/ftapi.c @@ -49,7 +49,7 @@ FT_UNUSED( library ); FT_Stream_OpenMemory( stream, base, size ); - } + } FT_BASE_DEF( FT_Error ) @@ -57,7 +57,7 @@ FT_ULong pos ) { return FT_Stream_Seek( stream, pos ); - } + } FT_BASE_DEF( FT_Error ) @@ -65,7 +65,7 @@ FT_Long distance ) { return FT_Stream_Skip( stream, distance ); - } + } FT_BASE_DEF( FT_Error ) @@ -74,7 +74,7 @@ FT_ULong count ) { return FT_Stream_Read( stream, buffer, count ); - } + } FT_BASE_DEF( FT_Error ) @@ -84,7 +84,7 @@ FT_ULong count ) { return FT_Stream_ReadAt( stream, pos, buffer, count ); - } + } FT_BASE_DEF( FT_Error ) @@ -93,7 +93,7 @@ FT_Byte** pbytes ) { return FT_Stream_ExtractFrame( stream, count, pbytes ); - } + } FT_BASE_DEF( void ) @@ -101,14 +101,14 @@ FT_Byte** pbytes ) { FT_Stream_ReleaseFrame( stream, pbytes ); - } + } FT_BASE_DEF( FT_Error ) FT_Access_Frame( FT_Stream stream, FT_ULong count ) { return FT_Stream_EnterFrame( stream, count ); - } + } FT_BASE_DEF( void ) @@ -116,6 +116,6 @@ { FT_Stream_ExitFrame( stream ); } - + /* END */ diff --git a/src/libs/freetype2/base/ftbase.c b/src/libs/freetype2/base/ftbase.c index 7d5a7fd8e8..b3b5d1da2d 100644 --- a/src/libs/freetype2/base/ftbase.c +++ b/src/libs/freetype2/base/ftbase.c @@ -4,7 +4,7 @@ /* */ /* Single object library component (body only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,16 +20,16 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT -#include "ftutil.c" -#include "ftdbgmem.c" -#include "ftstream.c" #include "ftcalc.c" -#include "fttrigon.c" -#include "ftoutln.c" +#include "ftdbgmem.c" #include "ftgloadr.c" -#include "ftobjs.c" #include "ftnames.c" +#include "ftobjs.c" +#include "ftoutln.c" #include "ftrfork.c" +#include "ftstream.c" +#include "fttrigon.c" +#include "ftutil.c" #if defined( __APPLE__ ) && !defined ( DARWIN_NO_CARBON ) #include "ftmac.c" diff --git a/src/libs/freetype2/base/ftbitmap.c b/src/libs/freetype2/base/ftbitmap.c index d4709a440f..50c9382c09 100644 --- a/src/libs/freetype2/base/ftbitmap.c +++ b/src/libs/freetype2/base/ftbitmap.c @@ -5,7 +5,7 @@ /* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */ /* bitmaps into 8bpp format (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, */ @@ -104,10 +104,11 @@ int pitch; int new_pitch; FT_UInt ppb; - FT_Int i; + FT_Int i, width; unsigned char* buffer; + width = bitmap->width; pitch = bitmap->pitch; if ( pitch < 0 ) pitch = -pitch; @@ -170,15 +171,21 @@ if ( bitmap->pitch > 0 ) { + FT_Int len = ( width + ppb - 1 ) / ppb; + + for ( i = 0; i < bitmap->rows; i++ ) FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ), - bitmap->buffer + pitch * i, pitch ); + bitmap->buffer + pitch * i, len ); } else { + FT_Int len = ( width + ppb - 1 ) / ppb; + + for ( i = 0; i < bitmap->rows; i++ ) FT_MEM_COPY( buffer + new_pitch * i, - bitmap->buffer + pitch * i, pitch ); + bitmap->buffer + pitch * i, len ); } FT_FREE( bitmap->buffer ); diff --git a/src/libs/freetype2/base/ftcalc.c b/src/libs/freetype2/base/ftcalc.c index ba3d089355..b7fb78199d 100644 --- a/src/libs/freetype2/base/ftcalc.c +++ b/src/libs/freetype2/base/ftcalc.c @@ -159,7 +159,7 @@ } -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER /* documentation is in ftcalc.h */ @@ -183,7 +183,7 @@ return ( s > 0 ) ? d : -d; } -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#endif /* TT_USE_BYTECODE_INTERPRETER */ /* documentation is in freetype.h */ @@ -228,7 +228,7 @@ } -#else /* FT_LONG64 */ +#else /* !FT_LONG64 */ static void @@ -302,12 +302,11 @@ FT_Int64* y, FT_Int64 *z ) { - register FT_UInt32 lo, hi, max; + register FT_UInt32 lo, hi; - max = x->lo > y->lo ? x->lo : y->lo; - lo = x->lo + y->lo; - hi = x->hi + y->hi + ( lo < max ); + lo = x->lo + y->lo; + hi = x->hi + y->hi + ( lo < x->lo ); z->lo = lo; z->hi = hi; @@ -316,6 +315,23 @@ /* documentation is in freetype.h */ + /* The FT_MulDiv function has been optimized thanks to ideas from */ + /* Graham Asher. The trick is to optimize computation when everything */ + /* fits within 32-bits (a rather common case). */ + /* */ + /* we compute 'a*b+c/2', then divide it by 'c'. (positive values) */ + /* */ + /* 46340 is FLOOR(SQRT(2^31-1)). */ + /* */ + /* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */ + /* */ + /* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */ + /* */ + /* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */ + /* */ + /* and 2*0x157F0 = 176096 */ + /* */ + FT_EXPORT_DEF( FT_Long ) FT_MulDiv( FT_Long a, FT_Long b, @@ -353,7 +369,7 @@ } -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER FT_BASE_DEF( FT_Long ) FT_MulDiv_No_Round( FT_Long a, @@ -387,7 +403,7 @@ return ( s < 0 ? -a : a ); } -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#endif /* TT_USE_BYTECODE_INTERPRETER */ /* documentation is in freetype.h */ @@ -396,7 +412,32 @@ FT_MulFix( FT_Long a, FT_Long b ) { -#if 1 + /* use inline assembly to speed up things a bit */ + +#if defined( __GNUC__ ) && defined( i386 ) + + FT_Long result; + + + __asm__ __volatile__ ( + "imul %%edx\n" + "movl %%edx, %%ecx\n" + "sarl $31, %%ecx\n" + "addl $0x8000, %%ecx\n" + "addl %%ecx, %%eax\n" + "adcl $0, %%edx\n" + "shrl $16, %%eax\n" + "shll $16, %%edx\n" + "addl %%edx, %%eax\n" + "mov %%eax, %0\n" + : "=r"(result) + : "a"(a), "d"(b) + : "%ecx" + ); + return result; + +#elif 1 + FT_Long sa, sb; FT_ULong ua, ub; @@ -405,24 +446,22 @@ return a; sa = ( a >> ( sizeof ( a ) * 8 - 1 ) ); - a = ( a ^ sa ) - sa; + a = ( a ^ sa ) - sa; sb = ( b >> ( sizeof ( b ) * 8 - 1 ) ); - b = ( b ^ sb ) - sb; + b = ( b ^ sb ) - sb; ua = (FT_ULong)a; ub = (FT_ULong)b; if ( ua <= 2048 && ub <= 1048576L ) - { - ua = ( ua * ub + 0x8000 ) >> 16; - } + ua = ( ua * ub + 0x8000U ) >> 16; else { - FT_ULong al = ua & 0xFFFF; + FT_ULong al = ua & 0xFFFFU; ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + - ( ( al * ( ub & 0xFFFF ) + 0x8000 ) >> 16 ); + ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 ); } sa ^= sb, @@ -439,23 +478,21 @@ if ( a == 0 || b == 0x10000L ) return a; - s = a; a = FT_ABS(a); - s ^= b; b = FT_ABS(b); + s = a; a = FT_ABS( a ); + s ^= b; b = FT_ABS( b ); ua = (FT_ULong)a; ub = (FT_ULong)b; if ( ua <= 2048 && ub <= 1048576L ) - { - ua = ( ua * ub + 0x8000L ) >> 16; - } + ua = ( ua * ub + 0x8000UL ) >> 16; else { - FT_ULong al = ua & 0xFFFFL; + FT_ULong al = ua & 0xFFFFUL; ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + - ( ( al * ( ub & 0xFFFFL ) + 0x8000L ) >> 16 ); + ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 ); } return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua ); @@ -531,7 +568,7 @@ /* apparently, the second version of this code is not compiled correctly */ - /* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */ + /* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */ #if 1 @@ -568,7 +605,7 @@ if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */ return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL ); /* Return Max/Min Int32 if division overflow. */ - /* This includes division by zero! */ + /* This includes division by zero! */ q = 0; for ( i = 0; i < 32; i++ ) { @@ -664,4 +701,123 @@ } + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Int ) + ft_corner_orientation( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ) + { + FT_Int result; + + + /* deal with the trivial cases quickly */ + if ( in_y == 0 ) + { + if ( in_x >= 0 ) + result = out_y; + else + result = -out_y; + } + else if ( in_x == 0 ) + { + if ( in_y >= 0 ) + result = -out_x; + else + result = out_x; + } + else if ( out_y == 0 ) + { + if ( out_x >= 0 ) + result = in_y; + else + result = -in_y; + } + else if ( out_x == 0 ) + { + if ( out_y >= 0 ) + result = -in_x; + else + result = in_x; + } + else /* general case */ + { + +#ifdef FT_LONG64 + + FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x; + + + if ( delta == 0 ) + result = 0; + else + result = 1 - 2 * ( delta < 0 ); + +#else + + FT_Int64 z1, z2; + + + ft_multo64( in_x, out_y, &z1 ); + ft_multo64( in_y, out_x, &z2 ); + + if ( z1.hi > z2.hi ) + result = +1; + else if ( z1.hi < z2.hi ) + result = -1; + else if ( z1.lo > z2.lo ) + result = +1; + else if ( z1.lo < z2.lo ) + result = -1; + else + result = 0; + +#endif + } + + return result; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Int ) + ft_corner_is_flat( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ) + { + FT_Pos ax = in_x; + FT_Pos ay = in_y; + + FT_Pos d_in, d_out, d_corner; + + + if ( ax < 0 ) + ax = -ax; + if ( ay < 0 ) + ay = -ay; + d_in = ax + ay; + + ax = out_x; + if ( ax < 0 ) + ax = -ax; + ay = out_y; + if ( ay < 0 ) + ay = -ay; + d_out = ax + ay; + + ax = out_x + in_x; + if ( ax < 0 ) + ax = -ax; + ay = out_y + in_y; + if ( ay < 0 ) + ay = -ay; + d_corner = ax + ay; + + return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); + } + + /* END */ diff --git a/src/libs/freetype2/base/ftdbgmem.c b/src/libs/freetype2/base/ftdbgmem.c index 7ebb141242..52a5c2057f 100644 --- a/src/libs/freetype2/base/ftdbgmem.c +++ b/src/libs/freetype2/base/ftdbgmem.c @@ -460,7 +460,9 @@ FT_MemSource node, *pnode; - hash = (FT_UInt32)(void*)_ft_debug_file + + /* cast to FT_PtrDist first since void* can be larger */ + /* than FT_UInt32 and GCC 4.1.1 emits a warning */ + hash = (FT_UInt32)(FT_PtrDist)(void*)_ft_debug_file + (FT_UInt32)( 5 * _ft_debug_lineno ); pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS]; diff --git a/src/libs/freetype2/base/ftgasp.c b/src/libs/freetype2/base/ftgasp.c new file mode 100644 index 0000000000..8485d29259 --- /dev/null +++ b/src/libs/freetype2/base/ftgasp.c @@ -0,0 +1,61 @@ +/***************************************************************************/ +/* */ +/* ftgasp.c */ +/* */ +/* Access of TrueType's `gasp' table (body). */ +/* */ +/* Copyright 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* 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_GASP_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + + FT_EXPORT_DEF( FT_Int ) + FT_Get_Gasp( FT_Face face, + FT_UInt ppem ) + { + FT_Int result = FT_GASP_NO_TABLE; + + + if ( face && FT_IS_SFNT( face ) ) + { + TT_Face ttface = (TT_Face)face; + + + if ( ttface->gasp.numRanges > 0 ) + { + TT_GaspRange range = ttface->gasp.gaspRanges; + TT_GaspRange range_end = range + ttface->gasp.numRanges; + + + while ( ppem > range->maxPPEM ) + { + range++; + if ( range >= range_end ) + goto Exit; + } + + result = range->gaspFlag; + + /* ensure that we don't have spurious bits */ + if ( ttface->gasp.version == 0 ) + result &= 3; + } + } + Exit: + return result; + } + + +/* END */ diff --git a/src/libs/freetype2/base/ftgloadr.c b/src/libs/freetype2/base/ftgloadr.c index 81ecd8e373..ab52621ea6 100644 --- a/src/libs/freetype2/base/ftgloadr.c +++ b/src/libs/freetype2/base/ftgloadr.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph loader (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -112,6 +112,8 @@ FT_FREE( loader->base.extra_points ); FT_FREE( loader->base.subglyphs ); + loader->base.extra_points2 = NULL; + loader->max_points = 0; loader->max_contours = 0; loader->max_subglyphs = 0; @@ -149,8 +151,13 @@ /* handle extra points table - if any */ if ( loader->use_extra ) - loader->current.extra_points = - loader->base.extra_points + base->n_points; + { + loader->current.extra_points = loader->base.extra_points + + base->n_points; + + loader->current.extra_points2 = loader->base.extra_points2 + + base->n_points; + } } @@ -161,9 +168,12 @@ FT_Memory memory = loader->memory; - if ( !FT_NEW_ARRAY( loader->base.extra_points, loader->max_points ) ) + if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) ) { - loader->use_extra = 1; + loader->use_extra = 1; + loader->base.extra_points2 = loader->base.extra_points + + loader->max_points; + FT_GlyphLoader_Adjust_Points( loader ); } return error; @@ -212,9 +222,18 @@ FT_RENEW_ARRAY( base->tags, old_max, new_max ) ) goto Exit; - if ( loader->use_extra && - FT_RENEW_ARRAY( loader->base.extra_points, old_max, new_max ) ) - goto Exit; + if ( loader->use_extra ) + { + if ( FT_RENEW_ARRAY( loader->base.extra_points, + old_max * 2, new_max * 2 ) ) + goto Exit; + + FT_ARRAY_MOVE( loader->base.extra_points + new_max, + loader->base.extra_points + old_max, + old_max ); + + loader->base.extra_points2 = loader->base.extra_points + new_max; + } adjust = 1; loader->max_points = new_max; @@ -355,8 +374,12 @@ /* do we need to copy the extra points? */ if ( target->use_extra && source->use_extra ) + { FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points, num_points ); + FT_ARRAY_COPY( target->base.extra_points2, source->base.extra_points2, + num_points ); + } out->n_points = (short)num_points; out->n_contours = (short)num_contours; diff --git a/src/libs/freetype2/base/ftgxval.c b/src/libs/freetype2/base/ftgxval.c index 615e5ed6f5..32662bed87 100644 --- a/src/libs/freetype2/base/ftgxval.c +++ b/src/libs/freetype2/base/ftgxval.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating TrueTyepGX/AAT tables (body). */ /* */ -/* Copyright 2004, 2005 by */ +/* Copyright 2004, 2005, 2006 by */ /* Masatake YAMATO, Redhat K.K, */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -62,7 +62,7 @@ tables, table_length ); else - error = FT_Err_Invalid_Argument; + error = FT_Err_Unimplemented_Feature; Exit: return error; @@ -108,7 +108,7 @@ validation_flags, ckern_table ); else - error = FT_Err_Invalid_Argument; + error = FT_Err_Unimplemented_Feature; Exit: return error; diff --git a/src/libs/freetype2/base/ftlcdfil.c b/src/libs/freetype2/base/ftlcdfil.c new file mode 100644 index 0000000000..f40bbeae5f --- /dev/null +++ b/src/libs/freetype2/base/ftlcdfil.c @@ -0,0 +1,351 @@ +/***************************************************************************/ +/* */ +/* ftlcdfil.c */ +/* */ +/* FreeType API for color filtering of subpixel bitmap glyphs (body). */ +/* */ +/* Copyright 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* 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_LCD_FILTER_H +#include FT_IMAGE_H +#include FT_INTERNAL_OBJECTS_H + + +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + +/* define USE_LEGACY to implement the legacy filter */ +#define USE_LEGACY + + /* FIR filter used by the default and light filters */ + static void + _ft_lcd_filter_fir( FT_Bitmap* bitmap, + FT_Render_Mode mode, + FT_Library library ) + { + FT_Byte* weights = library->lcd_weights; + FT_UInt width = (FT_UInt)bitmap->width; + FT_UInt height = (FT_UInt)bitmap->rows; + + + /* horizontal in-place FIR filter */ + if ( mode == FT_RENDER_MODE_LCD && width >= 4 ) + { + FT_Byte* line = bitmap->buffer; + + + for ( ; height > 0; height--, line += bitmap->pitch ) + { + FT_UInt fir[5]; + FT_UInt val1, xx; + + + val1 = line[0]; + fir[0] = weights[2] * val1; + fir[1] = weights[3] * val1; + fir[2] = weights[4] * val1; + fir[3] = 0; + fir[4] = 0; + + val1 = line[1]; + fir[0] += weights[1] * val1; + fir[1] += weights[2] * val1; + fir[2] += weights[3] * val1; + fir[3] += weights[4] * val1; + + for ( xx = 2; xx < width; xx++ ) + { + FT_UInt val, pix; + + + val = line[xx]; + pix = fir[0] + weights[0] * val; + fir[0] = fir[1] + weights[1] * val; + fir[1] = fir[2] + weights[2] * val; + fir[2] = fir[3] + weights[3] * val; + fir[3] = weights[4] * val; + + pix >>= 8; + pix |= -( pix >> 8 ); + line[xx - 2] = (FT_Byte)pix; + } + + { + FT_UInt pix; + + + pix = fir[0] >> 8; + pix |= -( pix >> 8 ); + line[xx - 2] = (FT_Byte)pix; + + pix = fir[1] >> 8; + pix |= -( pix >> 8 ); + line[xx - 1] = (FT_Byte)pix; + } + } + } + + /* vertical in-place FIR filter */ + else if ( mode == FT_RENDER_MODE_LCD_V && height >= 4 ) + { + FT_Byte* column = bitmap->buffer; + FT_Int pitch = bitmap->pitch; + + + for ( ; width > 0; width--, column++ ) + { + FT_Byte* col = column; + FT_UInt fir[5]; + FT_UInt val1, yy; + + + val1 = col[0]; + fir[0] = weights[2] * val1; + fir[1] = weights[3] * val1; + fir[2] = weights[4] * val1; + fir[3] = 0; + fir[4] = 0; + col += pitch; + + val1 = col[0]; + fir[0] += weights[1] * val1; + fir[1] += weights[2] * val1; + fir[2] += weights[3] * val1; + fir[3] += weights[4] * val1; + col += pitch; + + for ( yy = 2; yy < height; yy++ ) + { + FT_UInt val, pix; + + + val = col[0]; + pix = fir[0] + weights[0] * val; + fir[0] = fir[1] + weights[1] * val; + fir[1] = fir[2] + weights[2] * val; + fir[2] = fir[3] + weights[3] * val; + fir[3] = weights[4] * val; + + pix >>= 8; + pix |= -( pix >> 8 ); + col[-2 * pitch] = (FT_Byte)pix; + col += pitch; + } + + { + FT_UInt pix; + + + pix = fir[0] >> 8; + pix |= -( pix >> 8 ); + col[-2 * pitch] = (FT_Byte)pix; + + pix = fir[1] >> 8; + pix |= -( pix >> 8 ); + col[-pitch] = (FT_Byte)pix; + } + } + } + } + + +#ifdef USE_LEGACY + + /* FIR filter used by the default and light filters */ + static void + _ft_lcd_filter_legacy( FT_Bitmap* bitmap, + FT_Render_Mode mode, + FT_Library library ) + { + FT_UInt width = (FT_UInt)bitmap->width; + FT_UInt height = (FT_UInt)bitmap->rows; + FT_Int pitch = bitmap->pitch; + + static const int filters[3][3] = + { + { 65538 * 9/13, 65538 * 1/6, 65538 * 1/13 }, + { 65538 * 3/13, 65538 * 4/6, 65538 * 3/13 }, + { 65538 * 1/13, 65538 * 1/6, 65538 * 9/13 } + }; + + FT_UNUSED( library ); + + + /* horizontal in-place FIR filter */ + if ( mode == FT_RENDER_MODE_LCD && width >= 3 ) + { + FT_Byte* line = bitmap->buffer; + + + for ( ; height > 0; height--, line += pitch ) + { + FT_UInt xx; + + + for ( xx = 0; xx < width; xx += 3 ) + { + FT_UInt r = 0; + FT_UInt g = 0; + FT_UInt b = 0; + FT_UInt p; + + + p = line[xx]; + r += filters[0][0] * p; + g += filters[0][1] * p; + b += filters[0][2] * p; + + p = line[xx + 1]; + r += filters[1][0] * p; + g += filters[1][1] * p; + b += filters[1][2] * p; + + p = line[xx + 2]; + r += filters[2][0] * p; + g += filters[2][1] * p; + b += filters[2][2] * p; + + line[xx] = (FT_Byte)( r / 65536 ); + line[xx + 1] = (FT_Byte)( g / 65536 ); + line[xx + 2] = (FT_Byte)( b / 65536 ); + } + } + } + else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 ) + { + FT_Byte* column = bitmap->buffer; + + + for ( ; width > 0; width--, column++ ) + { + FT_Byte* col = column; + FT_Byte* col_end = col + height * pitch; + + + for ( ; col < col_end; col += 3 * pitch ) + { + FT_UInt r = 0; + FT_UInt g = 0; + FT_UInt b = 0; + FT_UInt p; + + + p = col[0]; + r += filters[0][0] * p; + g += filters[0][1] * p; + b += filters[0][2] * p; + + p = col[pitch]; + r += filters[1][0] * p; + g += filters[1][1] * p; + b += filters[1][2] * p; + + p = col[pitch * 2]; + r += filters[2][0] * p; + g += filters[2][1] * p; + b += filters[2][2] * p; + + col[0] = (FT_Byte)( r / 65536 ); + col[pitch] = (FT_Byte)( g / 65536 ); + col[2 * pitch] = (FT_Byte)( b / 65536 ); + } + } + } + } + +#endif /* USE_LEGACY */ + + + FT_EXPORT( FT_Error ) + FT_Library_SetLcdFilter( FT_Library library, + FT_LcdFilter filter ) + { + static const FT_Byte light_filter[5] = + { 0, 85, 86, 85, 0 }; + /* the values here sum up to a value larger than 256, */ + /* providing a cheap gamma correction */ + static const FT_Byte default_filter[5] = + { 0x10, 0x40, 0x70, 0x40, 0x10 }; + + + if ( library == NULL ) + return FT_Err_Invalid_Argument; + + switch ( filter ) + { + case FT_LCD_FILTER_NONE: + library->lcd_filter_func = NULL; + library->lcd_extra = 0; + break; + + case FT_LCD_FILTER_DEFAULT: +#if defined( FT_FORCE_LEGACY_LCD_FILTER ) + + library->lcd_filter_func = _ft_lcd_filter_legacy; + library->lcd_extra = 0; + +#elif defined( FT_FORCE_LIGHT_LCD_FILTER ) + + memcpy( library->lcd_weights, light_filter, 5 ); + library->lcd_filter_func = _ft_lcd_filter_fir; + library->lcd_extra = 2; + +#else + + memcpy( library->lcd_weights, default_filter, 5 ); + library->lcd_filter_func = _ft_lcd_filter_fir; + library->lcd_extra = 2; + +#endif + + break; + + case FT_LCD_FILTER_LIGHT: + memcpy( library->lcd_weights, light_filter, 5 ); + library->lcd_filter_func = _ft_lcd_filter_fir; + library->lcd_extra = 2; + break; + +#ifdef USE_LEGACY + + case FT_LCD_FILTER_LEGACY: + library->lcd_filter_func = _ft_lcd_filter_legacy; + library->lcd_extra = 0; + break; + +#endif + + default: + return FT_Err_Invalid_Argument; + } + + library->lcd_filter = filter; + return 0; + } + +#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + FT_EXPORT( FT_Error ) + FT_Library_SetLcdFilter( FT_Library library, + FT_LcdFilter filter ) + { + FT_UNUSED( library ); + FT_UNUSED( filter ); + + return FT_Err_Unimplemented_Feature; + } + +#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + +/* END */ diff --git a/src/libs/freetype2/base/ftmac.c b/src/libs/freetype2/base/ftmac.c index 6e4cbe577b..ea47caaf27 100644 --- a/src/libs/freetype2/base/ftmac.c +++ b/src/libs/freetype2/base/ftmac.c @@ -3,7 +3,10 @@ /* ftmac.c */ /* */ /* Mac FOND support. Written by just@letterror.com. */ -/* Heavily Fixed by mpsuzuki, George Williams and Sean McBride */ +/* Heavily modified by mpsuzuki, George Williams, and Sean McBride. */ +/* */ +/* 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 by */ /* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ @@ -53,6 +56,12 @@ - If there is a TrueType font (an `sfnt' resource), read it into memory, wrap it into a memory stream, load the TrueType driver and delegate the rest of the work to it, by calling FT_Open_Face(). + + - Some suitcase fonts (notably Onyx) might point the `LWFN' file to + itself, even though it doesn't contains `POST' resources. To handle + this special case without opening the file an extra time, we just + ignore errors from the `LWFN' and fallback to the `sfnt' if both are + available. */ @@ -60,67 +69,25 @@ #include FT_FREETYPE_H #include FT_INTERNAL_STREAM_H -#if defined( __GNUC__ ) || defined( __IBMC__ ) /* This is for Mac OS X. Without redefinition, OS_INLINE */ /* expands to `static inline' which doesn't survive the */ /* -ansi compilation flag of GCC. */ +#undef OS_INLINE #define OS_INLINE static __inline__ #include <Carbon/Carbon.h> -#else -#include <Resources.h> -#include <Fonts.h> -#include <Errors.h> -#include <Files.h> -#include <TextUtils.h> -#endif - -#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO -#include <FSp_fopen.h> -#endif - -#include FT_MAC_H - - - /* FSSpec functions are deprecated since Mac OS X 10.4 */ -#ifndef HAVE_FSSPEC -#if TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON -#define HAVE_FSSPEC 1 -#else -#define HAVE_FSSPEC 0 -#endif -#endif - - /* most FSRef functions were introduced since Mac OS 9 */ -#ifndef HAVE_FSREF -#if TARGET_API_MAC_OSX -#define HAVE_FSREF 1 -#else -#define HAVE_FSREF 0 -#endif -#endif #ifndef HFS_MAXPATHLEN #define HFS_MAXPATHLEN 1024 #endif - /* QuickDraw is deprecated since Mac OS X 10.4 */ -#ifndef HAVE_QUICKDRAW_CARBON -#if TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON -#define HAVE_QUICKDRAW_CARBON 1 -#else -#define HAVE_QUICKDRAW_CARBON 0 -#endif -#endif +#include FT_MAC_H + + /* 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_FSSpec( a, b, c, d ) - /* AppleTypeService is available since Mac OS X */ -#ifndef HAVE_ATS -#if TARGET_API_MAC_OSX -#define HAVE_ATS 1 -#else -#define HAVE_ATS 0 -#endif -#endif /* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over TrueType in case *both* are available (this is not common, @@ -130,8 +97,6 @@ #endif -#if !HAVE_QUICKDRAW_CARBON /* QuickDraw is deprecated since Mac OS X 10.4 */ - FT_EXPORT_DEF( FT_Error ) FT_GetFile_From_Mac_Name( const char* fontName, FSSpec* pathSpec, @@ -140,106 +105,6 @@ return FT_Err_Unimplemented_Feature; } -#else - - FT_EXPORT_DEF( FT_Error ) - FT_GetFile_From_Mac_Name( const char* fontName, - FSSpec* pathSpec, - FT_Long* face_index ) - { - OptionBits options = kFMUseGlobalScopeOption; - - FMFontFamilyIterator famIter; - OSStatus status = FMCreateFontFamilyIterator( NULL, NULL, - options, - &famIter ); - FMFont the_font = 0; - FMFontFamily family = 0; - - - *face_index = 0; - while ( status == 0 && !the_font ) - { - status = FMGetNextFontFamily( &famIter, &family ); - if ( status == 0 ) - { - int stat2; - FMFontFamilyInstanceIterator instIter; - Str255 famNameStr; - char famName[256]; - - - /* get the family name */ - FMGetFontFamilyName( family, famNameStr ); - CopyPascalStringToC( famNameStr, famName ); - - /* iterate through the styles */ - FMCreateFontFamilyInstanceIterator( family, &instIter ); - - *face_index = 0; - stat2 = 0; - - while ( stat2 == 0 && !the_font ) - { - FMFontStyle style; - FMFontSize size; - FMFont font; - - - stat2 = FMGetNextFontFamilyInstance( &instIter, &font, - &style, &size ); - if ( stat2 == 0 && size == 0 ) - { - char fullName[256]; - - - /* build up a complete face name */ - ft_strcpy( fullName, famName ); - if ( style & bold ) - ft_strcat( fullName, " Bold" ); - if ( style & italic ) - ft_strcat( fullName, " Italic" ); - - /* compare with the name we are looking for */ - if ( ft_strcmp( fullName, fontName ) == 0 ) - { - /* found it! */ - the_font = font; - } - else - ++(*face_index); - } - } - - FMDisposeFontFamilyInstanceIterator( &instIter ); - } - } - - FMDisposeFontFamilyIterator( &famIter ); - - if ( the_font ) - { - FMGetFontContainer( the_font, pathSpec ); - return FT_Err_Ok; - } - else - return FT_Err_Unknown_File_Format; - } - -#endif /* HAVE_QUICKDRAW_CARBON */ - - -#if !HAVE_ATS - - FT_EXPORT_DEF( FT_Error ) - FT_GetFile_From_Mac_ATS_Name( const char* fontName, - FSSpec* pathSpec, - FT_Long* face_index ) - { - return FT_Err_Unimplemented_Feature; - } - -#else FT_EXPORT_DEF( FT_Error ) FT_GetFile_From_Mac_ATS_Name( const char* fontName, @@ -287,143 +152,11 @@ return FT_Err_Ok; } -#endif /* HAVE_ATS */ - - -#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO - -#define STREAM_FILE( stream ) ( (FT_FILE*)stream->descriptor.pointer ) - - - FT_CALLBACK_DEF( void ) - ft_FSp_stream_close( FT_Stream stream ) - { - ft_fclose( STREAM_FILE( stream ) ); - - stream->descriptor.pointer = NULL; - stream->size = 0; - stream->base = 0; - } - - - FT_CALLBACK_DEF( unsigned long ) - ft_FSp_stream_io( FT_Stream stream, - unsigned long offset, - unsigned char* buffer, - unsigned long count ) - { - FT_FILE* file; - - - file = STREAM_FILE( stream ); - - ft_fseek( file, offset, SEEK_SET ); - - return (unsigned long)ft_fread( buffer, 1, count, file ); - } - -#endif /* __MWERKS__ && !TARGET_RT_MAC_MACHO */ - - -#if HAVE_FSSPEC && !HAVE_FSREF - - static OSErr - FT_FSPathMakeSpec( const UInt8* pathname, - FSSpec* spec_p, - Boolean isDirectory ) - { - const char *p, *q; - short vRefNum; - long dirID; - Str255 nodeName; - OSErr err; - - - p = q = (const char *)pathname; - dirID = 0; - vRefNum = 0; - - while ( 1 ) - { - q = p + FT_MIN( 255, ft_strlen( p ) ); - - if ( q == p ) - return 0; - - if ( 255 < ft_strlen( (char *)pathname ) ) - { - while ( p < q && *q != ':' ) - q--; - } - - if ( p < q ) - *(char *)nodeName = q - p; - else if ( ft_strlen( p ) < 256 ) - *(char *)nodeName = ft_strlen( p ); - else - return errFSNameTooLong; - - ft_strncpy( (char *)nodeName + 1, (char *)p, *(char *)nodeName ); - err = FSMakeFSSpec( vRefNum, dirID, nodeName, spec_p ); - if ( err || '\0' == *q ) - return err; - - vRefNum = spec_p->vRefNum; - dirID = spec_p->parID; - - p = q; - } - } - - - static OSErr - FT_FSpMakePath( const FSSpec* spec_p, - UInt8* path, - UInt32 maxPathSize ) - { - OSErr err; - FSSpec spec = *spec_p; - short vRefNum; - long dirID; - Str255 parDir_name; - - - FT_MEM_SET( path, 0, maxPathSize ); - while ( 1 ) - { - int child_namelen = ft_strlen( (char *)path ); - unsigned char node_namelen = spec.name[0]; - unsigned char* node_name = spec.name + 1; - - - if ( node_namelen + child_namelen > maxPathSize ) - return errFSNameTooLong; - - FT_MEM_MOVE( path + node_namelen + 1, path, child_namelen ); - FT_MEM_COPY( path, node_name, node_namelen ); - if ( child_namelen > 0 ) - path[node_namelen] = ':'; - - vRefNum = spec.vRefNum; - dirID = spec.parID; - parDir_name[0] = '\0'; - err = FSMakeFSSpec( vRefNum, dirID, parDir_name, &spec ); - if ( noErr != err || dirID == spec.parID ) - break; - } - return noErr; - } - -#endif /* HAVE_FSSPEC && !HAVE_FSREF */ - static OSErr FT_FSPathMakeRes( const UInt8* pathname, short* res ) { - -#if HAVE_FSREF - OSErr err; FSRef ref; @@ -440,22 +173,6 @@ *res = FSOpenResFile( &ref, fsRdPerm ); err = ResError(); -#else - - OSErr err; - FSSpec spec; - - - if ( noErr != FT_FSPathMakeSpec( pathname, &spec, FALSE ) ) - return FT_Err_Cannot_Open_Resource; - - /* at present, no support for dfont format without FSRef */ - /* (see above), try original resource-fork font */ - *res = FSpOpenResFile( &spec, fsRdPerm ); - err = ResError(); - -#endif /* HAVE_FSREF */ - return err; } @@ -464,9 +181,6 @@ static OSType get_file_type_from_path( const UInt8* pathname ) { - -#if HAVE_FSREF - FSRef ref; FSCatalogInfo info; @@ -479,23 +193,6 @@ return ( OSType ) 0; return ((FInfo *)(info.finderInfo))->fdType; - -#else - - FSSpec spec; - FInfo finfo; - - - if ( noErr != FT_FSPathMakeSpec( pathname, &spec, FALSE ) ) - return ( OSType ) 0; - - if ( noErr != FSpGetFInfo( &spec, &finfo ) ) - return ( OSType ) 0; - - return finfo.fdType; - -#endif /* HAVE_FSREF */ - } @@ -536,7 +233,8 @@ /* The count is 1 greater than the value in the FOND. */ /* Isn't that cute? :-) */ - return 1 + *( (short*)( fond_data + sizeof ( FamRec ) ) ); + return EndianS16_BtoN( *( (short*)( fond_data + + sizeof ( FamRec ) ) ) ) + 1; } @@ -549,13 +247,14 @@ fond = (FamRec*)fond_data; - face_all = *( (short *)( fond_data + sizeof ( FamRec ) ) ) + 1; + face_all = EndianS16_BtoN( *( (short *)( fond_data + + sizeof ( FamRec ) ) ) ) + 1; assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 ); face = 0; for ( i = 0; i < face_all; i++ ) { - if ( 0 == assoc[i].fontSize ) + if ( 0 == EndianS16_BtoN( assoc[i].fontSize ) ) face++; } return face; @@ -597,19 +296,19 @@ /* if the face at this index is not scalable, fall back to the first one (old behavior) */ - if ( assoc->fontSize == 0 ) + if ( EndianS16_BtoN( assoc->fontSize ) == 0 ) { *have_sfnt = 1; - *sfnt_id = assoc->fontID; + *sfnt_id = EndianS16_BtoN( assoc->fontID ); } else if ( base_assoc->fontSize == 0 ) { *have_sfnt = 1; - *sfnt_id = base_assoc->fontID; + *sfnt_id = EndianS16_BtoN( base_assoc->fontID ); } } - if ( fond->ffStylOff ) + if ( EndianS32_BtoN( fond->ffStylOff ) ) { unsigned char* p = (unsigned char*)fond_data; StyleTable* style; @@ -619,10 +318,10 @@ int i; - p += fond->ffStylOff; + p += EndianS32_BtoN( fond->ffStylOff ); style = (StyleTable*)p; p += sizeof ( StyleTable ); - string_count = *(unsigned short*)(p); + string_count = EndianS16_BtoN( *(short*)(p) ); p += sizeof ( short ); for ( i = 0; i < string_count && i < 64; i++ ) @@ -679,9 +378,6 @@ UInt8* path_lwfn, int path_size ) { - -#if HAVE_FSREF - FSRef ref, par_ref; int dirname_len; @@ -720,44 +416,6 @@ return FT_Err_Cannot_Open_Resource; return FT_Err_Ok; - -#else - - int i; - FSSpec spec; - - - /* pathname for FSSpec is always HFS format */ - if ( ft_strlen( (char *)path_fond ) > path_size ) - return FT_Err_Invalid_Argument; - - ft_strcpy( (char *)path_lwfn, (char *)path_fond ); - - i = ft_strlen( (char *)path_lwfn ) - 1; - while ( i > 0 && ':' != path_lwfn[i] ) - i--; - - if ( i + 1 + base_lwfn[0] > path_size ) - return FT_Err_Invalid_Argument; - - if ( ':' == path_lwfn[i] ) - { - ft_strcpy( (char *)path_lwfn + i + 1, (char *)base_lwfn + 1 ); - path_lwfn[i + 1 + base_lwfn[0]] = '\0'; - } - else - { - ft_strcpy( (char *)path_lwfn, (char *)base_lwfn + 1 ); - path_lwfn[base_lwfn[0]] = '\0'; - } - - if ( noErr != FT_FSPathMakeSpec( path_lwfn, &spec, FALSE ) ) - return FT_Err_Cannot_Open_Resource; - - return FT_Err_Ok; - -#endif /* HAVE_FSREF */ - } @@ -770,13 +428,13 @@ Str255 lwfn_file_name; UInt8 buff[HFS_MAXPATHLEN]; FT_Error err; + short num_faces; have_sfnt = have_lwfn = 0; HLock( fond ); parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 ); - HUnlock( fond ); if ( lwfn_file_name[0] ) { @@ -787,9 +445,12 @@ } if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) ) - return 1; + num_faces = 1; else - return count_faces_scalable( *fond ); + num_faces = count_faces_scalable( *fond ); + + HUnlock( fond ); + return num_faces; } @@ -1010,6 +671,8 @@ error = FT_Open_Face( library, &args, face_index, aface ); if ( error == FT_Err_Ok ) (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; + else + FT_Stream_Free( stream, 0 ); return error; } @@ -1150,7 +813,7 @@ Str255 lwfn_file_name; UInt8 path_lwfn[HFS_MAXPATHLEN]; OSErr err; - FT_Error error; + FT_Error error = FT_Err_Ok; GetResInfo( fond, &fond_id, &fond_type, fond_name ); @@ -1170,8 +833,6 @@ if ( noErr != ResError() ) goto found_no_lwfn_file; -#if HAVE_FSREF - { UInt8 path_fond[HFS_MAXPATHLEN]; FSRef ref; @@ -1191,61 +852,24 @@ if ( FT_Err_Ok == error ) have_lwfn = 1; } - -#elif HAVE_FSSPEC - - { - UInt8 path_fond[HFS_MAXPATHLEN]; - FCBPBRec pb; - Str255 fond_file_name; - FSSpec spec; - - - FT_MEM_SET( &spec, 0, sizeof ( FSSpec ) ); - FT_MEM_SET( &pb, 0, sizeof ( FCBPBRec ) ); - - pb.ioNamePtr = fond_file_name; - pb.ioVRefNum = 0; - pb.ioRefNum = res; - pb.ioFCBIndx = 0; - - err = PBGetFCBInfoSync( &pb ); - if ( noErr != err ) - goto found_no_lwfn_file; - - err = FSMakeFSSpec( pb.ioFCBVRefNum, pb.ioFCBParID, - fond_file_name, &spec ); - if ( noErr != err ) - goto found_no_lwfn_file; - - err = FT_FSpMakePath( &spec, path_fond, sizeof ( path_fond ) ); - if ( noErr != err ) - goto found_no_lwfn_file; - - error = lookup_lwfn_by_fond( path_fond, lwfn_file_name, - path_lwfn, sizeof ( path_lwfn ) ); - if ( FT_Err_Ok == error ) - have_lwfn = 1; - } - -#endif /* HAVE_FSREF, HAVE_FSSPEC */ - } if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) ) - return FT_New_Face_From_LWFN( library, - path_lwfn, - face_index, - aface ); + error = FT_New_Face_From_LWFN( library, + path_lwfn, + face_index, + aface ); + else + error = FT_Err_Unknown_File_Format; found_no_lwfn_file: - if ( have_sfnt ) - return FT_New_Face_From_SFNT( library, - sfnt_id, - face_index, - aface ); + if ( have_sfnt && FT_Err_Ok != error ) + error = FT_New_Face_From_SFNT( library, + sfnt_id, + face_index, + aface ); - return FT_Err_Unknown_File_Format; + return error; } @@ -1336,13 +960,6 @@ FT_Long face_index, FT_Face* aface ) { - -#if !HAVE_FSREF - - return FT_Err_Unimplemented_Feature; - -#else - FT_Error error; FT_Open_Args args; OSErr err; @@ -1364,9 +981,6 @@ args.flags = FT_OPEN_PATHNAME; args.pathname = (char*)pathname; return FT_Open_Face( library, &args, face_index, aface ); - -#endif /* HAVE_FSREF */ - } @@ -1385,9 +999,6 @@ FT_Long face_index, FT_Face* aface ) { - -#if HAVE_FSREF - FSRef ref; @@ -1395,37 +1006,6 @@ return FT_Err_Invalid_Argument; else return FT_New_Face_From_FSRef( library, &ref, face_index, aface ); - -#elif HAVE_FSSPEC - - FT_Error error; - FT_Open_Args args; - OSErr err; - UInt8 pathname[HFS_MAXPATHLEN]; - - - if ( !spec ) - return FT_Err_Invalid_Argument; - - err = FT_FSpMakePath( spec, pathname, sizeof ( pathname ) ); - if ( err ) - error = FT_Err_Cannot_Open_Resource; - - error = FT_New_Face_From_Resource( library, pathname, face_index, aface ); - if ( error != 0 || *aface != NULL ) - return error; - - /* fallback to datafork font */ - args.flags = FT_OPEN_PATHNAME; - args.pathname = (char*)pathname; - return FT_Open_Face( library, &args, face_index, aface ); - -#else - - return FT_Err_Unimplemented_Feature; - -#endif /* HAVE_FSREF, HAVE_FSSPEC */ - } diff --git a/src/libs/freetype2/base/ftmm.c b/src/libs/freetype2/base/ftmm.c index 940f8640a7..586d5e84db 100644 --- a/src/libs/freetype2/base/ftmm.c +++ b/src/libs/freetype2/base/ftmm.c @@ -174,7 +174,7 @@ /* documentation is in ftmm.h */ - + /* This is exactly the same as the previous function. It exists for */ /* orthogonality. */ diff --git a/src/libs/freetype2/base/ftobjs.c b/src/libs/freetype2/base/ftobjs.c index a7d82de768..7c9d312b49 100644 --- a/src/libs/freetype2/base/ftobjs.c +++ b/src/libs/freetype2/base/ftobjs.c @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -78,11 +78,10 @@ FT_BASE_DEF( FT_Int ) ft_validator_run( FT_Validator valid ) { - int result; + /* This function doesn't work! None should call it. */ + FT_UNUSED( valid ); - - result = ft_setjmp( valid->jump_buffer ); - return result; + return -1; } @@ -90,8 +89,17 @@ ft_validator_error( FT_Validator valid, FT_Error error ) { + /* since the cast below also disables the compiler's */ + /* type check, we introduce a dummy variable, which */ + /* will be optimized away */ + volatile jmp_buf* jump_buffer = &valid->jump_buffer; + + valid->error = error; - ft_longjmp( valid->jump_buffer, 1 ); + + /* throw away volatileness; use `jump_buffer' or the */ + /* compiler may warn about an unused local variable */ + ft_longjmp( *(jmp_buf*) jump_buffer, 1 ); } @@ -541,8 +549,8 @@ if ( !face || !face->size || !face->glyph ) return FT_Err_Invalid_Face_Handle; - if ( glyph_index >= (FT_UInt)face->num_glyphs ) - return FT_Err_Invalid_Argument; + /* The validity test for `glyph_index' is performed by the */ + /* font drivers. */ slot = face->glyph; ft_glyphslot_clear( slot ); @@ -565,22 +573,44 @@ load_flags &= ~FT_LOAD_RENDER; } - if ( FT_LOAD_TARGET_MODE( load_flags ) == FT_RENDER_MODE_LIGHT ) - load_flags |= FT_LOAD_FORCE_AUTOHINT; + /* + * Determine whether we need to auto-hint or not. + * The general rules are: + * + * - Do only auto-hinting if we have a hinter module, + * a scalable font format dealing with outlines, + * and no transforms except simple slants. + * + * - Then, autohint if FT_LOAD_FORCE_AUTOHINT is set + * or if we don't have a native font hinter. + * + * - Otherwise, auto-hint for LIGHT hinting mode. + * + * - Exception: The font requires the unpatented + * bytecode interpreter to load properly. + */ - /* auto-hinter is preferred and should be used */ - if ( ( !FT_DRIVER_HAS_HINTER( driver ) || - ( load_flags & FT_LOAD_FORCE_AUTOHINT ) ) && - !( load_flags & FT_LOAD_NO_HINTING ) && - !( load_flags & FT_LOAD_NO_AUTOHINT ) ) + autohint = 0; + if ( hinter && + ( load_flags & FT_LOAD_NO_HINTING ) == 0 && + ( load_flags & FT_LOAD_NO_AUTOHINT ) == 0 && + FT_DRIVER_IS_SCALABLE( driver ) && + FT_DRIVER_USES_OUTLINES( driver ) && + face->internal->transform_matrix.yy > 0 && + face->internal->transform_matrix.yx == 0 ) { - /* check whether it works for this face */ - autohint = - FT_BOOL( hinter && - FT_DRIVER_IS_SCALABLE( driver ) && - FT_DRIVER_USES_OUTLINES( driver ) && - face->internal->transform_matrix.yy > 0 && - face->internal->transform_matrix.yx == 0 ); + if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) != 0 || + !FT_DRIVER_HAS_HINTER( driver ) ) + autohint = 1; + else + { + FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); + + + if ( mode == FT_RENDER_MODE_LIGHT || + face->internal->ignore_unpatented_hinter ) + autohint = 1; + } } if ( autohint ) @@ -1341,6 +1371,7 @@ FT_Long flag_offset; FT_Long rlen; int is_cff; + FT_Long face_index_in_resource = 0; if ( face_index == -1 ) @@ -1372,7 +1403,7 @@ error = open_face_from_buffer( library, sfnt_data, rlen, - face_index, + face_index_in_resource, is_cff ? "cff" : "truetype", aface ); @@ -1414,6 +1445,9 @@ error = Mac_Read_POST_Resource( library, stream, data_offsets, count, face_index, aface ); FT_FREE( data_offsets ); + /* POST exists in an LWFN providing a single face */ + if ( !error ) + (*aface)->num_faces = 1; return error; } @@ -1423,9 +1457,14 @@ &data_offsets, &count ); if ( !error ) { + FT_Long face_index_internal = face_index % count; + + error = Mac_Read_sfnt_Resource( library, stream, data_offsets, count, - face_index, aface ); + face_index_internal, aface ); FT_FREE( data_offsets ); + if ( !error ) + (*aface)->num_faces = count; } return error; @@ -1531,7 +1570,7 @@ error = IsMacResource( library, stream2, offsets[i], face_index, aface ); - FT_Stream_Close( stream2 ); + FT_Stream_Free( stream2, 0 ); FT_TRACE3(( "%s\n", error ? "failed": "successful" )); @@ -2050,7 +2089,7 @@ FT_Match_Size( FT_Face face, FT_Size_Request req, FT_Bool ignore_width, - FT_ULong* index ) + FT_ULong* size_index ) { FT_Int i; FT_Long w, h; @@ -2084,8 +2123,8 @@ if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width ) { - if ( index ) - *index = (FT_ULong)i; + if ( size_index ) + *size_index = (FT_ULong)i; return FT_Err_Ok; } @@ -2544,6 +2583,9 @@ if ( !face ) return FT_Err_Invalid_Face_Handle; + if ( encoding == FT_ENCODING_NONE ) + return FT_Err_Invalid_Argument; + /* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */ /* charmap available, i.e., one with UCS-4 characters, if possible. */ /* */ @@ -3718,10 +3760,38 @@ if ( library->generic.finalizer ) library->generic.finalizer( library ); - /* Close all modules in the library */ + /* Close all faces in the library. If we don't do + * this, we can have some subtle memory leaks. + * Example: + * + * - the cff font driver uses the pshinter module in cff_size_done + * - if the pshinter module is destroyed before the cff font driver, + * opened FT_Face objects managed by the driver are not properly + * destroyed, resulting in a memory leak + */ + { + FT_UInt n; + + + for ( n = 0; n < library->num_modules; n++ ) + { + FT_Module module = library->modules[n]; + FT_List faces; + + + if ( ( module->clazz->module_flags & FT_MODULE_FONT_DRIVER ) == 0 ) + continue; + + faces = &FT_DRIVER(module)->faces_list; + while ( faces->head ) + FT_Done_Face( FT_FACE( faces->head->data ) ); + } + } + + /* Close all other modules in the library */ #if 1 /* XXX Modules are removed in the reversed order so that */ - /* type42 module is removed before truetype module. This */ + /* type42 module is removed before truetype module. This */ /* avoids double free in some occasions. It is a hack. */ while ( library->num_modules > 0 ) FT_Remove_Module( library, @@ -3861,7 +3931,7 @@ #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ - + FT_EXPORT_DEF( FT_Error ) FT_Get_SubGlyph_Info( FT_GlyphSlot glyph, FT_UInt sub_index, @@ -3872,14 +3942,14 @@ FT_Matrix *p_transform ) { FT_Error error = FT_Err_Invalid_Argument; - - if ( glyph != NULL && + + if ( glyph != NULL && glyph->format == FT_GLYPH_FORMAT_COMPOSITE && sub_index < glyph->num_subglyphs ) { FT_SubGlyph subg = glyph->subglyphs + sub_index; - + *p_index = subg->index; *p_flags = subg->flags; diff --git a/src/libs/freetype2/base/ftotval.c b/src/libs/freetype2/base/ftotval.c index f14580d290..b6de6db85d 100644 --- a/src/libs/freetype2/base/ftotval.c +++ b/src/libs/freetype2/base/ftotval.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating OpenType tables (body). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2006 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 @@ GSUB_table, JSTF_table ); else - error = FT_Err_Invalid_Argument; + error = FT_Err_Unimplemented_Feature; Exit: return error; diff --git a/src/libs/freetype2/base/ftoutln.c b/src/libs/freetype2/base/ftoutln.c index b23b16439c..2a35659e1a 100644 --- a/src/libs/freetype2/base/ftoutln.c +++ b/src/libs/freetype2/base/ftoutln.c @@ -4,7 +4,7 @@ /* */ /* FreeType outline management (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -732,7 +732,7 @@ return ( n % 2 ); } - + static FT_Bool ft_contour_enclosed( FT_Outline* outline, FT_UShort c ) @@ -934,7 +934,8 @@ FT_Outline_Get_Orientation( FT_Outline* outline ) { FT_Pos xmin = 32768L; - FT_Vector* xmin_point = NULL; + FT_Pos xmin_ymin = 32768L; + FT_Pos xmin_ymax = -32768L; FT_Vector* xmin_first = NULL; FT_Vector* xmin_last = NULL; @@ -943,22 +944,31 @@ FT_Vector* first; FT_Vector* last; FT_Vector* prev; - FT_Vector* next; + FT_Vector* point; + + int i; + FT_Pos ray_y[3]; + FT_Orientation result[3]; if ( !outline || outline->n_points <= 0 ) return FT_ORIENTATION_TRUETYPE; + /* We use the nonzero winding rule to find the orientation. */ + /* Since glyph outlines behave much more `regular' than arbitrary */ + /* cubic or quadratic curves, this test deals with the polygon */ + /* only which is spanned up by the control points. */ + first = outline->points; for ( contour = outline->contours; contour < outline->contours + outline->n_contours; contour++, first = last + 1 ) { - FT_Vector* point; - FT_Int on_curve; - FT_Int on_curve_count = 0; - FT_Pos tmp_xmin = 32768L; - FT_Vector* tmp_xmin_point = NULL; + FT_Pos contour_xmin = 32768L; + FT_Pos contour_xmax = -32768L; + FT_Pos contour_ymin = 32768L; + FT_Pos contour_ymax = -32768L; + last = outline->points + *contour; @@ -968,55 +978,108 @@ for ( point = first; point <= last; ++point ) { - /* Count on-curve points. If there are less than 3 on-curve */ - /* points, just bypass this contour. */ - on_curve = outline->tags[point - outline->points] & 1; - on_curve_count += on_curve; + if ( point->x < contour_xmin ) + contour_xmin = point->x; - if ( point->x < tmp_xmin && on_curve ) - { - tmp_xmin = point->x; - tmp_xmin_point = point; - } + if ( point->x > contour_xmax ) + contour_xmax = point->x; + + if ( point->y < contour_ymin ) + contour_ymin = point->y; + + if ( point->y > contour_ymax ) + contour_ymax = point->y; } - if ( on_curve_count > 2 && tmp_xmin < xmin ) + if ( contour_xmin < xmin && + contour_xmin != contour_xmax && + contour_ymin != contour_ymax ) { - xmin = tmp_xmin; - xmin_point = tmp_xmin_point; + xmin = contour_xmin; + xmin_ymin = contour_ymin; + xmin_ymax = contour_ymax; xmin_first = first; xmin_last = last; } } - if ( !xmin_point ) + if ( xmin == 32768 ) return FT_ORIENTATION_TRUETYPE; - prev = ( xmin_point == xmin_first ) ? xmin_last : xmin_point - 1; - next = ( xmin_point == xmin_last ) ? xmin_first : xmin_point + 1; + ray_y[0] = ( xmin_ymin * 3 + xmin_ymax ) >> 2; + ray_y[1] = ( xmin_ymin + xmin_ymax ) >> 1; + ray_y[2] = ( xmin_ymin + xmin_ymax * 3 ) >> 2; - /* Skip off-curve points */ - while ( ( outline->tags[prev - outline->points] & 1 ) == 0 ) + for ( i = 0; i < 3; i++ ) { - if ( prev == xmin_first ) - prev = xmin_last; - else - --prev; + FT_Pos left_x; + FT_Pos right_x; + FT_Vector* left1; + FT_Vector* left2; + FT_Vector* right1; + FT_Vector* right2; + + + RedoRay: + left_x = 32768L; + right_x = -32768L; + + left1 = left2 = right1 = right2 = NULL; + + prev = xmin_last; + for ( point = xmin_first; point <= xmin_last; prev = point, ++point ) + { + FT_Pos tmp_x; + + + if ( point->y == ray_y[i] || prev->y == ray_y[i] ) + { + ray_y[i]++; + goto RedoRay; + } + + if ( ( point->y < ray_y[i] && prev->y < ray_y[i] ) || + ( point->y > ray_y[i] && prev->y > ray_y[i] ) ) + continue; + + tmp_x = FT_MulDiv( point->x - prev->x, + ray_y[i] - prev->y, + point->y - prev->y ) + prev->x; + + if ( tmp_x < left_x ) + { + left_x = tmp_x; + left1 = prev; + left2 = point; + } + + if ( tmp_x > right_x ) + { + right_x = tmp_x; + right1 = prev; + right2 = point; + } + } + + if ( left1 && right1 ) + { + if ( left1->y < left2->y && right1->y > right2->y ) + result[i] = FT_ORIENTATION_TRUETYPE; + else if ( left1->y > left2->y && right1->y < right2->y ) + result[i] = FT_ORIENTATION_POSTSCRIPT; + else + result[i] = FT_ORIENTATION_NONE; + } } - while ( ( outline->tags[next - outline->points] & 1 ) == 0 ) - { - if ( next == xmin_last ) - next = xmin_first; - else - ++next; - } + if ( result[0] != FT_ORIENTATION_NONE && + ( result[0] == result[1] || result[0] == result[2] ) ) + return result[0]; - if ( FT_Atan2( prev->x - xmin_point->x, prev->y - xmin_point->y ) > - FT_Atan2( next->x - xmin_point->x, next->y - xmin_point->y ) ) - return FT_ORIENTATION_POSTSCRIPT; - else - return FT_ORIENTATION_TRUETYPE; + if ( result[1] != FT_ORIENTATION_NONE && result[1] == result[2] ) + return result[1]; + + return FT_ORIENTATION_TRUETYPE; } diff --git a/src/libs/freetype2/base/ftrfork.c b/src/libs/freetype2/base/ftrfork.c index cfa5891c43..a4f726d930 100644 --- a/src/libs/freetype2/base/ftrfork.c +++ b/src/libs/freetype2/base/ftrfork.c @@ -647,7 +647,7 @@ error = raccess_guess_apple_double( library, stream2, file_name, &nouse, result_offset ); - FT_Stream_Close( stream2 ); + FT_Stream_Free( stream2, 0 ); return error; } diff --git a/src/libs/freetype2/base/ftsynth.c b/src/libs/freetype2/base/ftsynth.c index 7ff2a3c38c..ff88ce96c5 100644 --- a/src/libs/freetype2/base/ftsynth.c +++ b/src/libs/freetype2/base/ftsynth.c @@ -137,8 +137,11 @@ return; } - /* assume the layout is horizontal */ - slot->advance.x += xstr; + if ( slot->advance.x ) + slot->advance.x += xstr; + + if ( slot->advance.y ) + slot->advance.y += ystr; slot->metrics.width += xstr; slot->metrics.height += ystr; diff --git a/src/libs/freetype2/base/ftutil.c b/src/libs/freetype2/base/ftutil.c index 7ad780d389..d76f5e588d 100644 --- a/src/libs/freetype2/base/ftutil.c +++ b/src/libs/freetype2/base/ftutil.c @@ -120,12 +120,16 @@ FT_Error error = FT_Err_Ok; - if ( cur_count < 0 || new_count < 0 || item_size <= 0 ) + /* Note that we now accept `item_size == 0' as a valid parameter, in + * order to cover very weird cases where an ALLOC_MULT macro would be + * called. + */ + if ( cur_count < 0 || new_count < 0 || item_size < 0 ) { /* may help catch/prevent nasty security issues */ error = FT_Err_Invalid_Argument; } - else if ( new_count == 0 ) + else if ( new_count == 0 || item_size == 0 ) { ft_mem_free( memory, block ); block = NULL; diff --git a/src/libs/freetype2/base/rules.mk b/src/libs/freetype2/base/rules.mk index bbc6cb7071..d6e441254b 100644 --- a/src/libs/freetype2/base/rules.mk +++ b/src/libs/freetype2/base/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006 by +# Copyright 1996-2000, 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, modified, @@ -32,8 +32,10 @@ BASE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SRC_DIR)/base) # # ftsystem, ftinit, and ftdebug are handled by freetype.mk # -BASE_SRC := $(BASE_DIR)/ftapi.c \ - $(BASE_DIR)/ftcalc.c \ +# All files listed here should be included in `ftbase.c' (for a `single' +# build). +# +BASE_SRC := $(BASE_DIR)/ftcalc.c \ $(BASE_DIR)/ftdbgmem.c \ $(BASE_DIR)/ftgloadr.c \ $(BASE_DIR)/ftnames.c \ diff --git a/src/libs/freetype2/bdf/README b/src/libs/freetype2/bdf/README index d45e4fb15a..e3f2ae3861 100644 --- a/src/libs/freetype2/bdf/README +++ b/src/libs/freetype2/bdf/README @@ -8,14 +8,14 @@ Introduction ************ BDF (Bitmap Distribution Format) is a bitmap font format defined by Adobe, -which is intended to be easily understood by both humans and computers. +which is intended to be easily understood by both humans and computers. This code implements a BDF driver for the FreeType library, following the Adobe Specification V 2.2. The specification of the BDF font format is available from Adobe's web site: http://partners.adobe.com/asn/developer/PDFS/TN/5005.BDF_Spec.pdf -Many good bitmap fonts in bdf format come with XFree86 (www.XFree86.org). +Many good bitmap fonts in bdf format come with XFree86 (www.XFree86.org). They do not define vertical metrics, because the X Consortium BDF specification has removed them. @@ -40,13 +40,13 @@ client application the work of interpreting them. For instance: FT_New_Face( library, ..., &face ); bdfface = (BDF_Public_Face)face; - - if ( ( bdfface->charset_registry == "ISO10646" ) && + + if ( ( bdfface->charset_registry == "ISO10646" ) && ( bdfface->charset_encoding == "1" ) ) [..] -Thus the driver always exports `ft_encoding_none' as face->charmap.encoding. +Thus the driver always exports `ft_encoding_none' as face->charmap.encoding. FT_Get_Char_Index's behavior is unmodified, that is, it converts the ULong value given as argument into the corresponding glyph number. diff --git a/src/libs/freetype2/bdf/bdf.c b/src/libs/freetype2/bdf/bdf.c index 9c828853e1..f95fb76225 100644 --- a/src/libs/freetype2/bdf/bdf.c +++ b/src/libs/freetype2/bdf/bdf.c @@ -3,7 +3,7 @@ FreeType font driver for bdf files Copyright (C) 2001, 2002 by - Francesco Zappa Nardelli + Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/libs/freetype2/bdf/bdf.h b/src/libs/freetype2/bdf/bdf.h index b42baa6e04..1b64426aad 100644 --- a/src/libs/freetype2/bdf/bdf.h +++ b/src/libs/freetype2/bdf/bdf.h @@ -161,7 +161,7 @@ FT_BEGIN_HEADER { const char* key; void* data; - + } _hashnode, *hashnode; diff --git a/src/libs/freetype2/bdf/bdfdrivr.c b/src/libs/freetype2/bdf/bdfdrivr.c index b03c8d0f85..34071481be 100644 --- a/src/libs/freetype2/bdf/bdfdrivr.c +++ b/src/libs/freetype2/bdf/bdfdrivr.c @@ -435,6 +435,8 @@ THE SOFTWARE. /* convert from 722.7 decipoints to 72 points per inch */ bsize->size = (FT_Pos)( ( prop->value.int32 * 64 * 7200 + 36135L ) / 72270L ); + else + bsize->size = bsize->width << 6; prop = bdf_get_font_property( font, "PIXEL_SIZE" ); if ( prop ) @@ -646,16 +648,17 @@ THE SOFTWARE. FT_UInt glyph_index, FT_Int32 load_flags ) { - BDF_Face face = (BDF_Face)FT_SIZE_FACE( size ); + BDF_Face bdf = (BDF_Face)FT_SIZE_FACE( size ); + FT_Face face = FT_FACE( bdf ); FT_Error error = BDF_Err_Ok; FT_Bitmap* bitmap = &slot->bitmap; bdf_glyph_t glyph; - int bpp = face->bdffont->bpp; + int bpp = bdf->bdffont->bpp; FT_UNUSED( load_flags ); - if ( !face ) + if ( !face || glyph_index >= (FT_UInt)face->num_glyphs ) { error = BDF_Err_Invalid_Argument; goto Exit; @@ -663,12 +666,12 @@ THE SOFTWARE. /* index 0 is the undefined glyph */ if ( glyph_index == 0 ) - glyph_index = face->default_glyph; + glyph_index = bdf->default_glyph; else glyph_index--; /* slot, bitmap => freetype, glyph => bdflib */ - glyph = face->bdffont->glyphs[glyph_index]; + glyph = bdf->bdffont->glyphs[glyph_index]; bitmap->rows = glyph.bbx.height; bitmap->width = glyph.bbx.width; @@ -710,7 +713,7 @@ THE SOFTWARE. * used here, provided such fonts do exist. */ ft_synthesize_vertical_metrics( &slot->metrics, - face->bdffont->bbx.height << 6 ); + bdf->bdffont->bbx.height << 6 ); Exit: return error; diff --git a/src/libs/freetype2/bdf/bdflib.c b/src/libs/freetype2/bdf/bdflib.c index 3c928e5634..fa3dd2facb 100644 --- a/src/libs/freetype2/bdf/bdflib.c +++ b/src/libs/freetype2/bdf/bdflib.c @@ -2204,7 +2204,7 @@ bdf_options_t* opts, bdf_font_t* *font ) { - unsigned long lineno; + unsigned long lineno = 0; /* make compiler happy */ _bdf_parse_t *p; FT_Memory memory = extmemory; @@ -2224,7 +2224,7 @@ error = _bdf_readstream( stream, _bdf_parse_start, (void *)p, &lineno ); if ( error ) - goto Exit; + goto Fail; if ( p->font != 0 ) { @@ -2316,7 +2316,7 @@ if ( FT_RENEW_ARRAY( p->font->comments, p->font->comments_len, p->font->comments_len + 1 ) ) - goto Exit; + goto Fail; p->font->comments[p->font->comments_len] = 0; } @@ -2337,6 +2337,15 @@ } return error; + + Fail: + bdf_free_font( p->font ); + + memory = extmemory; + + FT_FREE( p->font ); + + goto Exit; } diff --git a/src/libs/freetype2/bdf/module.mk b/src/libs/freetype2/bdf/module.mk index a9789736a0..dfaa2744eb 100644 --- a/src/libs/freetype2/bdf/module.mk +++ b/src/libs/freetype2/bdf/module.mk @@ -4,7 +4,7 @@ # Copyright 2001, 2002, 2006 by # Francesco Zappa Nardelli -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights diff --git a/src/libs/freetype2/cache/ftccmap.c b/src/libs/freetype2/cache/ftccmap.c index fefcbdfc05..1568e5e855 100644 --- a/src/libs/freetype2/cache/ftccmap.c +++ b/src/libs/freetype2/cache/ftccmap.c @@ -305,9 +305,13 @@ * more than a few charmaps, so if the index is very large... * * It is also very unlikely that a rogue client is interested - * in Unicode values 0 to 3. + * in Unicode values 0 to 15. + * + * NOTE: The original threshold was 4, but we found a font from the + * Adobe Acrobat Reader Pack, named `KozMinProVI-Regular.otf', + * which contains more than 5 charmaps. */ - if ( cmap_index >= 4 ) + if ( cmap_index >= 16 ) { FTC_OldCMapDesc desc = (FTC_OldCMapDesc) face_id; diff --git a/src/libs/freetype2/cff/cffcmap.c b/src/libs/freetype2/cff/cffcmap.c index cfaaebc9fb..fffc5fc550 100644 --- a/src/libs/freetype2/cff/cffcmap.c +++ b/src/libs/freetype2/cff/cffcmap.c @@ -120,9 +120,10 @@ /*************************************************************************/ FT_CALLBACK_DEF( const char* ) - cff_sid_to_glyph_name( CFF_Font cff, + cff_sid_to_glyph_name( TT_Face face, FT_UInt idx ) { + CFF_Font cff = (CFF_Font)face->extra.data; CFF_Charset charset = &cff->charset; FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; FT_UInt sid = charset->sids[idx]; @@ -132,6 +133,17 @@ } + FT_CALLBACK_DEF( void ) + cff_sid_free_glyph_name( TT_Face face, + const char* gname ) + { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( gname ); + } + + FT_CALLBACK_DEF( FT_Error ) cff_cmap_unicode_init( PS_Unicodes unicodes ) { @@ -149,8 +161,9 @@ return psnames->unicodes_init( memory, unicodes, cff->num_glyphs, - (PS_Glyph_NameFunc)&cff_sid_to_glyph_name, - (FT_Pointer)cff ); + (PS_GetGlyphNameFunc)&cff_sid_to_glyph_name, + (PS_FreeGlyphNameFunc)&cff_sid_free_glyph_name, + (FT_Pointer)face ); } diff --git a/src/libs/freetype2/cff/cffcmap.h b/src/libs/freetype2/cff/cffcmap.h index f3d8e7af1a..3809b85611 100644 --- a/src/libs/freetype2/cff/cffcmap.h +++ b/src/libs/freetype2/cff/cffcmap.h @@ -39,14 +39,14 @@ FT_BEGIN_HEADER { FT_CMapRec cmap; FT_UShort* gids; /* up to 256 elements */ - + } CFF_CMapStdRec; FT_CALLBACK_TABLE const FT_CMap_ClassRec cff_cmap_encoding_class_rec; - + /*************************************************************************/ /*************************************************************************/ /***** *****/ diff --git a/src/libs/freetype2/cff/cffdrivr.c b/src/libs/freetype2/cff/cffdrivr.c index e90e2b04e1..1f04728ea2 100644 --- a/src/libs/freetype2/cff/cffdrivr.c +++ b/src/libs/freetype2/cff/cffdrivr.c @@ -4,7 +4,7 @@ /* */ /* OpenType font driver implementation (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -302,9 +302,57 @@ } + static FT_Error + cff_ps_get_font_info( CFF_Face face, + PS_FontInfoRec* afont_info ) + { + CFF_Font cff = (CFF_Font)face->extra.data; + FT_Error error = FT_Err_Ok; + + + if ( cff && cff->font_info == NULL ) + { + CFF_FontRecDict dict = &cff->top_font.font_dict; + PS_FontInfoRec *font_info; + FT_Memory memory = face->root.memory; + + + if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) ) + goto Fail; + + font_info->version = cff_index_get_sid_string( &cff->string_index, + dict->version, + cff->psnames ); + font_info->notice = cff_index_get_sid_string( &cff->string_index, + dict->notice, + cff->psnames ); + font_info->full_name = cff_index_get_sid_string( &cff->string_index, + dict->full_name, + cff->psnames ); + font_info->family_name = cff_index_get_sid_string( &cff->string_index, + dict->family_name, + cff->psnames ); + font_info->weight = cff_index_get_sid_string( &cff->string_index, + dict->weight, + cff->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; + font_info->underline_thickness = (FT_Short)dict->underline_thickness; + + cff->font_info = font_info; + } + + *afont_info = *cff->font_info; + + Fail: + return error; + } + + static const FT_Service_PsInfoRec cff_service_ps_info = { - (PS_GetFontInfoFunc) NULL, /* unsupported with CFF fonts */ + (PS_GetFontInfoFunc) cff_ps_get_font_info, (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, (PS_GetFontPrivateFunc)NULL /* unsupported with CFF fonts */ }; diff --git a/src/libs/freetype2/cff/cffgload.c b/src/libs/freetype2/cff/cffgload.c index 673a814d75..5c5ae61590 100644 --- a/src/libs/freetype2/cff/cffgload.c +++ b/src/libs/freetype2/cff/cffgload.c @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -2275,16 +2275,29 @@ FT_UInt glyph_index, FT_Int32 load_flags ) { - FT_Error error; - CFF_Decoder decoder; - TT_Face face = (TT_Face)glyph->root.face; - FT_Bool hinting; - CFF_Font cff = (CFF_Font)face->extra.data; + FT_Error error; + CFF_Decoder decoder; + TT_Face face = (TT_Face)glyph->root.face; + FT_Bool hinting; + CFF_Font cff = (CFF_Font)face->extra.data; - FT_Matrix font_matrix; - FT_Vector font_offset; + FT_Matrix font_matrix; + FT_Vector font_offset; + /* 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 ) + { + glyph_index = cff_charset_cid_to_gindex( &cff->charset, glyph_index ); + if ( glyph_index == 0 ) + return CFF_Err_Invalid_Argument; + } + else if ( glyph_index >= cff->num_glyphs ) + return CFF_Err_Invalid_Argument; + if ( load_flags & FT_LOAD_NO_RECURSE ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; @@ -2376,18 +2389,6 @@ FT_ULong charstring_len; - /* 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 ) - { - if ( glyph_index < cff->charset.max_cid ) - glyph_index = cff->charset.cids[glyph_index]; - else - glyph_index = 0; - } - cff_decoder_init( &decoder, face, size, glyph, hinting, FT_LOAD_TARGET_MODE( load_flags ) ); @@ -2421,13 +2422,15 @@ /* See how charstring loads at cff_index_access_element() in */ /* cffload.c. */ { - CFF_IndexRec csindex = cff->charstrings_index; + CFF_Index csindex = &cff->charstrings_index; - glyph->root.control_data = - csindex.bytes + csindex.offsets[glyph_index] - 1; - glyph->root.control_len = - charstring_len; + if ( csindex->offsets ) + { + glyph->root.control_data = csindex->bytes + + csindex->offsets[glyph_index] - 1; + glyph->root.control_len = charstring_len; + } } } diff --git a/src/libs/freetype2/cff/cffload.c b/src/libs/freetype2/cff/cffload.c index a7b7d70e91..b7a41a14ee 100644 --- a/src/libs/freetype2/cff/cffload.c +++ b/src/libs/freetype2/cff/cffload.c @@ -4,7 +4,7 @@ /* */ /* OpenType and CFF data/program tables loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -22,6 +22,7 @@ #include FT_INTERNAL_STREAM_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_TRUETYPE_TAGS_H +#include FT_TYPE1_TABLES_H #include "cffload.h" #include "cffparse.h" @@ -32,1016 +33,147 @@ #if 1 static const FT_UShort cff_isoadobe_charset[229] = { - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 96, - 97, - 98, - 99, - 100, - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120, - 121, - 122, - 123, - 124, - 125, - 126, - 127, - 128, - 129, - 130, - 131, - 132, - 133, - 134, - 135, - 136, - 137, - 138, - 139, - 140, - 141, - 142, - 143, - 144, - 145, - 146, - 147, - 148, - 149, - 150, - 151, - 152, - 153, - 154, - 155, - 156, - 157, - 158, - 159, - 160, - 161, - 162, - 163, - 164, - 165, - 166, - 167, - 168, - 169, - 170, - 171, - 172, - 173, - 174, - 175, - 176, - 177, - 178, - 179, - 180, - 181, - 182, - 183, - 184, - 185, - 186, - 187, - 188, - 189, - 190, - 191, - 192, - 193, - 194, - 195, - 196, - 197, - 198, - 199, - 200, - 201, - 202, - 203, - 204, - 205, - 206, - 207, - 208, - 209, - 210, - 211, - 212, - 213, - 214, - 215, - 216, - 217, - 218, - 219, - 220, - 221, - 222, - 223, - 224, - 225, - 226, - 227, - 228 + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228 }; static const FT_UShort cff_expert_charset[166] = { - 0, - 1, - 229, - 230, - 231, - 232, - 233, - 234, - 235, - 236, - 237, - 238, - 13, - 14, - 15, - 99, - 239, - 240, - 241, - 242, - 243, - 244, - 245, - 246, - 247, - 248, - 27, - 28, - 249, - 250, - 251, - 252, - 253, - 254, - 255, - 256, - 257, - 258, - 259, - 260, - 261, - 262, - 263, - 264, - 265, - 266, - 109, - 110, - 267, - 268, - 269, - 270, - 271, - 272, - 273, - 274, - 275, - 276, - 277, - 278, - 279, - 280, - 281, - 282, - 283, - 284, - 285, - 286, - 287, - 288, - 289, - 290, - 291, - 292, - 293, - 294, - 295, - 296, - 297, - 298, - 299, - 300, - 301, - 302, - 303, - 304, - 305, - 306, - 307, - 308, - 309, - 310, - 311, - 312, - 313, - 314, - 315, - 316, - 317, - 318, - 158, - 155, - 163, - 319, - 320, - 321, - 322, - 323, - 324, - 325, - 326, - 150, - 164, - 169, - 327, - 328, - 329, - 330, - 331, - 332, - 333, - 334, - 335, - 336, - 337, - 338, - 339, - 340, - 341, - 342, - 343, - 344, - 345, - 346, - 347, - 348, - 349, - 350, - 351, - 352, - 353, - 354, - 355, - 356, - 357, - 358, - 359, - 360, - 361, - 362, - 363, - 364, - 365, - 366, - 367, - 368, - 369, - 370, - 371, - 372, - 373, - 374, - 375, - 376, - 377, - 378 + 0, 1, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 13, 14, 15, 99, + 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 27, 28, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 109, 110, + 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 158, 155, 163, 319, + 320, 321, 322, 323, 324, 325, 326, 150, + 164, 169, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, + 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378 }; static const FT_UShort cff_expertsubset_charset[87] = { - 0, - 1, - 231, - 232, - 235, - 236, - 237, - 238, - 13, - 14, - 15, - 99, - 239, - 240, - 241, - 242, - 243, - 244, - 245, - 246, - 247, - 248, - 27, - 28, - 249, - 250, - 251, - 253, - 254, - 255, - 256, - 257, - 258, - 259, - 260, - 261, - 262, - 263, - 264, - 265, - 266, - 109, - 110, - 267, - 268, - 269, - 270, - 272, - 300, - 301, - 302, - 305, - 314, - 315, - 158, - 155, - 163, - 320, - 321, - 322, - 323, - 324, - 325, - 326, - 150, - 164, - 169, - 327, - 328, - 329, - 330, - 331, - 332, - 333, - 334, - 335, - 336, - 337, - 338, - 339, - 340, - 341, - 342, - 343, - 344, - 345, - 346 + 0, 1, 231, 232, 235, 236, 237, 238, + 13, 14, 15, 99, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 27, 28, + 249, 250, 251, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, + 266, 109, 110, 267, 268, 269, 270, 272, + 300, 301, 302, 305, 314, 315, 158, 155, + 163, 320, 321, 322, 323, 324, 325, 326, + 150, 164, 169, 327, 328, 329, 330, 331, + 332, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, 346 }; static const FT_UShort cff_standard_encoding[256] = { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 96, - 97, - 98, - 99, - 100, - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 0, - 111, - 112, - 113, - 114, - 0, - 115, - 116, - 117, - 118, - 119, - 120, - 121, - 122, - 0, - 123, - 0, - 124, - 125, - 126, - 127, - 128, - 129, - 130, - 131, - 0, - 132, - 133, - 0, - 134, - 135, - 136, - 137, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 138, - 0, - 139, - 0, - 0, - 0, - 0, - 140, - 141, - 142, - 143, - 0, - 0, - 0, - 0, - 0, - 144, - 0, - 0, - 0, - 145, - 0, - 0, - 146, - 147, - 148, - 149, - 0, - 0, - 0, - 0 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, + 0, 111, 112, 113, 114, 0, 115, 116, + 117, 118, 119, 120, 121, 122, 0, 123, + 0, 124, 125, 126, 127, 128, 129, 130, + 131, 0, 132, 133, 0, 134, 135, 136, + 137, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 138, 0, 139, 0, 0, 0, 0, + 140, 141, 142, 143, 0, 0, 0, 0, + 0, 144, 0, 0, 0, 145, 0, 0, + 146, 147, 148, 149, 0, 0, 0, 0 }; static const FT_UShort cff_expert_encoding[256] = { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 229, - 230, - 0, - 231, - 232, - 233, - 234, - 235, - 236, - 237, - 238, - 13, - 14, - 15, - 99, - 239, - 240, - 241, - 242, - 243, - 244, - 245, - 246, - 247, - 248, - 27, - 28, - 249, - 250, - 251, - 252, - 0, - 253, - 254, - 255, - 256, - 257, - 0, - 0, - 0, - 258, - 0, - 0, - 259, - 260, - 261, - 262, - 0, - 0, - 263, - 264, - 265, - 0, - 266, - 109, - 110, - 267, - 268, - 269, - 0, - 270, - 271, - 272, - 273, - 274, - 275, - 276, - 277, - 278, - 279, - 280, - 281, - 282, - 283, - 284, - 285, - 286, - 287, - 288, - 289, - 290, - 291, - 292, - 293, - 294, - 295, - 296, - 297, - 298, - 299, - 300, - 301, - 302, - 303, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 304, - 305, - 306, - 0, - 0, - 307, - 308, - 309, - 310, - 311, - 0, - 312, - 0, - 0, - 312, - 0, - 0, - 314, - 315, - 0, - 0, - 316, - 317, - 318, - 0, - 0, - 0, - 158, - 155, - 163, - 319, - 320, - 321, - 322, - 323, - 324, - 325, - 0, - 0, - 326, - 150, - 164, - 169, - 327, - 328, - 329, - 330, - 331, - 332, - 333, - 334, - 335, - 336, - 337, - 338, - 339, - 340, - 341, - 342, - 343, - 344, - 345, - 346, - 347, - 348, - 349, - 350, - 351, - 352, - 353, - 354, - 355, - 356, - 357, - 358, - 359, - 360, - 361, - 362, - 363, - 364, - 365, - 366, - 367, - 368, - 369, - 370, - 371, - 372, - 373, - 374, - 375, - 376, - 377, - 378 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 229, 230, 0, 231, 232, 233, 234, + 235, 236, 237, 238, 13, 14, 15, 99, + 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 27, 28, 249, 250, 251, 252, + 0, 253, 254, 255, 256, 257, 0, 0, + 0, 258, 0, 0, 259, 260, 261, 262, + 0, 0, 263, 264, 265, 0, 266, 109, + 110, 267, 268, 269, 0, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 304, 305, 306, 0, 0, 307, 308, + 309, 310, 311, 0, 312, 0, 0, 312, + 0, 0, 314, 315, 0, 0, 316, 317, + 318, 0, 0, 0, 158, 155, 163, 319, + 320, 321, 322, 323, 324, 325, 0, 0, + 326, 150, 164, 169, 327, 328, 329, 330, + 331, 332, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378 }; #endif @@ -1063,28 +195,35 @@ #define FT_COMPONENT trace_cffload - /* read a CFF offset from memory */ + /* read an offset from the index's stream current position */ static FT_ULong - cff_get_offset( FT_Byte* p, - FT_Byte off_size ) + cff_index_read_offset( CFF_Index idx, + FT_Error *errorp ) { - FT_ULong result; + FT_Error error; + FT_Stream stream = idx->stream; + FT_Byte tmp[4]; + FT_ULong result = 0; - for ( result = 0; off_size > 0; off_size-- ) + if ( !FT_STREAM_READ( tmp, idx->off_size ) ) { - result <<= 8; - result |= *p++; + FT_Int nn; + + + for ( nn = 0; nn < idx->off_size; nn++ ) + result = ( result << 8 ) | tmp[nn]; } + *errorp = error; return result; } static FT_Error - cff_new_index( CFF_Index idx, - FT_Stream stream, - FT_Bool load ) + cff_index_init( CFF_Index idx, + FT_Stream stream, + FT_Bool load ) { FT_Error error; FT_Memory memory = stream->memory; @@ -1094,13 +233,12 @@ FT_MEM_ZERO( idx, sizeof ( *idx ) ); idx->stream = stream; + idx->start = FT_STREAM_POS(); if ( !FT_READ_USHORT( count ) && count > 0 ) { - FT_Byte* p; - FT_Byte offsize; - FT_ULong data_size; - FT_ULong* poff; + FT_Byte offsize; + FT_ULong size; /* there is at least one element; read the offset size, */ @@ -1108,40 +246,43 @@ if ( FT_READ_BYTE( offsize ) ) goto Exit; - idx->stream = stream; - idx->count = count; - idx->off_size = offsize; - data_size = (FT_ULong)( count + 1 ) * offsize; - - if ( FT_NEW_ARRAY( idx->offsets, count + 1 ) || - FT_FRAME_ENTER( data_size ) ) - goto Exit; - - poff = idx->offsets; - p = (FT_Byte*)stream->cursor; - - for ( ; (FT_Short)count >= 0; count-- ) + if ( offsize < 1 || offsize > 4 ) { - poff[0] = cff_get_offset( p, offsize ); - poff++; - p += offsize; + error = FT_Err_Invalid_Table; + goto Exit; } - FT_FRAME_EXIT(); + idx->count = count; + idx->off_size = offsize; + size = (FT_ULong)( count + 1 ) * offsize; - idx->data_offset = FT_STREAM_POS(); - data_size = poff[-1] - 1; + idx->data_offset = idx->start + 3 + size; + + if ( FT_STREAM_SKIP( size - offsize ) ) + goto Exit; + + size = cff_index_read_offset( idx, &error ); + if ( error ) + goto Exit; + + if ( size == 0 ) + { + error = CFF_Err_Invalid_Table; + goto Exit; + } + + idx->data_size = --size; if ( load ) { /* load the data */ - if ( FT_FRAME_EXTRACT( data_size, idx->bytes ) ) + if ( FT_FRAME_EXTRACT( size, idx->bytes ) ) goto Exit; } else { /* skip the data */ - if ( FT_STREAM_SKIP( data_size ) ) + if ( FT_STREAM_SKIP( size ) ) goto Exit; } } @@ -1155,7 +296,7 @@ static void - cff_done_index( CFF_Index idx ) + cff_index_done( CFF_Index idx ) { if ( idx->stream ) { @@ -1172,6 +313,67 @@ } + static FT_Error + cff_index_load_offsets( CFF_Index idx ) + { + FT_Error error = 0; + FT_Stream stream = idx->stream; + FT_Memory memory = stream->memory; + + + if ( idx->count > 0 && idx->offsets == NULL ) + { + FT_Byte offsize = idx->off_size; + FT_ULong data_size; + FT_Byte* p; + FT_Byte* p_end; + FT_ULong* poff; + + + data_size = (FT_ULong)( idx->count + 1 ) * offsize; + + if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) || + FT_STREAM_SEEK( idx->start + 3 ) || + FT_FRAME_ENTER( data_size ) ) + goto Exit; + + poff = idx->offsets; + p = (FT_Byte*)stream->cursor; + p_end = p + data_size; + + switch ( offsize ) + { + case 1: + for ( ; p < p_end; p++, poff++ ) + poff[0] = p[0]; + break; + + case 2: + for ( ; p < p_end; p += 2, poff++ ) + poff[0] = FT_PEEK_USHORT( p ); + break; + + case 3: + for ( ; p < p_end; p += 3, poff++ ) + poff[0] = FT_PEEK_OFF3( p ); + break; + + default: + for ( ; p < p_end; p += 4, poff++ ) + poff[0] = FT_PEEK_ULONG( p ); + } + + FT_FRAME_EXIT(); + } + + Exit: + if ( error ) + FT_FREE( idx->offsets ); + + return error; + } + + /* allocate a table containing pointers to an index's elements */ static FT_Error cff_index_get_pointers( CFF_Index idx, @@ -1185,6 +387,13 @@ *table = 0; + if ( idx->offsets == NULL ) + { + error = cff_index_load_offsets( idx ); + if ( error ) + goto Exit; + } + if ( idx->count > 0 && !FT_NEW_ARRAY( t, idx->count + 1 ) ) { old_offset = 1; @@ -1194,6 +403,10 @@ if ( !offset ) offset = old_offset; + /* sanity check for invalid offset tables */ + else if ( offset < old_offset || offset - 1 >= idx->data_size ) + offset = old_offset; + t[n] = idx->bytes + offset - 1; old_offset = offset; @@ -1201,6 +414,7 @@ *table = t; } + Exit: return error; } @@ -1217,21 +431,45 @@ if ( idx && idx->count > element ) { /* compute start and end offsets */ - FT_ULong off1, off2 = 0; + FT_Stream stream = idx->stream; + FT_ULong off1, off2 = 0; - off1 = idx->offsets[element]; - if ( off1 ) + /* load offsets from file or the offset table */ + if ( !idx->offsets ) { - do + FT_ULong pos = element * idx->off_size; + + + if ( FT_STREAM_SEEK( idx->start + 3 + pos ) ) + goto Exit; + + off1 = cff_index_read_offset( idx, &error ); + if ( error ) + goto Exit; + + if ( off1 != 0 ) { - element++; - off2 = idx->offsets[element]; + do + { + element++; + off2 = cff_index_read_offset( idx, &error ); + } + while ( off2 == 0 && element < idx->count ); + } + } + else /* use offsets table */ + { + off1 = idx->offsets[element]; + if ( off1 ) + { + do + { + element++; + off2 = idx->offsets[element]; - } while ( off2 == 0 && element < idx->count ); - - if ( !off2 ) - off1 = 0; + } while ( off2 == 0 && element < idx->count ); + } } /* access element */ @@ -1247,9 +485,6 @@ else { /* this index is still on disk/file, access it through a frame */ - FT_Stream stream = idx->stream; - - if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) || FT_FRAME_EXTRACT( off2 - off1, *pbytes ) ) goto Exit; @@ -1493,6 +728,61 @@ /*************************************************************************/ /*************************************************************************/ + static FT_Error + cff_charset_compute_cids( CFF_Charset charset, + FT_UInt num_glyphs, + FT_Memory memory ) + { + FT_Error error = FT_Err_Ok; + FT_UInt i; + FT_UShort max_cid = 0; + + + if ( charset->max_cid > 0 ) + goto Exit; + + for ( i = 0; i < num_glyphs; i++ ) + if ( charset->sids[i] > max_cid ) + max_cid = charset->sids[i]; + max_cid++; + + if ( FT_NEW_ARRAY( charset->cids, max_cid ) ) + goto Exit; + + for ( i = 0; i < num_glyphs; i++ ) + charset->cids[charset->sids[i]] = (FT_UShort)i; + + charset->max_cid = max_cid; + charset->num_glyphs = num_glyphs; + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_UInt ) + cff_charset_cid_to_gindex( CFF_Charset charset, + FT_UInt cid ) + { + FT_UInt result = 0; + + + if ( cid < charset->max_cid ) + result = charset->cids[cid]; + + return result; + } + + + static void + cff_charset_free_cids( CFF_Charset charset, + FT_Memory memory ) + { + FT_FREE( charset->cids ); + charset->max_cid = 0; + } + + static void cff_charset_done( CFF_Charset charset, FT_Stream stream ) @@ -1500,8 +790,9 @@ FT_Memory memory = stream->memory; + cff_charset_free_cids( charset, memory ); + FT_FREE( charset->sids ); - FT_FREE( charset->cids ); charset->format = 0; charset->offset = 0; } @@ -1672,25 +963,7 @@ /* we have to invert the `sids' array for subsetted CID-keyed fonts */ if ( invert ) - { - FT_UInt i; - FT_UShort max_cid = 0; - - - for ( i = 0; i < num_glyphs; i++ ) - if ( charset->sids[i] > max_cid ) - max_cid = charset->sids[i]; - max_cid++; - - if ( FT_NEW_ARRAY( charset->cids, max_cid ) ) - goto Exit; - FT_MEM_ZERO( charset->cids, sizeof ( FT_UShort ) * max_cid ); - - for ( i = 0; i < num_glyphs; i++ ) - charset->cids[charset->sids[i]] = (FT_UShort)i; - - charset->max_cid = max_cid; - } + error = cff_charset_compute_cids( charset, num_glyphs, memory ); Exit: /* Clean up if there was an error. */ @@ -1896,9 +1169,6 @@ } else { - FT_UInt i; - - /* We take into account the fact a CFF font can use a predefined */ /* encoding without containing all of the glyphs encoded by this */ /* encoding (see the note at the end of section 12 in the CFF */ @@ -1921,32 +1191,31 @@ encoding->count = 0; + error = cff_charset_compute_cids( charset, num_glyphs, + stream->memory ); + if ( error ) + goto Exit; + for ( j = 0; j < 256; j++ ) { - /* If j is encoded, find the GID for it. */ - if ( encoding->sids[j] ) + FT_UInt sid = encoding->sids[j]; + FT_UInt gid = 0; + + + if ( sid ) + gid = cff_charset_cid_to_gindex( charset, sid ); + + if ( gid != 0 ) { - for ( i = 1; i < num_glyphs; i++ ) - /* We matched, so break. */ - if ( charset->sids[i] == encoding->sids[j] ) - break; + encoding->codes[j] = (FT_UShort)gid; - /* i will be equal to num_glyphs if we exited the above */ - /* loop without a match. In this case, we also have to */ - /* fix the code to SID mapping. */ - if ( i == num_glyphs ) - { - encoding->codes[j] = 0; - encoding->sids [j] = 0; - } - else - { - encoding->codes[j] = (FT_UShort)i; - - /* update encoding count */ - if ( encoding->count < j + 1 ) - encoding->count = j + 1; - } + if ( encoding->count < j + 1 ) + encoding->count = j + 1; + } + else + { + encoding->codes[j] = 0; + encoding->sids [j] = 0; } } break; @@ -2013,7 +1282,7 @@ if ( error ) goto Exit; - + /* if it is a CID font, we stop there */ if ( top->cid_registry != 0xFFFFU ) goto Exit; @@ -2054,7 +1323,7 @@ priv->local_subrs_offset ) ) goto Exit; - error = cff_new_index( &font->local_subrs_index, stream, 1 ); + error = cff_index_init( &font->local_subrs_index, stream, 1 ); if ( error ) goto Exit; @@ -2076,7 +1345,7 @@ { if ( subfont ) { - cff_done_index( &subfont->local_subrs_index ); + cff_index_done( &subfont->local_subrs_index ); FT_FREE( subfont->local_subrs ); } } @@ -2132,10 +1401,14 @@ goto Exit; /* read the name, top dict, string and global subrs index */ - if ( FT_SET_ERROR( cff_new_index( &font->name_index, stream, 0 )) || - FT_SET_ERROR( cff_new_index( &font->font_dict_index, stream, 0 )) || - FT_SET_ERROR( cff_new_index( &font->string_index, stream, 0 )) || - FT_SET_ERROR( cff_new_index( &font->global_subrs_index, stream, 1 )) ) + if ( FT_SET_ERROR( cff_index_init( &font->name_index, + stream, 0 ) ) || + FT_SET_ERROR( cff_index_init( &font->font_dict_index, + stream, 0 ) ) || + FT_SET_ERROR( cff_index_init( &font->string_index, + stream, 0 ) ) || + FT_SET_ERROR( cff_index_init( &font->global_subrs_index, + stream, 1 ) ) ) goto Exit; /* well, we don't really forget the `disabled' fonts... */ @@ -2163,7 +1436,7 @@ if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) goto Exit; - error = cff_new_index( &font->charstrings_index, stream, 0 ); + error = cff_index_init( &font->charstrings_index, stream, 0 ); if ( error ) goto Exit; @@ -2180,7 +1453,7 @@ if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) ) goto Exit; - error = cff_new_index( &fd_index, stream, 0 ); + error = cff_index_init( &fd_index, stream, 0 ); if ( error ) goto Exit; @@ -2216,7 +1489,7 @@ base_offset + dict->cid_fd_select_offset ); Fail_CID: - cff_done_index( &fd_index ); + cff_index_done( &fd_index ); if ( error ) goto Exit; @@ -2286,11 +1559,11 @@ FT_UInt idx; - cff_done_index( &font->global_subrs_index ); - cff_done_index( &font->string_index ); - cff_done_index( &font->font_dict_index ); - cff_done_index( &font->name_index ); - cff_done_index( &font->charstrings_index ); + cff_index_done( &font->global_subrs_index ); + cff_index_done( &font->string_index ); + cff_index_done( &font->font_dict_index ); + cff_index_done( &font->name_index ); + cff_index_done( &font->charstrings_index ); /* release font dictionaries, but only if working with */ /* a CID keyed CFF font */ @@ -2298,6 +1571,9 @@ { for ( idx = 0; idx < font->num_subfonts; idx++ ) cff_subfont_done( memory, font->subfonts[idx] ); + + /* the subfonts array has been allocated as a single block */ + FT_FREE( font->subfonts[0] ); } cff_encoding_done( &font->encoding ); @@ -2307,6 +1583,16 @@ CFF_Done_FD_Select( &font->fd_select, font->stream ); + if (font->font_info != NULL) + { + FT_FREE( font->font_info->version ); + FT_FREE( font->font_info->notice ); + FT_FREE( font->font_info->full_name ); + FT_FREE( font->font_info->family_name ); + FT_FREE( font->font_info->weight ); + FT_FREE( font->font_info ); + } + FT_FREE( font->global_subrs ); FT_FREE( font->font_name ); } diff --git a/src/libs/freetype2/cff/cffload.h b/src/libs/freetype2/cff/cffload.h index ccf8ada1c3..068cbb58c2 100644 --- a/src/libs/freetype2/cff/cffload.h +++ b/src/libs/freetype2/cff/cffload.h @@ -4,7 +4,7 @@ /* */ /* OpenType & CFF data/program tables loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -52,6 +52,11 @@ FT_BEGIN_HEADER FT_Byte** pbytes ); + FT_LOCAL( FT_UInt ) + cff_charset_cid_to_gindex( CFF_Charset charset, + FT_UInt cid ); + + FT_LOCAL( FT_Error ) cff_font_load( FT_Stream stream, FT_Int face_index, diff --git a/src/libs/freetype2/cff/cffobjs.c b/src/libs/freetype2/cff/cffobjs.c index 2d1204e381..eb6159f74d 100644 --- a/src/libs/freetype2/cff/cffobjs.c +++ b/src/libs/freetype2/cff/cffobjs.c @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -207,13 +207,13 @@ { CFF_Face cffface = (CFF_Face)size->face; SFNT_Service sfnt = (SFNT_Service)cffface->sfnt; - FT_ULong index; + FT_ULong strike_index; - if ( sfnt->set_sbit_strike( cffface, req, &index ) ) + if ( sfnt->set_sbit_strike( cffface, req, &strike_index ) ) cffsize->strike_index = 0xFFFFFFFFUL; else - return cff_size_select( size, index ); + return cff_size_select( size, strike_index ); } #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ diff --git a/src/libs/freetype2/cff/cffobjs.h b/src/libs/freetype2/cff/cffobjs.h index cc4ab644c7..f18b5d9322 100644 --- a/src/libs/freetype2/cff/cffobjs.h +++ b/src/libs/freetype2/cff/cffobjs.h @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -120,7 +120,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) cff_size_select( FT_Size size, - FT_ULong index ); + FT_ULong strike_index ); #endif diff --git a/src/libs/freetype2/cff/cfftypes.h b/src/libs/freetype2/cff/cfftypes.h index 364b7cb6e9..306e5aab67 100644 --- a/src/libs/freetype2/cff/cfftypes.h +++ b/src/libs/freetype2/cff/cfftypes.h @@ -5,7 +5,7 @@ /* Basic OpenType/CFF type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -23,6 +23,7 @@ #include <ft2build.h> #include FT_FREETYPE_H +#include FT_TYPE1_TABLES_H FT_BEGIN_HEADER @@ -39,6 +40,9 @@ FT_BEGIN_HEADER /* <Fields> */ /* stream :: The source input stream. */ /* */ + /* start :: The position of the first index byte in the */ + /* input stream. */ + /* */ /* count :: The number of elements in the index. */ /* */ /* off_size :: The size in bytes of object offsets in index. */ @@ -46,16 +50,21 @@ FT_BEGIN_HEADER /* data_offset :: The position of first data byte in the index's */ /* bytes. */ /* */ - /* offsets :: A table of element offsets in the index. */ + /* data_size :: The size of the data table in this index. */ + /* */ + /* offsets :: A table of element offsets in the index. Must be */ + /* loaded explicitly. */ /* */ /* bytes :: If the index is loaded in memory, its bytes. */ /* */ typedef struct CFF_IndexRec_ { FT_Stream stream; + FT_ULong start; FT_UInt count; FT_Byte off_size; FT_ULong data_offset; + FT_ULong data_size; FT_ULong* offsets; FT_Byte* bytes; @@ -85,6 +94,8 @@ FT_BEGIN_HEADER FT_UShort* cids; /* the inverse mapping of `sids'; only needed */ /* for CID-keyed fonts */ FT_UInt max_cid; + FT_UInt num_glyphs; + } CFF_CharsetRec, *CFF_Charset; @@ -245,6 +256,9 @@ FT_BEGIN_HEADER /* interface to Postscript Names service */ void* psnames; + /* since version 2.3.0 */ + PS_FontInfoRec* font_info; /* font info dictionary */ + } CFF_FontRec, *CFF_Font; diff --git a/src/libs/freetype2/cid/cidgload.c b/src/libs/freetype2/cid/cidgload.c index ed706ade7d..aec34855cc 100644 --- a/src/libs/freetype2/cid/cidgload.c +++ b/src/libs/freetype2/cid/cidgload.c @@ -230,6 +230,9 @@ if ( error ) return error; + /* TODO: initialize decoder.len_buildchar and decoder.buildchar */ + /* if we ever support CID-keyed multiple master fonts */ + decoder.builder.metrics_only = 1; decoder.builder.load_points = 0; @@ -245,6 +248,8 @@ *max_advance = decoder.builder.advance.x; + psaux->t1_decoder_funcs->done( &decoder ); + return CID_Err_Ok; } @@ -270,6 +275,12 @@ FT_Vector font_offset; + if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) + { + error = CID_Err_Invalid_Argument; + goto Exit; + } + if ( load_flags & FT_LOAD_NO_RECURSE ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; @@ -284,128 +295,132 @@ cidglyph->format = FT_GLYPH_FORMAT_OUTLINE; - { - error = psaux->t1_decoder_funcs->init( &decoder, - cidglyph->face, - cidsize, - cidglyph, - 0, /* glyph names -- XXX */ - 0, /* blend == 0 */ - hinting, - FT_LOAD_TARGET_MODE( load_flags ), - cid_load_glyph ); + error = psaux->t1_decoder_funcs->init( &decoder, + cidglyph->face, + cidsize, + cidglyph, + 0, /* glyph names -- XXX */ + 0, /* blend == 0 */ + hinting, + FT_LOAD_TARGET_MODE( load_flags ), + cid_load_glyph ); + if ( error ) + goto Exit; - /* set up the decoder */ - decoder.builder.no_recurse = FT_BOOL( - ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) ); + /* TODO: initialize decoder.len_buildchar and decoder.buildchar */ + /* if we ever support CID-keyed multiple master fonts */ - error = cid_load_glyph( &decoder, glyph_index ); + /* set up the decoder */ + decoder.builder.no_recurse = FT_BOOL( + ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) ); - font_matrix = decoder.font_matrix; - font_offset = decoder.font_offset; + error = cid_load_glyph( &decoder, glyph_index ); + if ( error ) + goto Exit; - /* save new glyph tables */ - psaux->t1_decoder_funcs->done( &decoder ); - } + font_matrix = decoder.font_matrix; + font_offset = decoder.font_offset; - /* now, set the metrics -- this is rather simple, as */ + /* save new glyph tables */ + psaux->t1_decoder_funcs->done( &decoder ); + + /* now set the metrics -- this is rather simple, as */ /* the left side bearing is the xMin, and the top side */ /* bearing the yMax */ - if ( !error ) + cidglyph->outline.flags &= FT_OUTLINE_OWNER; + cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL; + + /* for composite glyphs, return only left side bearing and */ + /* advance width */ + if ( load_flags & FT_LOAD_NO_RECURSE ) { - cidglyph->outline.flags &= FT_OUTLINE_OWNER; - cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL; + FT_Slot_Internal internal = cidglyph->internal; - /* for composite glyphs, return only left side bearing and */ - /* advance width */ - if ( load_flags & FT_LOAD_NO_RECURSE ) + + cidglyph->metrics.horiBearingX = decoder.builder.left_bearing.x; + cidglyph->metrics.horiAdvance = decoder.builder.advance.x; + + internal->glyph_matrix = font_matrix; + internal->glyph_delta = font_offset; + internal->glyph_transformed = 1; + } + else + { + FT_BBox cbox; + FT_Glyph_Metrics* metrics = &cidglyph->metrics; + FT_Vector advance; + + + /* copy the _unscaled_ advance width */ + metrics->horiAdvance = decoder.builder.advance.x; + cidglyph->linearHoriAdvance = decoder.builder.advance.x; + cidglyph->internal->glyph_transformed = 0; + + /* make up vertical ones */ + metrics->vertAdvance = ( face->cid.font_bbox.yMax - + face->cid.font_bbox.yMin ) >> 16; + cidglyph->linearVertAdvance = metrics->vertAdvance; + + cidglyph->format = FT_GLYPH_FORMAT_OUTLINE; + + if ( size && cidsize->metrics.y_ppem < 24 ) + cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; + + /* apply the font matrix */ + FT_Outline_Transform( &cidglyph->outline, &font_matrix ); + + FT_Outline_Translate( &cidglyph->outline, + font_offset.x, + font_offset.y ); + + advance.x = metrics->horiAdvance; + advance.y = 0; + FT_Vector_Transform( &advance, &font_matrix ); + metrics->horiAdvance = advance.x + font_offset.x; + + advance.x = 0; + advance.y = metrics->vertAdvance; + FT_Vector_Transform( &advance, &font_matrix ); + metrics->vertAdvance = advance.y + font_offset.y; + + if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) { - FT_Slot_Internal internal = cidglyph->internal; + /* scale the outline and the metrics */ + FT_Int n; + FT_Outline* cur = decoder.builder.base; + FT_Vector* vec = cur->points; + FT_Fixed x_scale = glyph->x_scale; + FT_Fixed y_scale = glyph->y_scale; - cidglyph->metrics.horiBearingX = decoder.builder.left_bearing.x; - cidglyph->metrics.horiAdvance = decoder.builder.advance.x; + /* First of all, scale the points */ + if ( !hinting || !decoder.builder.hints_funcs ) + for ( n = cur->n_points; n > 0; n--, vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } - internal->glyph_matrix = font_matrix; - internal->glyph_delta = font_offset; - internal->glyph_transformed = 1; + /* Then scale the metrics */ + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); } - else - { - FT_BBox cbox; - FT_Glyph_Metrics* metrics = &cidglyph->metrics; - FT_Vector advance; + /* compute the other metrics */ + FT_Outline_Get_CBox( &cidglyph->outline, &cbox ); - /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.builder.advance.x; - cidglyph->linearHoriAdvance = decoder.builder.advance.x; - cidglyph->internal->glyph_transformed = 0; + metrics->width = cbox.xMax - cbox.xMin; + metrics->height = cbox.yMax - cbox.yMin; - /* make up vertical ones */ - metrics->vertAdvance = ( face->cid.font_bbox.yMax - - face->cid.font_bbox.yMin ) >> 16; - cidglyph->linearVertAdvance = metrics->vertAdvance; + metrics->horiBearingX = cbox.xMin; + metrics->horiBearingY = cbox.yMax; - cidglyph->format = FT_GLYPH_FORMAT_OUTLINE; - - if ( size && cidsize->metrics.y_ppem < 24 ) - cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; - - /* apply the font matrix */ - FT_Outline_Transform( &cidglyph->outline, &font_matrix ); - - FT_Outline_Translate( &cidglyph->outline, - font_offset.x, - font_offset.y ); - - advance.x = metrics->horiAdvance; - advance.y = 0; - FT_Vector_Transform( &advance, &font_matrix ); - metrics->horiAdvance = advance.x + font_offset.x; - advance.x = 0; - advance.y = metrics->vertAdvance; - FT_Vector_Transform( &advance, &font_matrix ); - metrics->vertAdvance = advance.y + font_offset.y; - - if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - /* scale the outline and the metrics */ - FT_Int n; - FT_Outline* cur = decoder.builder.base; - FT_Vector* vec = cur->points; - FT_Fixed x_scale = glyph->x_scale; - FT_Fixed y_scale = glyph->y_scale; - - - /* First of all, scale the points */ - if ( !hinting || !decoder.builder.hints_funcs ) - for ( n = cur->n_points; n > 0; n--, vec++ ) - { - vec->x = FT_MulFix( vec->x, x_scale ); - vec->y = FT_MulFix( vec->y, y_scale ); - } - - /* Then scale the metrics */ - metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); - metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); - } - - /* compute the other metrics */ - FT_Outline_Get_CBox( &cidglyph->outline, &cbox ); - - metrics->width = cbox.xMax - cbox.xMin; - metrics->height = cbox.yMax - cbox.yMin; - - metrics->horiBearingX = cbox.xMin; - metrics->horiBearingY = cbox.yMax; - - /* make up vertical ones */ - ft_synthesize_vertical_metrics( metrics, - metrics->vertAdvance ); - } + /* make up vertical ones */ + ft_synthesize_vertical_metrics( metrics, + metrics->vertAdvance ); } + Exit: return error; } diff --git a/src/libs/freetype2/cid/cidload.c b/src/libs/freetype2/cid/cidload.c index 8d96ea6ee4..9ed8cee46c 100644 --- a/src/libs/freetype2/cid/cidload.c +++ b/src/libs/freetype2/cid/cidload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 font loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -240,10 +240,10 @@ #include "cidtoken.h" - T1_FIELD_CALLBACK( "FDArray", parse_fd_array ) - T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix ) + T1_FIELD_CALLBACK( "FDArray", parse_fd_array, 0 ) + T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix, 0 ) - { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 } + { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } }; diff --git a/src/libs/freetype2/cid/cidparse.c b/src/libs/freetype2/cid/cidparse.c index ac56363f68..c2381fac1b 100644 --- a/src/libs/freetype2/cid/cidparse.c +++ b/src/libs/freetype2/cid/cidparse.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 parser (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -83,7 +83,8 @@ goto Exit; Again: - /* now, read the rest of the file until we find a `StartData' */ + /* now, read the rest of the file until we find */ + /* `StartData' or `/sfnts' */ { FT_Byte buffer[256 + 10]; FT_Int read_len = 256 + 10; @@ -92,7 +93,7 @@ for ( offset = (FT_ULong)FT_STREAM_POS(); ; offset += 256 ) { - FT_Int stream_len; + FT_Int stream_len; stream_len = stream->size - FT_STREAM_POS(); @@ -116,6 +117,11 @@ offset += p - buffer + 10; goto Found; } + else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 ) + { + offset += p - buffer + 7; + goto Found; + } } FT_MEM_MOVE( buffer, p, 10 ); @@ -125,8 +131,9 @@ } Found: - /* We have found the start of the binary data. Now rewind and */ - /* extract the frame corresponding to the PostScript section. */ + /* We have found the start of the binary data or the `/sfnts' token. */ + /* Now rewind and extract the frame corresponding to this PostScript */ + /* section. */ ps_len = offset - base_offset; if ( FT_STREAM_SEEK( base_offset ) || @@ -140,9 +147,10 @@ parser->root.limit = parser->root.cursor + ps_len; parser->num_dict = -1; - /* Finally, we check whether `StartData' was real -- it could be */ - /* in a comment or string. We also get its arguments to find out */ - /* whether the data is represented in binary or hex format. */ + /* Finally, we check whether `StartData' or `/sfnts' was real -- */ + /* it could be in a comment or string. We also get the arguments */ + /* of `StartData' to find out whether the data is represented in */ + /* binary or hex format. */ arg1 = parser->root.cursor; cid_parser_skip_PS_token( parser ); @@ -159,7 +167,7 @@ if ( parser->root.error ) break; - if ( *cur == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) + if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) { if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) parser->binary_length = ft_atol( (const char *)arg2 ); @@ -168,6 +176,12 @@ cur = parser->root.cursor; goto Exit; } + else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 ) + { + FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" )); + error = CID_Err_Unknown_File_Format; + goto Exit; + } cid_parser_skip_PS_token( parser ); cid_parser_skip_spaces ( parser ); diff --git a/src/libs/freetype2/cid/cidtoken.h b/src/libs/freetype2/cid/cidtoken.h index 2070aa91bb..ad5bbb2eef 100644 --- a/src/libs/freetype2/cid/cidtoken.h +++ b/src/libs/freetype2/cid/cidtoken.h @@ -4,7 +4,7 @@ /* */ /* CID token definitions (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,17 +21,17 @@ #undef T1CODE #define T1CODE T1_FIELD_LOCATION_CID_INFO - T1_FIELD_KEY ( "CIDFontName", cid_font_name ) - T1_FIELD_NUM ( "CIDFontVersion", cid_version ) - T1_FIELD_NUM ( "CIDFontType", cid_font_type ) - T1_FIELD_STRING( "Registry", registry ) - T1_FIELD_STRING( "Ordering", ordering ) - T1_FIELD_NUM ( "Supplement", supplement ) - T1_FIELD_NUM ( "UIDBase", uid_base ) - T1_FIELD_NUM ( "CIDMapOffset", cidmap_offset ) - T1_FIELD_NUM ( "FDBytes", fd_bytes ) - T1_FIELD_NUM ( "GDBytes", gd_bytes ) - T1_FIELD_NUM ( "CIDCount", cid_count ) + T1_FIELD_KEY ( "CIDFontName", cid_font_name, 0 ) + T1_FIELD_NUM ( "CIDFontVersion", cid_version, 0 ) + T1_FIELD_NUM ( "CIDFontType", cid_font_type, 0 ) + T1_FIELD_STRING( "Registry", registry, 0 ) + T1_FIELD_STRING( "Ordering", ordering, 0 ) + T1_FIELD_NUM ( "Supplement", supplement, 0 ) + T1_FIELD_NUM ( "UIDBase", uid_base, 0 ) + T1_FIELD_NUM ( "CIDMapOffset", cidmap_offset, 0 ) + T1_FIELD_NUM ( "FDBytes", fd_bytes, 0 ) + T1_FIELD_NUM ( "GDBytes", gd_bytes, 0 ) + T1_FIELD_NUM ( "CIDCount", cid_count, 0 ) #undef FT_STRUCTURE @@ -39,15 +39,15 @@ #undef T1CODE #define T1CODE T1_FIELD_LOCATION_FONT_INFO - T1_FIELD_STRING( "version", version ) - T1_FIELD_STRING( "Notice", notice ) - T1_FIELD_STRING( "FullName", full_name ) - T1_FIELD_STRING( "FamilyName", family_name ) - T1_FIELD_STRING( "Weight", weight ) - T1_FIELD_NUM ( "ItalicAngle", italic_angle ) - T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch ) - T1_FIELD_NUM ( "UnderlinePosition", underline_position ) - T1_FIELD_NUM ( "UnderlineThickness", underline_thickness ) + T1_FIELD_STRING( "version", version, 0 ) + T1_FIELD_STRING( "Notice", notice, 0 ) + T1_FIELD_STRING( "FullName", full_name, 0 ) + T1_FIELD_STRING( "FamilyName", family_name, 0 ) + T1_FIELD_STRING( "Weight", weight, 0 ) + T1_FIELD_NUM ( "ItalicAngle", italic_angle, 0 ) + T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch, 0 ) + T1_FIELD_NUM ( "UnderlinePosition", underline_position, 0 ) + T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, 0 ) #undef FT_STRUCTURE @@ -55,15 +55,15 @@ #undef T1CODE #define T1CODE T1_FIELD_LOCATION_FONT_DICT - T1_FIELD_NUM ( "PaintType", paint_type ) - T1_FIELD_NUM ( "FontType", font_type ) - T1_FIELD_NUM ( "SubrMapOffset", subrmap_offset ) - T1_FIELD_NUM ( "SDBytes", sd_bytes ) - T1_FIELD_NUM ( "SubrCount", num_subrs ) - T1_FIELD_NUM ( "lenBuildCharArray", len_buildchar ) - T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold ) - T1_FIELD_FIXED( "ExpansionFactor", expansion_factor ) - T1_FIELD_FIXED( "StrokeWidth", stroke_width ) + T1_FIELD_NUM ( "PaintType", paint_type, 0 ) + T1_FIELD_NUM ( "FontType", font_type, 0 ) + T1_FIELD_NUM ( "SubrMapOffset", subrmap_offset, 0 ) + T1_FIELD_NUM ( "SDBytes", sd_bytes, 0 ) + T1_FIELD_NUM ( "SubrCount", num_subrs, 0 ) + T1_FIELD_NUM ( "lenBuildCharArray", len_buildchar, 0 ) + T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold, 0 ) + T1_FIELD_FIXED( "ExpansionFactor", expansion_factor, 0 ) + T1_FIELD_FIXED( "StrokeWidth", stroke_width, 0 ) #undef FT_STRUCTURE @@ -71,33 +71,33 @@ #undef T1CODE #define T1CODE T1_FIELD_LOCATION_PRIVATE - T1_FIELD_NUM ( "UniqueID", unique_id ) - T1_FIELD_NUM ( "lenIV", lenIV ) - T1_FIELD_NUM ( "LanguageGroup", language_group ) - T1_FIELD_NUM ( "password", password ) + T1_FIELD_NUM ( "UniqueID", unique_id, 0 ) + T1_FIELD_NUM ( "lenIV", lenIV, 0 ) + T1_FIELD_NUM ( "LanguageGroup", language_group, 0 ) + T1_FIELD_NUM ( "password", password, 0 ) - T1_FIELD_FIXED_1000( "BlueScale", blue_scale ) - T1_FIELD_NUM ( "BlueShift", blue_shift ) - T1_FIELD_NUM ( "BlueFuzz", blue_fuzz ) + T1_FIELD_FIXED_1000( "BlueScale", blue_scale, 0 ) + T1_FIELD_NUM ( "BlueShift", blue_shift, 0 ) + T1_FIELD_NUM ( "BlueFuzz", blue_fuzz, 0 ) - T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14 ) - T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10 ) - T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14 ) - T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10 ) + T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14, 0 ) + T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10, 0 ) + T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14, 0 ) + T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10, 0 ) - T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1 ) - T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1 ) - T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2 ) + T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1, 0 ) + T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1, 0 ) + T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2, 0 ) - T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 ) - T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 ) + T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12, 0 ) + T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12, 0 ) #undef FT_STRUCTURE #define FT_STRUCTURE FT_BBox #undef T1CODE #define T1CODE T1_FIELD_LOCATION_BBOX - T1_FIELD_BBOX( "FontBBox", xMin ) + T1_FIELD_BBOX( "FontBBox", xMin, 0 ) /* END */ diff --git a/src/libs/freetype2/gzip/ftgzip.c b/src/libs/freetype2/gzip/ftgzip.c index 6f7bad777c..af2022d7f5 100644 --- a/src/libs/freetype2/gzip/ftgzip.c +++ b/src/libs/freetype2/gzip/ftgzip.c @@ -554,6 +554,28 @@ } + static FT_ULong + ft_gzip_get_uncompressed_size( FT_Stream stream ) + { + FT_Error error; + FT_ULong old_pos; + FT_ULong result = 0; + + + old_pos = stream->pos; + if ( !FT_Stream_Seek( stream, stream->size - 4 ) ) + { + result = (FT_ULong)FT_Stream_ReadLong( stream, &error ); + if ( error ) + result = 0; + + FT_Stream_Seek( stream, old_pos ); + } + + return result; + } + + FT_EXPORT_DEF( FT_Error ) FT_Stream_OpenGzip( FT_Stream stream, FT_Stream source ) @@ -586,6 +608,52 @@ stream->descriptor.pointer = zip; } + /* + * We use the following trick to try to dramatically improve the + * performance while dealing with small files. If the original stream + * size is less than a certain threshold, we try to load the whole font + * file into memory. This saves us from using the 32KB buffer needed + * to inflate the file, plus the two 4KB intermediate input/output + * buffers used in the `FT_GZipFile' structure. + */ + { + FT_ULong zip_size = ft_gzip_get_uncompressed_size( source ); + + + if ( zip_size != 0 && zip_size < 40 * 1024 ) + { + FT_Byte* zip_buff; + + + if ( !FT_ALLOC( zip_buff, zip_size ) ) + { + FT_ULong count; + + + count = ft_gzip_file_io( zip, 0, zip_buff, zip_size ); + if ( count == zip_size ) + { + ft_gzip_file_done( zip ); + FT_FREE( zip ); + + stream->descriptor.pointer = NULL; + + stream->size = zip_size; + stream->pos = 0; + stream->base = zip_buff; + stream->read = NULL; + stream->close = ft_gzip_stream_close; + + goto Exit; + } + + ft_gzip_file_io( zip, 0, NULL, 0 ); + FT_FREE( zip_buff ); + } + error = 0; + } + } + stream->size = 0x7FFFFFFFL; /* don't know the real size! */ stream->pos = 0; stream->base = 0; diff --git a/src/libs/freetype2/gzip/inftrees.c b/src/libs/freetype2/gzip/inftrees.c index 9002bf5b89..7b74296ee1 100644 --- a/src/libs/freetype2/gzip/inftrees.c +++ b/src/libs/freetype2/gzip/inftrees.c @@ -131,6 +131,9 @@ uIntf *v /* working area: values in order of bit length */ uInt z; /* number of entries in current table */ + /* Make comiler happy */ + r.base = 0; + /* Generate counts for each bit length */ p = c; #define C0 *p++ = 0; diff --git a/src/libs/freetype2/otvalid/otvmod.c b/src/libs/freetype2/otvalid/otvmod.c index 4c46e6baf5..157272f1ae 100644 --- a/src/libs/freetype2/otvalid/otvmod.c +++ b/src/libs/freetype2/otvalid/otvmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType's OpenType validation module implementation (body). */ /* */ -/* Copyright 2004, 2005 by */ +/* Copyright 2004, 2005, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,10 +39,10 @@ static FT_Error - otv_load_table( FT_Face face, - FT_Tag tag, - FT_Byte* *table, - FT_ULong *table_len ) + otv_load_table( FT_Face face, + FT_Tag tag, + FT_Byte* volatile* table, + FT_ULong* table_len ) { FT_Error error; FT_Memory memory = FT_FACE_MEMORY( face ); @@ -65,18 +65,22 @@ static FT_Error - otv_validate( FT_Face face, - FT_UInt ot_flags, - FT_Bytes *ot_base, - FT_Bytes *ot_gdef, - FT_Bytes *ot_gpos, - FT_Bytes *ot_gsub, - FT_Bytes *ot_jstf ) + otv_validate( FT_Face volatile face, + FT_UInt ot_flags, + FT_Bytes *ot_base, + FT_Bytes *ot_gdef, + FT_Bytes *ot_gpos, + FT_Bytes *ot_gsub, + FT_Bytes *ot_jstf ) { - FT_Error error = OTV_Err_Ok; - FT_Byte *base, *gdef, *gpos, *gsub, *jstf; - FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf; - FT_ValidatorRec valid; + FT_Error error = OTV_Err_Ok; + FT_Byte* volatile base; + FT_Byte* volatile gdef; + FT_Byte* volatile gpos; + FT_Byte* volatile gsub; + FT_Byte* volatile jstf; + FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf; + FT_ValidatorRec volatile valid; base = gdef = gpos = gsub = jstf = NULL; @@ -124,7 +128,7 @@ if ( base ) { ft_validator_init( &valid, base, base + len_base, FT_VALIDATE_DEFAULT ); - if ( ft_validator_run( &valid ) == 0 ) + if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_BASE_validate( base, &valid ); error = valid.error; if ( error ) @@ -134,7 +138,7 @@ if ( gpos ) { ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT ); - if ( ft_validator_run( &valid ) == 0 ) + if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_GPOS_validate( gpos, face->num_glyphs, &valid ); error = valid.error; if ( error ) @@ -144,7 +148,7 @@ if ( gsub ) { ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT ); - if ( ft_validator_run( &valid ) == 0 ) + if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_GSUB_validate( gsub, face->num_glyphs, &valid ); error = valid.error; if ( error ) @@ -154,7 +158,7 @@ if ( gdef ) { ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT ); - if ( ft_validator_run( &valid ) == 0 ) + if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_GDEF_validate( gdef, gsub, gpos, &valid ); error = valid.error; if ( error ) @@ -164,7 +168,7 @@ if ( jstf ) { ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT ); - if ( ft_validator_run( &valid ) == 0 ) + if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_JSTF_validate( jstf, gsub, gpos, face->num_glyphs, &valid ); error = valid.error; if ( error ) @@ -194,14 +198,14 @@ static - const FT_Service_OTvalidateRec otvalid_interface = + const FT_Service_OTvalidateRec otvalid_interface = { otv_validate }; static - const FT_ServiceDescRec otvalid_services[] = + const FT_ServiceDescRec otvalid_services[] = { { FT_SERVICE_ID_OPENTYPE_VALIDATE, &otvalid_interface }, { NULL, NULL } diff --git a/src/libs/freetype2/pcf/README b/src/libs/freetype2/pcf/README index 75f49e1427..2798d27932 100644 --- a/src/libs/freetype2/pcf/README +++ b/src/libs/freetype2/pcf/README @@ -13,11 +13,11 @@ Glyph images are loaded into memory only on demand, thus leading to a small memory footprint. Informations on the PCF font format can only be worked out from -``pcfread.c'', and ``pcfwrite.c'', to be found, for instance, in the XFree86 +`pcfread.c', and `pcfwrite.c', to be found, for instance, in the XFree86 (www.xfree86.org) source tree (xc/lib/font/bitmap/). Many good bitmap fonts in bdf format come with XFree86: they can be -compiled into the pcf format using the ``bdftopcf'' utility. +compiled into the pcf format using the `bdftopcf' utility. Supported hardware @@ -46,11 +46,11 @@ client application the work of interpreting them. For instance: FT_New_Face( library,..., &face ); pcfface = (PCF_Public_Face)face; - - if ((pcfface->charset_registry == "ISO10646") && + + if ((pcfface->charset_registry == "ISO10646") && (pcfface->charset_encoding) == "1")) [..] -Thus the driver always export ``ft_encoding_none'' as +Thus the driver always export `ft_encoding_none' as face->charmap.encoding. FT_Get_Char_Index() behavior is unmodified, that is, it converts the ULong value given as argument into the corresponding glyph number. diff --git a/src/libs/freetype2/pcf/module.mk b/src/libs/freetype2/pcf/module.mk index 5bc7ce3c66..0c51cd6fc4 100644 --- a/src/libs/freetype2/pcf/module.mk +++ b/src/libs/freetype2/pcf/module.mk @@ -4,7 +4,7 @@ # Copyright 2000, 2006 by # Francesco Zappa Nardelli -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights diff --git a/src/libs/freetype2/pcf/pcfdrivr.c b/src/libs/freetype2/pcf/pcfdrivr.c index 91de2b2292..c0f0e49ca1 100644 --- a/src/libs/freetype2/pcf/pcfdrivr.c +++ b/src/libs/freetype2/pcf/pcfdrivr.c @@ -203,19 +203,23 @@ THE SOFTWARE. /* free properties */ { - PCF_Property prop = face->properties; + PCF_Property prop; FT_Int i; - for ( i = 0; i < face->nprops; i++ ) + if ( face->properties ) { - prop = &face->properties[i]; + for ( i = 0; i < face->nprops; i++ ) + { + prop = &face->properties[i]; - FT_FREE( prop->name ); - if ( prop->isString ) - FT_FREE( prop->value.atom ); + if ( prop ) { + FT_FREE( prop->name ); + if ( prop->isString ) + FT_FREE( prop->value.atom ); + } + } } - FT_FREE( face->properties ); } @@ -258,6 +262,8 @@ THE SOFTWARE. FT_Error error2; + PCF_Face_Done( pcfface ); + /* this didn't work, try gzip support! */ error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream ); if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature ) @@ -357,6 +363,7 @@ THE SOFTWARE. Fail: FT_TRACE2(( "[not a valid PCF file]\n" )); + PCF_Face_Done( pcfface ); error = PCF_Err_Unknown_File_Format; /* error */ goto Exit; } @@ -435,7 +442,7 @@ THE SOFTWARE. FT_TRACE4(( "load_glyph %d ---", glyph_index )); - if ( !face ) + if ( !face || glyph_index >= (FT_UInt)face->root.num_glyphs ) { error = PCF_Err_Invalid_Argument; goto Exit; diff --git a/src/libs/freetype2/pcf/pcfread.c b/src/libs/freetype2/pcf/pcfread.c index e775b1abf1..12ff5b3b28 100644 --- a/src/libs/freetype2/pcf/pcfread.c +++ b/src/libs/freetype2/pcf/pcfread.c @@ -2,7 +2,7 @@ FreeType font driver for pcf fonts - Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006 by + Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -102,7 +102,8 @@ THE SOFTWARE. return PCF_Err_Cannot_Open_Resource; if ( toc->version != PCF_FILE_VERSION || - toc->count > FT_ARRAY_MAX( face->toc.tables ) ) + toc->count > FT_ARRAY_MAX( face->toc.tables ) || + toc->count == 0 ) return PCF_Err_Invalid_File_Format; if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) ) @@ -116,6 +117,41 @@ THE SOFTWARE. tables++; } + /* Sort tables and check for overlaps. Because they are almost */ + /* always ordered already, an in-place bubble sort with simultaneous */ + /* boundary checking seems appropriate. */ + tables = face->toc.tables; + + for ( n = 0; n < toc->count - 1; n++ ) + { + FT_UInt i, have_change; + + + have_change = 0; + + for ( i = 0; i < toc->count - 1 - n; i++ ) + { + PCF_TableRec tmp; + + + if ( tables[i].offset > tables[i + 1].offset ) + { + tmp = tables[i]; + tables[i] = tables[i + 1]; + tables[i + 1] = tmp; + + have_change = 1; + } + + if ( ( tables[i].size > tables[i + 1].offset ) || + ( tables[i].offset > tables[i + 1].offset - tables[i].size ) ) + return PCF_Err_Invalid_Offset; + } + + if ( !have_change ) + break; + } + #if defined( FT_DEBUG_LEVEL_TRACE ) { @@ -130,7 +166,8 @@ THE SOFTWARE. tables = face->toc.tables; for ( i = 0; i < toc->count; i++ ) { - for( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); j++ ) + for ( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); + j++ ) if ( tables[i].type == (FT_UInt)( 1 << j ) ) name = tableNames[j]; @@ -153,13 +190,15 @@ THE SOFTWARE. } +#define PCF_METRIC_SIZE 12 + static const FT_Frame_Field pcf_metric_header[] = { #undef FT_STRUCTURE #define FT_STRUCTURE PCF_MetricRec - FT_FRAME_START( 12 ), + FT_FRAME_START( PCF_METRIC_SIZE ), FT_FRAME_SHORT_LE( leftSideBearing ), FT_FRAME_SHORT_LE( rightSideBearing ), FT_FRAME_SHORT_LE( characterWidth ), @@ -176,7 +215,7 @@ THE SOFTWARE. #undef FT_STRUCTURE #define FT_STRUCTURE PCF_MetricRec - FT_FRAME_START( 12 ), + FT_FRAME_START( PCF_METRIC_SIZE ), FT_FRAME_SHORT( leftSideBearing ), FT_FRAME_SHORT( rightSideBearing ), FT_FRAME_SHORT( characterWidth ), @@ -187,13 +226,15 @@ THE SOFTWARE. }; +#define PCF_COMPRESSED_METRIC_SIZE 5 + static const FT_Frame_Field pcf_compressed_metric_header[] = { #undef FT_STRUCTURE #define FT_STRUCTURE PCF_Compressed_MetricRec - FT_FRAME_START( 5 ), + FT_FRAME_START( PCF_COMPRESSED_METRIC_SIZE ), FT_FRAME_BYTE( leftSideBearing ), FT_FRAME_BYTE( rightSideBearing ), FT_FRAME_BYTE( characterWidth ), @@ -221,7 +262,7 @@ THE SOFTWARE. ? pcf_metric_msb_header : pcf_metric_header; - /* the following sets 'error' but doesn't return in case of failure */ + /* the following sets `error' but doesn't return in case of failure */ (void)FT_STREAM_READ_FIELDS( fields, metric ); } else @@ -261,23 +302,26 @@ THE SOFTWARE. for ( i = 0; i < ntables; i++ ) if ( tables[i].type == type ) { - if ( stream->pos > tables[i].offset ) { + if ( stream->pos > tables[i].offset ) + { error = PCF_Err_Invalid_Stream_Skip; goto Fail; } - if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) ) { + if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) ) + { error = PCF_Err_Invalid_Stream_Skip; goto Fail; } - *asize = tables[i].size; /* unused - to be removed */ + *asize = tables[i].size; *aformat = tables[i].format; return PCF_Err_Ok; } Fail: + *asize = 0; return error; } @@ -298,13 +342,15 @@ THE SOFTWARE. } +#define PCF_PROPERTY_SIZE 9 + static const FT_Frame_Field pcf_property_header[] = { #undef FT_STRUCTURE #define FT_STRUCTURE PCF_ParsePropertyRec - FT_FRAME_START( 9 ), + FT_FRAME_START( PCF_PROPERTY_SIZE ), FT_FRAME_LONG_LE( name ), FT_FRAME_BYTE ( isString ), FT_FRAME_LONG_LE( value ), @@ -318,7 +364,7 @@ THE SOFTWARE. #undef FT_STRUCTURE #define FT_STRUCTURE PCF_ParsePropertyRec - FT_FRAME_START( 9 ), + FT_FRAME_START( PCF_PROPERTY_SIZE ), FT_FRAME_LONG( name ), FT_FRAME_BYTE( isString ), FT_FRAME_LONG( value ), @@ -353,8 +399,8 @@ THE SOFTWARE. PCF_Face face ) { PCF_ParseProperty props = 0; - PCF_Property properties = 0; - FT_Int nprops, i; + PCF_Property properties; + FT_UInt nprops, i; FT_ULong format, size; FT_Error error; FT_Memory memory = FT_FACE(face)->memory; @@ -390,6 +436,15 @@ THE SOFTWARE. FT_TRACE4(( " nprop = %d\n", nprops )); + /* rough estimate */ + if ( nprops > size / PCF_PROPERTY_SIZE ) + { + error = PCF_Err_Invalid_Table; + goto Bail; + } + + face->nprops = nprops; + if ( FT_NEW_ARRAY( props, nprops ) ) goto Bail; @@ -427,6 +482,13 @@ THE SOFTWARE. FT_TRACE4(( " string_size = %ld\n", string_size )); + /* rough estimate */ + if ( string_size > size - nprops * PCF_PROPERTY_SIZE ) + { + error = PCF_Err_Invalid_Table; + goto Bail; + } + if ( FT_NEW_ARRAY( strings, string_size ) ) goto Bail; @@ -437,13 +499,24 @@ THE SOFTWARE. if ( FT_NEW_ARRAY( properties, nprops ) ) goto Bail; + face->properties = properties; + for ( i = 0; i < nprops; i++ ) { - /* XXX: make atom */ - if ( FT_NEW_ARRAY( properties[i].name, - ft_strlen( strings + props[i].name ) + 1 ) ) + FT_Long name_offset = props[i].name; + + + if ( ( name_offset < 0 ) || + ( (FT_ULong)name_offset > string_size ) ) + { + error = PCF_Err_Invalid_Offset; goto Bail; - ft_strcpy( properties[i].name, strings + props[i].name ); + } + + if ( FT_NEW_ARRAY( properties[i].name, + ft_strlen( strings + name_offset ) + 1 ) ) + goto Bail; + ft_strcpy( properties[i].name, strings + name_offset ); FT_TRACE4(( " %s:", properties[i].name )); @@ -451,8 +524,18 @@ THE SOFTWARE. if ( props[i].isString ) { + FT_Long value_offset = props[i].value; + + + if ( ( value_offset < 0 ) || + ( (FT_ULong)value_offset > string_size ) ) + { + error = PCF_Err_Invalid_Offset; + goto Bail; + } + if ( FT_NEW_ARRAY( properties[i].value.atom, - ft_strlen( strings + props[i].value ) + 1 ) ) + ft_strlen( strings + value_offset ) + 1 ) ) goto Bail; ft_strcpy( properties[i].value.atom, strings + props[i].value ); @@ -466,13 +549,7 @@ THE SOFTWARE. } } - face->properties = properties; - face->nprops = nprops; - - FT_FREE( props ); - FT_FREE( strings ); - - return PCF_Err_Ok; + error = PCF_Err_Ok; Bail: FT_FREE( props ); @@ -488,11 +565,9 @@ THE SOFTWARE. { FT_Error error = PCF_Err_Ok; FT_Memory memory = FT_FACE(face)->memory; - FT_ULong format = 0; - FT_ULong size = 0; + FT_ULong format, size; PCF_Metric metrics = 0; - int i; - int nmetrics = -1; + FT_ULong nmetrics, i; error = pcf_seek_to_table_type( stream, @@ -504,7 +579,8 @@ THE SOFTWARE. if ( error ) return error; - error = FT_READ_ULONG_LE( format ); + if ( FT_READ_ULONG_LE( format ) ) + goto Bail; if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && !PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) ) @@ -524,16 +600,30 @@ THE SOFTWARE. else (void)FT_READ_USHORT_LE( nmetrics ); } - if ( error || nmetrics == -1 ) + if ( error ) return PCF_Err_Invalid_File_Format; face->nmetrics = nmetrics; + FT_TRACE4(( "pcf_get_metrics:\n" )); + + FT_TRACE4(( " number of metrics: %d\n", nmetrics )); + + /* rough estimate */ + if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + { + if ( nmetrics > size / PCF_METRIC_SIZE ) + return PCF_Err_Invalid_Table; + } + else + { + if ( nmetrics > size / PCF_COMPRESSED_METRIC_SIZE ) + return PCF_Err_Invalid_Table; + } + if ( FT_NEW_ARRAY( face->metrics, nmetrics ) ) return PCF_Err_Out_Of_Memory; - FT_TRACE4(( "pcf_get_metrics:\n" )); - metrics = face->metrics; for ( i = 0; i < nmetrics; i++ ) { @@ -541,7 +631,7 @@ THE SOFTWARE. metrics[i].bits = 0; - FT_TRACE4(( " idx %d: width=%d, " + FT_TRACE5(( " idx %d: width=%d, " "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n", i, ( metrics + i )->characterWidth, @@ -557,6 +647,8 @@ THE SOFTWARE. if ( error ) FT_FREE( face->metrics ); + + Bail: return error; } @@ -597,14 +689,16 @@ THE SOFTWARE. if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) return PCF_Err_Invalid_File_Format; + FT_TRACE4(( "pcf_get_bitmaps:\n" )); + + FT_TRACE4(( " number of bitmaps: %d\n", nbitmaps )); + if ( nbitmaps != face->nmetrics ) return PCF_Err_Invalid_File_Format; if ( FT_NEW_ARRAY( offsets, nbitmaps ) ) return error; - FT_TRACE4(( "pcf_get_bitmaps:\n" )); - for ( i = 0; i < nbitmaps; i++ ) { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) @@ -612,7 +706,7 @@ THE SOFTWARE. else (void)FT_READ_LONG_LE( offsets[i] ); - FT_TRACE4(( " bitmap %d: offset %ld (0x%lX)\n", + FT_TRACE5(( " bitmap %d: offset %ld (0x%lX)\n", i, offsets[i], offsets[i] )); } if ( error ) @@ -640,15 +734,22 @@ THE SOFTWARE. FT_UNUSED( sizebitmaps ); /* only used for debugging */ for ( i = 0; i < nbitmaps; i++ ) - face->metrics[i].bits = stream->pos + offsets[i]; + { + /* rough estimate */ + if ( ( offsets[i] < 0 ) || + ( (FT_ULong)offsets[i] > size ) ) + { + FT_ERROR(( "pcf_get_bitmaps:")); + FT_ERROR(( " invalid offset to bitmap data of glyph %d\n", i )); + } + else + face->metrics[i].bits = stream->pos + offsets[i]; + } face->bitmapsFormat = format; - FT_FREE ( offsets ); - return error; - Bail: - FT_FREE ( offsets ); + FT_FREE( offsets ); return error; } @@ -734,7 +835,7 @@ THE SOFTWARE. tmpEncoding[j].glyph = (FT_Short)encodingOffset; - FT_TRACE4(( " code %d (0x%04X): idx %d\n", + FT_TRACE5(( " code %d (0x%04X): idx %d\n", tmpEncoding[j].enc, tmpEncoding[j].enc, tmpEncoding[j].glyph )); @@ -828,7 +929,8 @@ THE SOFTWARE. if ( error ) goto Bail; - error = FT_READ_ULONG_LE( format ); + if ( FT_READ_ULONG_LE( format ) ) + goto Bail; if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && !PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ) @@ -876,7 +978,6 @@ THE SOFTWARE. accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */ accel->ink_maxbounds = accel->maxbounds; } - return error; Bail: return error; @@ -1082,11 +1183,12 @@ THE SOFTWARE. else root->family_name = NULL; - /* Note: We shift all glyph indices by +1 since we must + /* + * Note: We shift all glyph indices by +1 since we must * respect the convention that glyph 0 always corresponds - * to the "missing glyph". + * to the `missing glyph'. * - * This implies bumping the number of "available" glyphs by 1. + * This implies bumping the number of `available' glyphs by 1. */ root->num_glyphs = face->nmetrics + 1; @@ -1171,7 +1273,7 @@ THE SOFTWARE. Exit: if ( error ) { - /* this is done to respect the behaviour of the original */ + /* This is done to respect the behaviour of the original */ /* PCF font driver. */ error = PCF_Err_Invalid_File_Format; } diff --git a/src/libs/freetype2/pcf/pcfutil.c b/src/libs/freetype2/pcf/pcfutil.c index 67e657908d..67ddbe8890 100644 --- a/src/libs/freetype2/pcf/pcfutil.c +++ b/src/libs/freetype2/pcf/pcfutil.c @@ -2,7 +2,11 @@ Copyright 1990, 1994, 1998 The Open Group -All Rights Reserved. +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -43,12 +47,12 @@ in this Software without prior written authorization from The Open Group. for ( ; --nbytes >= 0; buf++ ) { unsigned int val = *buf; - + val = ( ( val >> 1 ) & 0x55 ) | ( ( val << 1 ) & 0xAA ); val = ( ( val >> 2 ) & 0x33 ) | ( ( val << 2 ) & 0xCC ); val = ( ( val >> 4 ) & 0x0F ) | ( ( val << 4 ) & 0xF0 ); - + *buf = (unsigned char)val; } } diff --git a/src/libs/freetype2/pfr/Jamfile b/src/libs/freetype2/pfr/Jamfile index a95178588b..f21a613545 100644 --- a/src/libs/freetype2/pfr/Jamfile +++ b/src/libs/freetype2/pfr/Jamfile @@ -13,7 +13,7 @@ UseFreeTypeHeaders ; if $(FT2_MULTI) { - _sources = pfrdrivr pfrgload pfrload pfrobjs pfrcmap pfrsbit ; + _sources = pfrdrivr pfrgload pfrload pfrobjs pfrcmap pfrsbit ; } else { diff --git a/src/libs/freetype2/pfr/pfrcmap.c b/src/libs/freetype2/pfr/pfrcmap.c index de6c5a07cf..05fe68fbe9 100644 --- a/src/libs/freetype2/pfr/pfrcmap.c +++ b/src/libs/freetype2/pfr/pfrcmap.c @@ -16,7 +16,7 @@ /***************************************************************************/ -#include "pfrcmap.h" +#include "pfrcmap.h" #include "pfrobjs.h" #include FT_INTERNAL_DEBUG_H @@ -29,12 +29,12 @@ cmap->num_chars = face->phy_font.num_chars; cmap->chars = face->phy_font.chars; - + /* just for safety, check that the character entries are correctly */ /* sorted in increasing character code order */ { FT_UInt n; - + for ( n = 1; n < cmap->num_chars; n++ ) { @@ -42,7 +42,7 @@ FT_ASSERT( 0 ); } } - + return 0; } diff --git a/src/libs/freetype2/pfr/pfrcmap.h b/src/libs/freetype2/pfr/pfrcmap.h index d77813e3c8..a626953054 100644 --- a/src/libs/freetype2/pfr/pfrcmap.h +++ b/src/libs/freetype2/pfr/pfrcmap.h @@ -31,7 +31,7 @@ FT_BEGIN_HEADER FT_CMapRec cmap; FT_UInt num_chars; PFR_Char chars; - + } PFR_CMapRec, *PFR_CMap; diff --git a/src/libs/freetype2/pfr/pfrload.h b/src/libs/freetype2/pfr/pfrload.h index 9e54b7d3fd..ed010715d1 100644 --- a/src/libs/freetype2/pfr/pfrload.h +++ b/src/libs/freetype2/pfr/pfrload.h @@ -54,11 +54,11 @@ FT_BEGIN_HEADER { FT_UInt type; PFR_ExtraItem_ParseFunc parser; - + } PFR_ExtraItemRec; - + typedef const struct PFR_ExtraItemRec_* PFR_ExtraItem; - + FT_LOCAL( FT_Error ) pfr_extra_items_skip( FT_Byte* *pp, @@ -109,7 +109,7 @@ FT_BEGIN_HEADER FT_Memory memory ); /* */ - + FT_END_HEADER #endif /* __PFRLOAD_H__ */ diff --git a/src/libs/freetype2/pfr/pfrobjs.c b/src/libs/freetype2/pfr/pfrobjs.c index 6c0ce903fd..180446d737 100644 --- a/src/libs/freetype2/pfr/pfrobjs.c +++ b/src/libs/freetype2/pfr/pfrobjs.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR object methods (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, */ @@ -122,15 +122,29 @@ if ( error ) goto Exit; - /* now, set-up all root face fields */ + /* now set up all root face fields */ { PFR_PhyFont phy_font = &face->phy_font; pfrface->face_index = face_index; - pfrface->num_glyphs = phy_font->num_chars; + pfrface->num_glyphs = phy_font->num_chars + 1; pfrface->face_flags = FT_FACE_FLAG_SCALABLE; + /* if all characters point to the same gps_offset 0, we */ + /* assume that the font only contains bitmaps */ + { + FT_UInt nn; + + + for ( nn = 0; nn < phy_font->num_chars; nn++ ) + if ( phy_font->chars[nn].gps_offset != 0 ) + break; + + if ( nn == phy_font->num_chars ) + pfrface->face_flags = 0; /* not scalable */ + } + if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 ) pfrface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; @@ -296,8 +310,11 @@ if ( gindex > 0 ) gindex--; - /* check that the glyph index is correct */ - FT_ASSERT( gindex < face->phy_font.num_chars ); + if ( !face || gindex >= face->phy_font.num_chars ) + { + error = PFR_Err_Invalid_Argument; + goto Exit; + } /* try to load an embedded bitmap */ if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 ) @@ -476,13 +493,14 @@ goto Exit; { - FT_UInt count = item->pair_count; - FT_UInt size = item->pair_size; - FT_UInt power = (FT_UInt)ft_highpow2( (FT_UInt32)count ); - FT_UInt probe = power * size; - FT_UInt extra = count - power; - FT_Byte* base = stream->cursor; - FT_Bool twobytes = FT_BOOL( item->flags & 1 ); + FT_UInt count = item->pair_count; + FT_UInt size = item->pair_size; + FT_UInt power = (FT_UInt)ft_highpow2( (FT_UInt32)count ); + FT_UInt probe = power * size; + FT_UInt extra = count - power; + FT_Byte* base = stream->cursor; + FT_Bool twobytes = FT_BOOL( item->flags & 1 ); + FT_Bool twobyte_adj = FT_BOOL( item->flags & 2 ); FT_Byte* p; FT_UInt32 cpair; @@ -500,7 +518,13 @@ goto Found; if ( cpair < pair ) + { + if ( twobyte_adj ) + p += 2; + else + p++; base = p; + } } while ( probe > size ) @@ -533,7 +557,7 @@ Found: - if ( item->flags & 2 ) + if ( twobyte_adj ) value = FT_PEEK_SHORT( p ); else value = p[0]; diff --git a/src/libs/freetype2/psaux/psconv.c b/src/libs/freetype2/psaux/psconv.c index 010d08cb53..3bbeab6d25 100644 --- a/src/libs/freetype2/psaux/psconv.c +++ b/src/libs/freetype2/psaux/psconv.c @@ -331,11 +331,53 @@ FT_UInt n ) { FT_Byte* p; - FT_UInt r = 0; + FT_UInt r = 0; + FT_UInt w = 0; + FT_UInt pad = 0x01; n *= 2; - for ( p = *cursor; r < n && p < limit; p++ ) + +#if 1 + + p = *cursor; + if ( n > (FT_UInt)( limit - p ) ) + n = (FT_UInt)( limit - p ); + + /* we try to process two nibbles at a time to be as fast as possible */ + for ( ; r < n; r++ ) + { + FT_UInt c = p[r]; + + + if ( IS_PS_SPACE( c ) ) + continue; + + if ( c OP 0x80 ) + break; + + c = ft_char_table[c & 0x7F]; + if ( (unsigned)c >= 16 ) + break; + + pad = ( pad << 4 ) | c; + if ( pad & 0x100 ) + { + buffer[w++] = (FT_Byte)pad; + pad = 0x01; + } + } + + if ( pad != 0x01 ) + buffer[w++] = (FT_Byte)( pad << 4 ); + + *cursor = p + r; + + return w; + +#else /* 0 */ + + for ( r = 0; r < n; r++ ) { FT_Char c; @@ -348,10 +390,10 @@ c = ft_char_table[*p & 0x7f]; - if ( c < 0 || c >= 16 ) + if ( (unsigned)c >= 16 ) break; - if ( r % 2 ) + if ( r & 1 ) { *buffer = (FT_Byte)(*buffer + c); buffer++; @@ -365,6 +407,9 @@ *cursor = p; return ( r + 1 ) / 2; + +#endif /* 0 */ + } @@ -375,11 +420,32 @@ FT_UInt n, FT_UShort* seed ) { - FT_Byte* p; - FT_UInt r; - FT_UShort s = *seed; + FT_Byte* p; + FT_UInt r; + FT_UInt s = *seed; +#if 1 + + p = *cursor; + if ( n > (FT_UInt)(limit - p) ) + n = (FT_UInt)(limit - p); + + for ( r = 0; r < n; r++ ) + { + FT_UInt val = p[r]; + FT_UInt b = ( val ^ ( s >> 8 ) ); + + + s = ( (val + s)*52845U + 22719 ) & 0xFFFFU; + buffer[r] = (FT_Byte) b; + } + + *cursor = p + n; + *seed = (FT_UShort)s; + +#else /* 0 */ + for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ ) { FT_Byte b = (FT_Byte)( *p ^ ( s >> 8 ) ); @@ -388,10 +454,11 @@ s = (FT_UShort)( ( *p + s ) * 52845U + 22719 ); *buffer++ = b; } - *cursor = p; *seed = s; +#endif /* 0 */ + return r; } diff --git a/src/libs/freetype2/psaux/psconv.h b/src/libs/freetype2/psaux/psconv.h index 82c370787f..e51124185d 100644 --- a/src/libs/freetype2/psaux/psconv.h +++ b/src/libs/freetype2/psaux/psconv.h @@ -63,42 +63,6 @@ FT_BEGIN_HEADER FT_UShort* seed ); -#define IS_PS_NEWLINE( ch ) \ - ( ( ch ) == '\r' || \ - ( ch ) == '\n' ) - -#define IS_PS_SPACE( ch ) \ - ( ( ch ) == ' ' || \ - IS_PS_NEWLINE( ch ) || \ - ( ch ) == '\t' || \ - ( ch ) == '\f' || \ - ( ch ) == '\0' ) - -#define IS_PS_SPECIAL( ch ) \ - ( ( ch ) == '/' || \ - ( ch ) == '(' || \ - ( ch ) == ')' || \ - ( ch ) == '<' || \ - ( ch ) == '>' || \ - ( ch ) == '[' || \ - ( ch ) == ']' || \ - ( ch ) == '{' || \ - ( ch ) == '}' || \ - ( ch ) == '%' ) - -#define IS_PS_DELIM( ch ) \ - ( IS_PS_SPACE( ch ) || \ - IS_PS_SPECIAL( ch ) ) - -#define IS_PS_DIGIT( ch ) ( ( ch ) >= '0' && ( ch ) <= '9' ) - -#define IS_PS_XDIGIT( ch ) \ - ( IS_PS_DIGIT( ( ch ) ) || \ - ( ( ch ) >= 'A' && ( ch ) <= 'F' ) || \ - ( ( ch ) >= 'a' && ( ch ) <= 'f' ) ) - -#define IS_PS_BASE85( ch ) ( ( ch ) >= '!' && ( ch ) <= 'u' ) - FT_END_HEADER #endif /* __PSCONV_H__ */ diff --git a/src/libs/freetype2/psaux/psobjs.c b/src/libs/freetype2/psaux/psobjs.c index 2b2892f3c4..3fb46afdb1 100644 --- a/src/libs/freetype2/psaux/psobjs.c +++ b/src/libs/freetype2/psaux/psobjs.c @@ -26,6 +26,16 @@ #include "psauxerr.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_psobjs + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -118,7 +128,7 @@ } /* copy elements and shift offsets */ - if (old_base ) + if ( old_base ) { FT_MEM_COPY( table->block, old_base, table->capacity ); shift_elements( table, old_base ); @@ -312,45 +322,94 @@ } - /* first character must be `(' */ +#define IS_OCTAL_DIGIT( c ) ( '0' <= (c) && (c) <= '7' ) - static void + + /* first character must be `('; */ + /* *acur is positioned at the character after the closing `)' */ + + static FT_Error skip_literal_string( FT_Byte* *acur, FT_Byte* limit ) { - FT_Byte* cur = *acur; - FT_Int embed = 0; + FT_Byte* cur = *acur; + FT_Int embed = 0; + FT_Error error = PSaux_Err_Invalid_File_Format; + unsigned int i; while ( cur < limit ) { - if ( *cur == '\\' ) - cur++; - else if ( *cur == '(' ) + FT_Byte c = *cur; + + + ++cur; + + if ( c == '\\' ) + { + /* Red Book 3rd ed., section `Literal Text Strings', p. 29: */ + /* A backslash can introduce three different types */ + /* of escape sequences: */ + /* - a special escaped char like \r, \n, etc. */ + /* - a one-, two-, or three-digit octal number */ + /* - none of the above in which case the backslash is ignored */ + + if ( cur == limit ) + /* error (or to be ignored?) */ + break; + + switch ( *cur ) + { + /* skip `special' escape */ + case 'n': + case 'r': + case 't': + case 'b': + case 'f': + case '\\': + case '(': + case ')': + ++cur; + break; + + default: + /* skip octal escape or ignore backslash */ + for ( i = 0; i < 3 && cur < limit; ++i ) + { + if ( ! IS_OCTAL_DIGIT( *cur ) ) + break; + + ++cur; + } + } + } + else if ( c == '(' ) embed++; - else if ( *cur == ')' ) + else if ( c == ')' ) { embed--; if ( embed == 0 ) { - cur++; + error = PSaux_Err_Ok; break; } } - cur++; } *acur = cur; + + return error; } /* first character must be `<' */ - static void - skip_string( PS_Parser parser ) + static FT_Error + skip_string( FT_Byte* *acur, + FT_Byte* limit ) { - FT_Byte* cur = parser->cursor; - FT_Byte* limit = parser->limit; + FT_Byte* cur = *acur; + FT_Error err = PSaux_Err_Ok; while ( ++cur < limit ) @@ -367,12 +426,72 @@ if ( cur < limit && *cur != '>' ) { FT_ERROR(( "skip_string: missing closing delimiter `>'\n" )); - parser->error = PSaux_Err_Invalid_File_Format; + err = PSaux_Err_Invalid_File_Format; } else cur++; - parser->cursor = cur; + *acur = cur; + return err; + } + + + /* first character must be the opening brace that */ + /* starts the procedure */ + + /* NB: [ and ] need not match: */ + /* `/foo {[} def' is a valid PostScript fragment, */ + /* even within a Type1 font */ + + static FT_Error + skip_procedure( FT_Byte* *acur, + FT_Byte* limit ) + { + FT_Byte* cur; + FT_Int embed = 0; + FT_Error error = PSaux_Err_Ok; + + + FT_ASSERT( **acur == '{' ); + + for ( cur = *acur; cur < limit && error == PSaux_Err_Ok; ++cur ) + { + switch ( *cur ) + { + case '{': + ++embed; + break; + + case '}': + --embed; + if ( embed == 0 ) + { + ++cur; + goto end; + } + break; + + case '(': + error = skip_literal_string( &cur, limit ); + break; + + case '<': + error = skip_string( &cur, limit ); + break; + + case '%': + skip_comment( &cur, limit ); + break; + } + } + + end: + if ( embed != 0 ) + error = PSaux_Err_Invalid_File_Format; + + *acur = cur; + + return error; } @@ -393,6 +512,7 @@ FT_Byte* cur = parser->cursor; FT_Byte* limit = parser->limit; + FT_Error error = PSaux_Err_Ok; skip_spaces( &cur, limit ); /* this also skips comments */ @@ -400,16 +520,23 @@ goto Exit; /* self-delimiting, single-character tokens */ - if ( *cur == '[' || *cur == ']' || - *cur == '{' || *cur == '}' ) + if ( *cur == '[' || *cur == ']' ) { cur++; goto Exit; } + /* skip balanced expressions (procedures and strings) */ + + if ( *cur == '{' ) /* {...} */ + { + error = skip_procedure( &cur, limit ); + goto Exit; + } + if ( *cur == '(' ) /* (...) */ { - skip_literal_string( &cur, limit ); + error = skip_literal_string( &cur, limit ); goto Exit; } @@ -419,11 +546,11 @@ { cur++; cur++; - goto Exit; } - parser->cursor = cur; - skip_string( parser ); - return; + else + error = skip_string( &cur, limit ); + + goto Exit; } if ( *cur == '>' ) @@ -433,7 +560,7 @@ { FT_ERROR(( "ps_parser_skip_PS_token: " "unexpected closing delimiter `>'\n" )); - parser->error = PSaux_Err_Invalid_File_Format; + error = PSaux_Err_Invalid_File_Format; goto Exit; } cur++; @@ -446,20 +573,27 @@ /* anything else */ while ( cur < limit ) { - if ( *cur == ')' ) - { - FT_ERROR(( "ps_parser_skip_PS_token: " - "unexpected closing delimiter `)'\n" )); - parser->error = PSaux_Err_Invalid_File_Format; - goto Exit; - } - else if ( IS_PS_DELIM( *cur ) ) + /* *cur might be invalid (e.g., ')' or '}'), but this */ + /* is handled by the test `cur == parser->cursor' below */ + if ( IS_PS_DELIM( *cur ) ) break; cur++; } Exit: + if ( cur == parser->cursor ) + { + FT_ERROR(( "ps_parser_skip_PS_token: " + "current token is `%c', which is self-delimiting " + "but invalid at this point\n", + *cur )); + + error = PSaux_Err_Invalid_File_Format; + } + + FT_ASSERT( parser->error == PSaux_Err_Ok ); + parser->error = error; parser->cursor = cur; } @@ -480,7 +614,6 @@ { FT_Byte* cur; FT_Byte* limit; - FT_Byte starter, ender; FT_Int embed; @@ -503,26 +636,27 @@ case '(': token->type = T1_TOKEN_TYPE_STRING; token->start = cur; - skip_literal_string( &cur, limit ); - if ( cur < limit ) + + if ( skip_literal_string( &cur, limit ) == PSaux_Err_Ok ) token->limit = cur; break; /************* check for programs/array *****************/ case '{': - token->type = T1_TOKEN_TYPE_ARRAY; - ender = '}'; - goto Lookup_Ender; + token->type = T1_TOKEN_TYPE_ARRAY; + token->start = cur; + + if ( skip_procedure( &cur, limit ) == PSaux_Err_Ok ) + token->limit = cur; + break; /************* check for table/array ********************/ + /* XXX: in theory we should also look for "<<" */ + /* since this is semantically equivalent to "["; */ + /* in practice it doesn't matter (?) */ case '[': - token->type = T1_TOKEN_TYPE_ARRAY; - ender = ']'; - /* fall through */ - - Lookup_Ender: + token->type = T1_TOKEN_TYPE_ARRAY; embed = 1; - starter = *cur; token->start = cur++; /* we need this to catch `[ ]' */ @@ -532,9 +666,11 @@ while ( cur < limit && !parser->error ) { - if ( *cur == starter ) + /* XXX: this is wrong because it does not */ + /* skip comments, procedures, and strings */ + if ( *cur == '[' ) embed++; - else if ( *cur == ender ) + else if ( *cur == ']' ) { embed--; if ( embed <= 0 ) @@ -555,7 +691,7 @@ /* ************ otherwise, it is any token **************/ default: token->start = cur; - token->type = T1_TOKEN_TYPE_ANY; + token->type = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY ); ps_parser_skip_PS_token( parser ); cur = parser->cursor; if ( !parser->error ) @@ -572,6 +708,9 @@ } + /* NB: `tokens' can be NULL if we only want to count */ + /* the number of array elements */ + FT_LOCAL_DEF( void ) ps_parser_to_token_array( PS_Parser parser, T1_Token tokens, @@ -607,7 +746,7 @@ if ( !token.type ) break; - if ( cur < limit ) + if ( tokens != NULL && cur < limit ) *cur = token; cur++; @@ -622,6 +761,8 @@ /* first character must be a delimiter or a part of a number */ + /* NB: `coords' can be NULL if we just want to skip the */ + /* array; in this case we ignore `max_coords' */ static FT_Int ps_tocoordarray( FT_Byte* *acur, @@ -654,21 +795,26 @@ /* now, read the coordinates */ while ( cur < limit ) { + FT_Short dummy; + + /* skip whitespace in front of data */ skip_spaces( &cur, limit ); if ( cur >= limit ) goto Exit; - if ( count >= max_coords ) + if ( coords != NULL && count >= max_coords ) break; - if ( c == ender ) + if ( *cur == ender ) { cur++; break; } - coords[count] = + /* call PS_Conv_ToFixed() even if coords == NULL */ + /* to properly parse number at `cur' */ + *( coords != NULL ? &coords[count] : &dummy ) = (FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 ); count++; @@ -683,6 +829,8 @@ /* first character must be a delimiter or a part of a number */ + /* NB: `values' can be NULL if we just want to skip the */ + /* array in this case we ignore `max_values' */ static FT_Int ps_tofixedarray( FT_Byte* *acur, @@ -716,21 +864,27 @@ /* now, read the values */ while ( cur < limit ) { + FT_Fixed dummy; + + /* skip whitespace in front of data */ skip_spaces( &cur, limit ); if ( cur >= limit ) goto Exit; - if ( count >= max_values ) + if ( values != NULL && count >= max_values ) break; - if ( c == ender ) + if ( *cur == ender ) { cur++; break; } - values[count] = PS_Conv_ToFixed( &cur, limit, power_ten ); + /* call PS_Conv_ToFixed() even if coords == NULL */ + /* to properly parse number at `cur' */ + *( values != NULL ? &values[count] : &dummy ) = + PS_Conv_ToFixed( &cur, limit, power_ten ); count++; if ( !ender ) @@ -957,18 +1111,41 @@ if ( cur >= limit ) break; - if ( field->type == T1_FIELD_TYPE_KEY ) + /* we allow both a string or a name */ + /* for cases like /FontName (foo) def */ + if ( token.type == T1_TOKEN_TYPE_KEY ) { /* don't include leading `/' */ len--; cur++; } - else + else if ( token.type == T1_TOKEN_TYPE_STRING ) { - /* don't include delimiting parentheses */ + /* don't include delimiting parentheses */ + /* XXX we don't handle <<...>> here */ + /* XXX should we convert octal escapes? */ + /* if so, what encoding should we use? */ cur++; len -= 2; } + else + { + FT_ERROR(( "ps_parser_load_field: expected a name or string " + "but found token of type %d instead\n", + token.type )); + error = PSaux_Err_Invalid_File_Format; + goto Exit; + } + + /* for this to work (FT_String**)q must have been */ + /* initialized to NULL */ + if ( *(FT_String**)q != NULL ) + { + FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n", + field->ident )); + FT_FREE( *(FT_String**)q ); + *(FT_String**)q = NULL; + } if ( FT_ALLOC( string, len + 1 ) ) goto Exit; @@ -1038,11 +1215,10 @@ T1_FieldRec fieldrec = *(T1_Field)field; -#if 1 fieldrec.type = T1_FIELD_TYPE_INTEGER; - if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY ) + if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY || + field->type == T1_FIELD_TYPE_BBOX ) fieldrec.type = T1_FIELD_TYPE_FIXED; -#endif ps_parser_to_token_array( parser, elements, T1_MAX_TABLE_ELEMENTS, &num_elements ); @@ -1057,9 +1233,10 @@ old_cursor = parser->cursor; old_limit = parser->limit; - /* we store the elements count */ - *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) = - (FT_Byte)num_elements; + /* we store the elements count if necessary */ + if ( field->type != T1_FIELD_TYPE_BBOX ) + *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) = + (FT_Byte)num_elements; /* we now load each element, adjusting the field.offset on each one */ token = elements; @@ -1105,8 +1282,8 @@ { FT_Error error = PSaux_Err_Ok; FT_Byte* cur; - - + + ps_parser_skip_spaces( parser ); cur = parser->cursor; diff --git a/src/libs/freetype2/psaux/t1cmap.c b/src/libs/freetype2/psaux/t1cmap.c index 79e58dde43..2934686966 100644 --- a/src/libs/freetype2/psaux/t1cmap.c +++ b/src/libs/freetype2/psaux/t1cmap.c @@ -276,7 +276,8 @@ return psnames->unicodes_init( memory, unicodes, face->type1.num_glyphs, - (PS_Glyph_NameFunc)&t1_get_glyph_name, + (PS_GetGlyphNameFunc)&t1_get_glyph_name, + (PS_FreeGlyphNameFunc)NULL, (FT_Pointer)face ); } diff --git a/src/libs/freetype2/psaux/t1decode.c b/src/libs/freetype2/psaux/t1decode.c index cf4bcc52f6..4373d6fa1e 100644 --- a/src/libs/freetype2/psaux/t1decode.c +++ b/src/libs/freetype2/psaux/t1decode.c @@ -4,7 +4,7 @@ /* */ /* PostScript Type 1 decoding routines (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -65,6 +65,7 @@ op_pop, op_return, op_setcurrentpoint, + op_unknown15, op_max /* never remove this one */ @@ -99,7 +100,8 @@ 1, /* callsubr */ 0, /* pop */ 0, /* return */ - 2 /* setcurrentpoint */ + 2, /* setcurrentpoint */ + 2 /* opcode 15 (undocumented and obsolete) */ }; @@ -323,6 +325,8 @@ FT_Byte* limit; T1_Builder builder = &decoder->builder; FT_Pos x, y, orig_x, orig_y; + FT_Int known_othersubr_result_cnt = 0; + FT_Int unknown_othersubr_result_cnt = 0; T1_Hints_Funcs hinter; @@ -344,6 +348,19 @@ hinter = (T1_Hints_Funcs)builder->hints_funcs; + /* a font that reads BuildCharArray without setting */ + /* its values first is buggy, but ... */ + FT_ASSERT( ( decoder->len_buildchar == 0 ) == + ( decoder->buildchar == NULL ) ); + + if ( decoder->len_buildchar > 0 ) + memset( &decoder->buildchar[0], + 0, + sizeof( decoder->buildchar[0] ) * + decoder->len_buildchar ); + + FT_TRACE4(( "\nStart charstring\n" )); + zone->base = charstring_base; limit = zone->limit = charstring_base + charstring_len; ip = zone->cursor = zone->base; @@ -365,6 +382,11 @@ FT_Long value = 0; + FT_ASSERT( known_othersubr_result_cnt == 0 || + unknown_othersubr_result_cnt == 0 ); + + FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); + /*********************************************************************/ /* */ /* Decode operator or operand */ @@ -414,7 +436,7 @@ break; case 15: /* undocumented, obsolete operator */ - op = op_none; + op = op_unknown15; break; case 21: @@ -520,6 +542,23 @@ } } + if ( unknown_othersubr_result_cnt > 0 ) + { + switch ( op ) + { + case op_callsubr: + case op_return: + case op_none: + case op_pop: + break; + + default: + /* all operands have been transferred by previous pops */ + unknown_othersubr_result_cnt = 0; + break; + } + } + /*********************************************************************/ /* */ /* Push value on stack, or process operator */ @@ -540,16 +579,59 @@ } else if ( op == op_callothersubr ) /* callothersubr */ { + FT_Int subr_no; + FT_Int arg_cnt; + + FT_TRACE4(( " callothersubr" )); if ( top - decoder->stack < 2 ) goto Stack_Underflow; top -= 2; - switch ( (FT_Int)top[1] ) + + subr_no = (FT_Int)top[1]; + arg_cnt = (FT_Int)top[0]; + + /***********************************************************/ + /* */ + /* remove all operands to callothersubr from the stack */ + /* */ + /* for handled othersubrs, where we know the number of */ + /* arguments, we increase the stack by the value of */ + /* known_othersubr_result_cnt */ + /* */ + /* for unhandled othersubrs the following pops adjust the */ + /* stack pointer as necessary */ + + if ( arg_cnt > top - decoder->stack ) + goto Stack_Underflow; + + top -= arg_cnt; + + known_othersubr_result_cnt = 0; + unknown_othersubr_result_cnt = 0; + + /* XXX TODO: The checks to `arg_count == <whatever>' */ + /* might not be correct; an othersubr expects a certain */ + /* number of operands on the PostScript stack (as opposed */ + /* to the T1 stack) but it doesn't have to put them there */ + /* by itself; previous othersubrs might have left the */ + /* operands there if they were not followed by an */ + /* appropriate number of pops */ + /* */ + /* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */ + /* accept a font that contains charstrings like */ + /* */ + /* 100 200 2 20 callothersubr */ + /* 300 1 20 callothersubr pop */ + /* */ + /* Perhaps this is the reason why BuildCharArray exists. */ + + switch ( subr_no ) { case 1: /* start flex feature */ - if ( top[0] != 0 ) + if ( arg_cnt != 0 ) goto Unexpected_OtherSubr; decoder->flex_state = 1; @@ -564,7 +646,7 @@ FT_Int idx; - if ( top[0] != 0 ) + if ( arg_cnt != 0 ) goto Unexpected_OtherSubr; /* note that we should not add a point for index 0; */ @@ -580,7 +662,7 @@ break; case 0: /* end flex feature */ - if ( top[0] != 3 ) + if ( arg_cnt != 3 ) goto Unexpected_OtherSubr; if ( decoder->flex_state == 0 || @@ -591,40 +673,15 @@ goto Syntax_Error; } - /* now consume the remaining `pop pop setcurpoint' */ - if ( ip + 6 > limit || - ip[0] != 12 || ip[1] != 17 || /* pop */ - ip[2] != 12 || ip[3] != 17 || /* pop */ - ip[4] != 12 || ip[5] != 33 ) /* setcurpoint */ - { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid flex charstring\n" )); - goto Syntax_Error; - } - - ip += 6; - decoder->flex_state = 0; + /* the two `results' are popped by the following setcurrentpoint */ + known_othersubr_result_cnt = 2; break; case 3: /* change hints */ - if ( top[0] != 1 ) + if ( arg_cnt != 1 ) goto Unexpected_OtherSubr; - /* eat the following `pop' */ - if ( ip + 2 > limit ) - { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid escape (12+%d)\n", ip[-1] )); - goto Syntax_Error; - } - - if ( ip[0] != 12 || ip[1] != 17 ) - { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "`pop' expected, found (%d %d)\n", ip[0], ip[1] )); - goto Syntax_Error; - } - ip += 2; + known_othersubr_result_cnt = 1; if ( hinter ) hinter->reset( hinter->hints, builder->current->n_points ); @@ -656,18 +713,14 @@ goto Syntax_Error; } - num_points = (FT_UInt)top[1] - 13 + ( top[1] == 18 ); - if ( top[0] != (FT_Int)( num_points * blend->num_designs ) ) + num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 ); + if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) ) { FT_ERROR(( "t1_decoder_parse_charstrings: " )); FT_ERROR(( "incorrect number of mm arguments\n" )); goto Syntax_Error; } - top -= blend->num_designs * num_points; - if ( top < decoder->stack ) - goto Stack_Underflow; - /* we want to compute: */ /* */ /* a0*w0 + a1*w1 + ... + ak*wk */ @@ -695,16 +748,178 @@ *values++ = tmp; } - /* note that `top' will be incremented later by calls to `pop' */ + + known_othersubr_result_cnt = num_points; break; } +#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS + + /* We cannot yet enable these since currently */ + /* our T1 stack stores integers which lack the */ + /* precision to express the values */ + + case 19: + /* <idx> 1 19 callothersubr */ + /* => replace elements starting from index cvi( <idx> ) */ + /* of BuildCharArray with WeightVector */ + { + FT_Int idx; + PS_Blend blend = decoder->blend; + + + if ( arg_cnt != 1 || blend == NULL ) + goto Unexpected_OtherSubr; + + idx = top[0]; + + if ( idx < 0 || + idx + blend->num_designs > decoder->face->len_buildchar ) + goto Unexpected_OtherSubr; + + memcpy( &decoder->buildchar[idx], + blend->weight_vector, + blend->num_designs * + sizeof( blend->weight_vector[ 0 ] ) ); + } + break; + + case 20: + /* <arg1> <arg2> 2 20 callothersubr pop */ + /* ==> push <arg1> + <arg2> onto T1 stack */ + if ( arg_cnt != 2 ) + goto Unexpected_OtherSubr; + + top[0] += top[1]; /* XXX (over|under)flow */ + + known_othersubr_result_cnt = 1; + break; + + case 21: + /* <arg1> <arg2> 2 21 callothersubr pop */ + /* ==> push <arg1> - <arg2> onto T1 stack */ + if ( arg_cnt != 2 ) + goto Unexpected_OtherSubr; + + top[0] -= top[1]; /* XXX (over|under)flow */ + + known_othersubr_result_cnt = 1; + break; + + case 22: + /* <arg1> <arg2> 2 22 callothersubr pop */ + /* ==> push <arg1> * <arg2> onto T1 stack */ + if ( arg_cnt != 2 ) + goto Unexpected_OtherSubr; + + top[0] *= top[1]; /* XXX (over|under)flow */ + + known_othersubr_result_cnt = 1; + break; + + case 23: + /* <arg1> <arg2> 2 23 callothersubr pop */ + /* ==> push <arg1> / <arg2> onto T1 stack */ + if ( arg_cnt != 2 || top[1] == 0 ) + goto Unexpected_OtherSubr; + + top[0] /= top[1]; /* XXX (over|under)flow */ + + known_othersubr_result_cnt = 1; + break; + +#endif /* CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS */ + + case 24: + /* <val> <idx> 2 24 callothersubr */ + /* => set BuildCharArray[cvi( <idx> )] = <val> */ + { + FT_Int idx; + PS_Blend blend = decoder->blend; + + if ( arg_cnt != 2 || blend == NULL ) + goto Unexpected_OtherSubr; + + idx = top[1]; + + if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) + goto Unexpected_OtherSubr; + + decoder->buildchar[idx] = top[0]; + } + break; + + case 25: + /* <idx> 1 25 callothersubr pop */ + /* => push BuildCharArray[cvi( idx )] */ + /* onto T1 stack */ + { + FT_Int idx; + PS_Blend blend = decoder->blend; + + if ( arg_cnt != 1 || blend == NULL ) + goto Unexpected_OtherSubr; + + idx = top[0]; + + if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) + goto Unexpected_OtherSubr; + + top[0] = decoder->buildchar[idx]; + } + + known_othersubr_result_cnt = 1; + break; + +#if 0 + case 26: + /* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */ + /* leave mark on T1 stack */ + /* <val> <idx> ==> set BuildCharArray[cvi( <idx> )] = <val> */ + XXX who has left his mark on the (PostScript) stack ?; + break; +#endif + + case 27: + /* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */ + /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */ + /* otherwise push <res2> */ + if ( arg_cnt != 4 ) + goto Unexpected_OtherSubr; + + if ( top[2] > top[3] ) + top[0] = top[1]; + + known_othersubr_result_cnt = 1; + break; + +#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS + case 28: + /* 0 28 callothersubr pop */ + /* => push random value from interval [0, 1) onto stack */ + if ( arg_cnt != 0 ) + goto Unexpected_OtherSubr; + + top[0] = FT_rand(); + known_othersubr_result_cnt = 1; + break; +#endif + default: + FT_ERROR(( "t1_decoder_parse_charstrings: " + "unknown othersubr [%d %d], wish me luck!\n", + arg_cnt, subr_no )); + unknown_othersubr_result_cnt = arg_cnt; + break; + Unexpected_OtherSubr: FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid othersubr [%d %d]!\n", top[0], top[1] )); + "invalid othersubr [%d %d]!\n", arg_cnt, subr_no )); goto Syntax_Error; } + + top += known_othersubr_result_cnt; + decoder->top = top; } else /* general operator */ @@ -712,9 +927,38 @@ FT_Int num_args = t1_args_count[op]; + FT_ASSERT( num_args >= 0 ); + if ( top - decoder->stack < num_args ) goto Stack_Underflow; + /* XXX Operators usually take their operands from the */ + /* bottom of the stack, i.e., the operands are */ + /* decoder->stack[0], ..., decoder->stack[num_args - 1]; */ + /* only div, callsubr, and callothersubr are different. */ + /* In practice it doesn't matter (?). */ + +#ifdef FT_DEBUG_LEVEL_TRACE + + switch ( op ) + { + case op_callsubr: + case op_div: + case op_callothersubr: + case op_pop: + case op_return: + break; + + default: + if ( top - decoder->stack != num_args ) + FT_TRACE0(( "\nMore operands on the stack than expected " + "(have %d, expected %d)\n", + top - decoder->stack, num_args )); + break; + } + +#endif /* FT_DEBUG_LEVEL_TRACE */ + top -= num_args; switch ( op ) @@ -740,8 +984,30 @@ /* add current outline to the glyph slot */ FT_GlyphLoader_Add( builder->loader ); + FT_TRACE4(( "\n" )); + + /* the compiler should optimize away this empty loop but ... */ + +#ifdef FT_DEBUG_LEVEL_TRACE + + if ( decoder->len_buildchar > 0 ) + { + FT_UInt i; + + + FT_TRACE4(( "BuildCharArray = [ " )); + + for ( i = 0; i < decoder->len_buildchar; ++i ) + FT_TRACE4(( "%d ", decoder->buildchar[ i ] )); + + FT_TRACE4(( "]\n" )); + } + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + FT_TRACE4(( "\n" )); + /* return now! */ - FT_TRACE4(( "\n\n" )); return PSaux_Err_Ok; case op_hsbw: @@ -997,8 +1263,22 @@ case op_pop: FT_TRACE4(( " pop" )); - /* theoretically, the arguments are already on the stack */ - top++; + if ( known_othersubr_result_cnt > 0 ) + { + known_othersubr_result_cnt--; + /* ignore, we pushed the operands ourselves */ + break; + } + + if ( unknown_othersubr_result_cnt == 0 ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: " + "no more operands for othersubr!\n" )); + goto Syntax_Error; + } + + unknown_othersubr_result_cnt--; + top++; /* `push' the operand to callothersubr onto the stack */ break; case op_return: @@ -1073,9 +1353,27 @@ case op_setcurrentpoint: FT_TRACE4(( " setcurrentpoint" )); - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "unexpected `setcurrentpoint'\n" )); - goto Syntax_Error; + /* From the T1 specs, section 6.4: */ + /* */ + /* The setcurrentpoint command is used only in */ + /* conjunction with results from OtherSubrs procedures. */ + + /* known_othersubr_result_cnt != 0 is already handled above */ + if ( decoder->flex_state != 1 ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: " )); + FT_ERROR(( "unexpected `setcurrentpoint'\n" )); + + goto Syntax_Error; + } + else + decoder->flex_state = 0; + break; + + case op_unknown15: + FT_TRACE4(( " opcode_15" )); + /* nothing to do except to pop the two arguments */ + break; default: FT_ERROR(( "t1_decoder_parse_charstrings: " @@ -1083,6 +1381,11 @@ goto Syntax_Error; } + /* XXX Operators usually clear the operand stack; */ + /* only div, callsubr, callothersubr, pop, and */ + /* return are different. */ + /* In practice it doesn't matter (?). */ + decoder->top = top; } /* general operator processing */ @@ -1143,6 +1446,10 @@ t1_builder_init( &decoder->builder, face, size, slot, hinting ); + /* decoder->buildchar and decoder->len_buildchar have to be */ + /* initialized by the caller since we cannot know the length */ + /* of the BuildCharArray */ + decoder->num_glyphs = (FT_UInt)face->num_glyphs; decoder->glyph_names = glyph_names; decoder->hint_mode = hint_mode; @@ -1151,7 +1458,7 @@ decoder->funcs = t1_decoder_funcs; - return 0; + return PSaux_Err_Ok; } diff --git a/src/libs/freetype2/pshinter/pshalgo.c b/src/libs/freetype2/pshinter/pshalgo.c index 8bf9c6a9eb..10ae7ef57c 100644 --- a/src/libs/freetype2/pshinter/pshalgo.c +++ b/src/libs/freetype2/pshinter/pshalgo.c @@ -4,7 +4,7 @@ /* */ /* PostScript hinting algorithm (body). */ /* */ -/* Copyright 2001, 2002, 2003, 2004, 2005 by */ +/* Copyright 2001, 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 */ @@ -19,6 +19,7 @@ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H #include "pshalgo.h" #include "pshnterr.h" @@ -879,6 +880,104 @@ /*************************************************************************/ /*************************************************************************/ +#if 1 + +#define psh_corner_is_flat ft_corner_is_flat +#define psh_corner_orientation ft_corner_orientation + +#else + + FT_LOCAL_DEF( FT_Int ) + psh_corner_is_flat( FT_Pos x_in, + FT_Pos y_in, + FT_Pos x_out, + FT_Pos y_out ) + { + FT_Pos ax = x_in; + FT_Pos ay = y_in; + + FT_Pos d_in, d_out, d_corner; + + + if ( ax < 0 ) + ax = -ax; + if ( ay < 0 ) + ay = -ay; + d_in = ax + ay; + + ax = x_out; + if ( ax < 0 ) + ax = -ax; + ay = y_out; + if ( ay < 0 ) + ay = -ay; + d_out = ax + ay; + + ax = x_out + x_in; + if ( ax < 0 ) + ax = -ax; + ay = y_out + y_in; + if ( ay < 0 ) + ay = -ay; + d_corner = ax + ay; + + return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); + } + + static FT_Int + psh_corner_orientation( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ) + { + FT_Int result; + + + /* deal with the trivial cases quickly */ + if ( in_y == 0 ) + { + if ( in_x >= 0 ) + result = out_y; + else + result = -out_y; + } + else if ( in_x == 0 ) + { + if ( in_y >= 0 ) + result = -out_x; + else + result = out_x; + } + else if ( out_y == 0 ) + { + if ( out_x >= 0 ) + result = in_y; + else + result = -in_y; + } + else if ( out_x == 0 ) + { + if ( out_y >= 0 ) + result = -in_x; + else + result = in_x; + } + else /* general case */ + { + long long delta = (long long)in_x * out_y - (long long)in_y * out_x; + + if ( delta == 0 ) + result = 0; + else + result = 1 - 2 * ( delta < 0 ); + } + + return result; + } + +#endif /* !1 */ + + #ifdef COMPUTE_INFLEXS /* compute all inflex points in a given glyph */ @@ -891,8 +990,8 @@ for ( n = 0; n < glyph->num_contours; n++ ) { PSH_Point first, start, end, before, after; - FT_Angle angle_in, angle_seg, angle_out; - FT_Angle diff_in, diff_out; + FT_Pos in_x, in_y, out_x, out_y; + FT_Int orient_prev, orient_cur; FT_Int finished = 0; @@ -910,9 +1009,10 @@ if ( end == first ) goto Skip; - } while ( PSH_POINT_EQUAL_ORG( end, first ) ); + in_x = end->org_u - start->org_u; + in_y = end->org_v - start->org_v; - angle_seg = PSH_POINT_ANGLE( start, end ); + } while ( in_x == 0 && in_y == 0 ); /* extend the segment start whenever possible */ before = start; @@ -925,14 +1025,18 @@ if ( before == first ) goto Skip; - } while ( PSH_POINT_EQUAL_ORG( before, start ) ); + out_x = start->org_u - before->org_u; + out_y = start->org_v - before->org_v; - angle_in = PSH_POINT_ANGLE( before, start ); + } while ( out_x == 0 && out_y == 0 ); - } while ( angle_in == angle_seg ); + orient_prev = psh_corner_orientation( in_x, in_y, out_x, out_y ); - first = start; - diff_in = FT_Angle_Diff( angle_in, angle_seg ); + } while ( orient_prev == 0 ); + + first = start; + in_x = out_x; + in_y = out_y; /* now, process all segments in the contour */ do @@ -948,19 +1052,17 @@ if ( after == first ) finished = 1; - } while ( PSH_POINT_EQUAL_ORG( end, after ) ); + out_x = after->org_u - end->org_u; + out_y = after->org_v - end->org_v; - angle_out = PSH_POINT_ANGLE( end, after ); + } while ( out_x == 0 && out_y == 0 ); - } while ( angle_out == angle_seg ); + orient_cur = psh_corner_orientation( in_x, in_y, out_x, out_y ); - diff_out = FT_Angle_Diff( angle_seg, angle_out ); + } while ( orient_cur == 0 ); - if ( ( diff_in ^ diff_out ) < 0 ) + if ( ( orient_cur ^ orient_prev ) < 0 ) { - /* diff_in and diff_out have different signs, we have */ - /* inflection points here... */ - do { psh_point_set_inflex( start ); @@ -971,10 +1073,11 @@ psh_point_set_inflex( start ); } - start = end; - end = after; - angle_seg = angle_out; - diff_in = diff_out; + start = end; + end = after; + orient_prev = orient_cur; + in_x = out_x; + in_y = out_y; } while ( !finished ); @@ -1199,28 +1302,11 @@ /* detect smooth points */ if ( point->flags & PSH_POINT_OFF ) point->flags |= PSH_POINT_SMOOTH; - else if ( point->dir_in != PSH_DIR_NONE || - point->dir_out != PSH_DIR_NONE ) + + else if ( point->dir_in == point->dir_out ) { - if ( point->dir_in == point->dir_out ) - point->flags |= PSH_POINT_SMOOTH; - } - else - { - FT_Angle angle_in, angle_out, diff; - - - angle_in = FT_Atan2( dxi, dyi ); - angle_out = FT_Atan2( dxo, dyo ); - - diff = angle_in - angle_out; - if ( diff < 0 ) - diff = -diff; - - if ( diff > FT_ANGLE_PI ) - diff = FT_ANGLE_2PI - diff; - - if ( diff < FT_ANGLE_PI / 16 ) + if ( point->dir_out != PSH_DIR_NONE || + psh_corner_is_flat( dxi, dyi, dxo, dyo ) ) point->flags |= PSH_POINT_SMOOTH; } } @@ -1382,115 +1468,147 @@ /* -major_dir. */ static void - psh_hint_table_find_strong_point( PSH_Hint_Table table, - PSH_Point point, - FT_Int threshold, - FT_Int major_dir ) + psh_hint_table_find_strong_points( PSH_Hint_Table table, + PSH_Point point, + FT_UInt count, + FT_Int threshold, + FT_Int major_dir ) { PSH_Hint* sort = table->sort; FT_UInt num_hints = table->num_hints; - FT_Int point_dir = 0; - if ( PSH_DIR_COMPARE( point->dir_in, major_dir ) ) - point_dir = point->dir_in; - - else if ( PSH_DIR_COMPARE( point->dir_out, major_dir ) ) - point_dir = point->dir_out; - - if ( point_dir ) + for ( ; count > 0; count--, point++ ) { - FT_UInt flag; + FT_Int point_dir = 0; + FT_Pos org_u = point->org_u; - for ( ; num_hints > 0; num_hints--, sort++ ) + if ( psh_point_is_strong( point ) ) + continue; + + if ( PSH_DIR_COMPARE( point->dir_in, major_dir ) ) + point_dir = point->dir_in; + + else if ( PSH_DIR_COMPARE( point->dir_out, major_dir ) ) + point_dir = point->dir_out; + + if ( point_dir ) { - PSH_Hint hint = sort[0]; - FT_Pos d; - - if ( point_dir == major_dir ) { - flag = PSH_POINT_EDGE_MIN; - d = point->org_u - hint->org_pos; + FT_UInt nn; - if ( FT_ABS( d ) < threshold ) + + for ( nn = 0; nn < num_hints; nn++ ) { - Is_Strong: - psh_point_set_strong( point ); - point->flags2 |= flag; - point->hint = hint; - break; + PSH_Hint hint = sort[nn]; + FT_Pos d = org_u - hint->org_pos; + + + if ( d < threshold && -d < threshold ) + { + psh_point_set_strong( point ); + point->flags2 |= PSH_POINT_EDGE_MIN; + point->hint = hint; + break; + } } } else if ( point_dir == -major_dir ) { - flag = PSH_POINT_EDGE_MAX; - d = point->org_u - hint->org_pos - hint->org_len; + FT_UInt nn; - if ( FT_ABS( d ) < threshold ) - goto Is_Strong; + + for ( nn = 0; nn < num_hints; nn++ ) + { + PSH_Hint hint = sort[nn]; + FT_Pos d = org_u - hint->org_pos - hint->org_len; + + + if ( d < threshold && -d < threshold ) + { + psh_point_set_strong( point ); + point->flags2 |= PSH_POINT_EDGE_MAX; + point->hint = hint; + break; + } + } } } - } #if 1 - else if ( psh_point_is_extremum( point ) ) - { - /* treat extrema as special cases for stem edge alignment */ - FT_UInt min_flag, max_flag; - - - if ( major_dir == PSH_DIR_HORIZONTAL ) + else if ( psh_point_is_extremum( point ) ) { - min_flag = PSH_POINT_POSITIVE; - max_flag = PSH_POINT_NEGATIVE; - } - else - { - min_flag = PSH_POINT_NEGATIVE; - max_flag = PSH_POINT_POSITIVE; - } + /* treat extrema as special cases for stem edge alignment */ + FT_UInt nn, min_flag, max_flag; - for ( ; num_hints > 0; num_hints--, sort++ ) - { - PSH_Hint hint = sort[0]; - FT_Pos d; - FT_Int flag; + if ( major_dir == PSH_DIR_HORIZONTAL ) + { + min_flag = PSH_POINT_POSITIVE; + max_flag = PSH_POINT_NEGATIVE; + } + else + { + min_flag = PSH_POINT_NEGATIVE; + max_flag = PSH_POINT_POSITIVE; + } if ( point->flags2 & min_flag ) { - flag = PSH_POINT_EDGE_MIN; - d = point->org_u - hint->org_pos; - - if ( FT_ABS( d ) < threshold ) + for ( nn = 0; nn < num_hints; nn++ ) { - Is_Strong2: - point->flags2 |= flag; - point->hint = hint; - psh_point_set_strong( point ); - break; + PSH_Hint hint = sort[nn]; + FT_Pos d = org_u - hint->org_pos; + + + if ( d < threshold && -d < threshold ) + { + point->flags2 |= PSH_POINT_EDGE_MIN; + point->hint = hint; + psh_point_set_strong( point ); + break; + } } } else if ( point->flags2 & max_flag ) { - flag = PSH_POINT_EDGE_MAX; - d = point->org_u - hint->org_pos - hint->org_len; + for ( nn = 0; nn < num_hints; nn++ ) + { + PSH_Hint hint = sort[nn]; + FT_Pos d = org_u - hint->org_pos - hint->org_len; - if ( FT_ABS( d ) < threshold ) - goto Is_Strong2; + + if ( d < threshold && -d < threshold ) + { + point->flags2 |= PSH_POINT_EDGE_MAX; + point->hint = hint; + psh_point_set_strong( point ); + break; + } + } } - if ( point->org_u >= hint->org_pos && - point->org_u <= hint->org_pos + hint->org_len ) + if ( point->hint == NULL ) { - point->hint = hint; + for ( nn = 0; nn < num_hints; nn++ ) + { + PSH_Hint hint = sort[nn]; + + + if ( org_u >= hint->org_pos && + org_u <= hint->org_pos + hint->org_len ) + { + point->hint = hint; + break; + } + } } } - } #endif /* 1 */ + } } @@ -1544,9 +1662,8 @@ psh_hint_table_activate_mask( table, mask ); - for ( ; count > 0; count--, point++ ) - psh_hint_table_find_strong_point( table, point, - threshold, major_dir ); + psh_hint_table_find_strong_points( table, point, count, + threshold, major_dir ); } first = next; } @@ -1560,12 +1677,9 @@ psh_hint_table_activate_mask( table, table->hint_masks->masks ); - for ( ; count > 0; count--, point++ ) - { - if ( !psh_point_is_strong( point ) ) - psh_hint_table_find_strong_point( table, point, - threshold, major_dir ); - } + + psh_hint_table_find_strong_points( table, point, count, + threshold, major_dir ); } /* now, certain points may have been attached to a hint and */ @@ -1710,6 +1824,8 @@ } +#define PSH_MAX_STRONG_INTERNAL 16 + static void psh_glyph_interpolate_normal_points( PSH_Glyph glyph, FT_Int dimension ) @@ -1718,14 +1834,64 @@ #if 1 /* first technique: a point is strong if it is a local extremum */ - PSH_Dimension dim = &glyph->globals->dimension[dimension]; - FT_Fixed scale = dim->scale_mult; + PSH_Dimension dim = &glyph->globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Memory memory = glyph->memory; - FT_UInt count = glyph->num_points; - PSH_Point point = glyph->points; + PSH_Point* strongs = NULL; + PSH_Point strongs_0[PSH_MAX_STRONG_INTERNAL]; + FT_UInt num_strongs = 0; + + PSH_Point points = glyph->points; + PSH_Point points_end = points + glyph->num_points; + PSH_Point point; - for ( ; count > 0; count--, point++ ) + /* first count the number of strong points */ + for ( point = points; point < points_end; point++ ) + { + if ( psh_point_is_strong( point ) ) + num_strongs++; + } + + if ( num_strongs == 0 ) /* nothing to do here */ + return; + + /* allocate an array to store a list of points, */ + /* stored in increasing org_u order */ + if ( num_strongs <= PSH_MAX_STRONG_INTERNAL ) + strongs = strongs_0; + else + { + FT_Error error; + + + if ( FT_NEW_ARRAY( strongs, num_strongs ) ) + return; + } + + num_strongs = 0; + for ( point = points; point < points_end; point++ ) + { + PSH_Point* insert; + + + if ( !psh_point_is_strong( point ) ) + continue; + + for ( insert = strongs + num_strongs; insert > strongs; insert-- ) + { + if ( insert[-1]->org_u <= point->org_u ) + break; + + insert[0] = insert[-1]; + } + insert[0] = point; + num_strongs++; + } + + /* now try to interpolate all normal points */ + for ( point = points; point < points_end; point++ ) { if ( psh_point_is_strong( point ) ) continue; @@ -1744,82 +1910,70 @@ point->flags &= ~PSH_POINT_SMOOTH; } - /* find best enclosing point coordinates */ + /* find best enclosing point coordinates then interpolate */ { - PSH_Point before = 0; - PSH_Point after = 0; - - FT_Pos diff_before = -32000; - FT_Pos diff_after = 32000; - FT_Pos u = point->org_u; - - FT_Int count2 = glyph->num_points; - PSH_Point cur = glyph->points; + PSH_Point before, after; + FT_UInt nn; - for ( ; count2 > 0; count2--, cur++ ) + for ( nn = 0; nn < num_strongs; nn++ ) + if ( strongs[nn]->org_u > point->org_u ) + break; + + if ( nn == 0 ) /* point before the first strong point */ { - if ( psh_point_is_strong( cur ) ) - { - FT_Pos diff = cur->org_u - u; + after = strongs[0]; - - if ( diff <= 0 ) - { - if ( diff > diff_before ) - { - diff_before = diff; - before = cur; - } - } - - else if ( diff >= 0 ) - { - if ( diff < diff_after ) - { - diff_after = diff; - after = cur; - } - } - } - } - - if ( !before ) - { - if ( !after ) - continue; - - /* we are before the first strong point coordinate; */ - /* simply translate the point */ point->cur_u = after->cur_u + - FT_MulFix( point->org_u - after->org_u, scale ); - } - else if ( !after ) - { - /* we are after the last strong point coordinate; */ - /* simply translate the point */ - point->cur_u = before->cur_u + - FT_MulFix( point->org_u - before->org_u, scale ); + FT_MulFix( point->org_u - after->org_u, + scale ); } else { - if ( diff_before == 0 ) - point->cur_u = before->cur_u; + before = strongs[nn - 1]; - else if ( diff_after == 0 ) - point->cur_u = after->cur_u; + for ( nn = num_strongs; nn > 0; nn-- ) + if ( strongs[nn - 1]->org_u < point->org_u ) + break; + + if ( nn == num_strongs ) /* point is after last strong point */ + { + before = strongs[nn - 1]; - else point->cur_u = before->cur_u + - FT_MulDiv( u - before->org_u, - after->cur_u - before->cur_u, - after->org_u - before->org_u ); - } + FT_MulFix( point->org_u - before->org_u, + scale ); + } + else + { + FT_Pos u; + + after = strongs[nn]; + + /* now interpolate point between before and after */ + u = point->org_u; + + if ( u == before->org_u ) + point->cur_u = before->cur_u; + + else if ( u == after->org_u ) + point->cur_u = after->cur_u; + + else + point->cur_u = before->cur_u + + FT_MulDiv( u - before->org_u, + after->cur_u - before->cur_u, + after->org_u - before->org_u ); + } + } psh_point_set_fitted( point ); } } + if ( strongs != strongs_0 ) + FT_FREE( strongs ); + #endif /* 1 */ } diff --git a/src/libs/freetype2/psnames/psmodule.c b/src/libs/freetype2/psnames/psmodule.c index 631eafd0ec..1a7a251dbc 100644 --- a/src/libs/freetype2/psnames/psmodule.c +++ b/src/libs/freetype2/psnames/psmodule.c @@ -182,11 +182,12 @@ /* Build a table that maps Unicode values to glyph indices. */ static FT_Error - ps_unicodes_init( FT_Memory memory, - PS_Unicodes table, - FT_UInt num_glyphs, - PS_Glyph_NameFunc get_glyph_name, - FT_Pointer glyph_data ) + ps_unicodes_init( FT_Memory memory, + PS_Unicodes table, + FT_UInt num_glyphs, + PS_GetGlyphNameFunc get_glyph_name, + PS_FreeGlyphNameFunc free_glyph_name, + FT_Pointer glyph_data ) { FT_Error error; @@ -220,6 +221,9 @@ map->glyph_index = n; map++; } + + if ( free_glyph_name ) + free_glyph_name( glyph_data, gname ); } } diff --git a/src/libs/freetype2/raster/ftraster.c b/src/libs/freetype2/raster/ftraster.c index cb9f946e56..63d6bb77d8 100644 --- a/src/libs/freetype2/raster/ftraster.c +++ b/src/libs/freetype2/raster/ftraster.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2005 by */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -378,19 +378,19 @@ #else /* FT_STATIC_RASTER */ -#define RAS_ARGS TRaster_Instance* raster, -#define RAS_ARG TRaster_Instance* raster +#define RAS_ARGS PWorker worker, +#define RAS_ARG PWorker worker -#define RAS_VARS raster, -#define RAS_VAR raster +#define RAS_VARS worker, +#define RAS_VAR worker -#define FT_UNUSED_RASTER FT_UNUSED( raster ) +#define FT_UNUSED_RASTER FT_UNUSED( worker ) #endif /* FT_STATIC_RASTER */ - typedef struct TRaster_Instance_ TRaster_Instance; + typedef struct TWorker_ TWorker, *PWorker; /* prototypes used for sweep function dispatch */ @@ -422,7 +422,7 @@ /* at the top. Thus, their offset can be coded with less */ /* opcodes, and it results in a smaller executable. */ - struct TRaster_Instance_ + struct TWorker_ { Int precision_bits; /* precision related variables */ Int precision; @@ -498,15 +498,9 @@ TBand band_stack[16]; /* band stack used for sub-banding */ Int band_top; /* band stack top */ - Int count_table[256]; /* Look-up table used to quickly count */ - /* set bits in a gray 2x2 cell */ - - void* memory; - #ifdef FT_RASTER_OPTION_ANTI_ALIASING - Byte grays[5]; /* Palette of gray levels used for */ - /* render. */ + Byte* grays; Byte gray_lines[RASTER_GRAY_LINES]; /* Intermediate table used to render the */ @@ -523,30 +517,53 @@ #endif /* FT_RASTER_ANTI_ALIASING */ -#if 0 - PByte flags; /* current flags table */ - PUShort outs; /* current outlines table */ - FT_Vector* coords; - - UShort nPoints; /* number of points in current glyph */ - Short nContours; /* number of contours in current glyph */ -#endif - }; + typedef struct TRaster_ + { + char* buffer; + long buffer_size; + void* memory; + PWorker worker; + Byte grays[5]; + Short gray_width; + + } TRaster, *PRaster; + #ifdef FT_STATIC_RASTER - static TRaster_Instance cur_ras; + static TWorker cur_ras; #define ras cur_ras #else -#define ras (*raster) +#define ras (*worker) #endif /* FT_STATIC_RASTER */ +static const char count_table[256] = +{ + 0 , 1 , 1 , 2 , 1 , 2 , 2 , 3 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4, + 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, + 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, + 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, + 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, + 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, + 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, + 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, + 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, + 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, + 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, + 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, + 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, + 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, + 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 }; + + + /*************************************************************************/ /*************************************************************************/ /** **/ @@ -2494,7 +2511,7 @@ { Int c1, c2; PByte pix, bit, bit2; - Int* count = ras.count_table; + char* count = (char*)count_table; Byte* grays; @@ -3153,32 +3170,19 @@ static void - ft_black_init( TRaster_Instance* raster ) + ft_black_init( PRaster raster ) { - FT_UInt n; - FT_ULong c; - - - /* setup count table */ - for ( n = 0; n < 256; n++ ) - { - c = ( n & 0x55 ) + ( ( n & 0xAA ) >> 1 ); - - c = ( ( c << 6 ) & 0x3000 ) | - ( ( c << 4 ) & 0x0300 ) | - ( ( c << 2 ) & 0x0030 ) | - (c & 0x0003 ); - - ras.count_table[n] = (UInt)c; - } + FT_UNUSED( raster ); #ifdef FT_RASTER_OPTION_ANTI_ALIASING + FT_UInt n; + /* set default 5-levels gray palette */ for ( n = 0; n < 5; n++ ) raster->grays[n] = n * 255 / 4; - ras.gray_width = RASTER_GRAY_LINES / 2; + raster->gray_width = RASTER_GRAY_LINES / 2; #endif } @@ -3195,7 +3199,7 @@ ft_black_new( void* memory, FT_Raster *araster ) { - static TRaster_Instance the_raster; + static TRaster the_raster; *araster = (FT_Raster)&the_raster; @@ -3218,11 +3222,11 @@ static int - ft_black_new( FT_Memory memory, - TRaster_Instance** araster ) + ft_black_new( FT_Memory memory, + PRaster *araster ) { - FT_Error error; - TRaster_Instance* raster; + FT_Error error; + PRaster raster; *araster = 0; @@ -3239,7 +3243,7 @@ static void - ft_black_done( TRaster_Instance* raster ) + ft_black_done( PRaster raster ) { FT_Memory memory = (FT_Memory)raster->memory; FT_FREE( raster ); @@ -3250,21 +3254,34 @@ static void - ft_black_reset( TRaster_Instance* raster, - char* pool_base, - long pool_size ) + ft_black_reset( PRaster raster, + char* pool_base, + long pool_size ) { - if ( (&ras) && pool_base && pool_size >= 4096 ) + if ( raster ) { - /* save the pool */ - ras.buff = (PLong)pool_base; - ras.sizeBuff = ras.buff + pool_size / sizeof ( Long ); + if ( pool_base && pool_size >= (long)sizeof(TWorker) + 2048 ) + { + PWorker worker = (PWorker)pool_base; + + + raster->buffer = pool_base + ( (sizeof ( *worker ) + 7 ) & ~7 ); + raster->buffer_size = ( ( pool_base + pool_size ) - + (char*)raster->buffer ) / sizeof ( Long ); + raster->worker = worker; + } + else + { + raster->buffer = NULL; + raster->buffer_size = 0; + raster->worker = NULL; + } } } static void - ft_black_set_mode( TRaster_Instance* raster, + ft_black_set_mode( PRaster raster, unsigned long mode, const char* palette ) { @@ -3273,11 +3290,11 @@ if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) ) { /* set 5-levels gray palette */ - ras.grays[0] = palette[0]; - ras.grays[1] = palette[1]; - ras.grays[2] = palette[2]; - ras.grays[3] = palette[3]; - ras.grays[4] = palette[4]; + raster->grays[0] = palette[0]; + raster->grays[1] = palette[1]; + raster->grays[2] = palette[2]; + raster->grays[3] = palette[3]; + raster->grays[4] = palette[4]; } #else @@ -3291,14 +3308,15 @@ static int - ft_black_render( TRaster_Instance* raster, + ft_black_render( PRaster raster, const FT_Raster_Params* params ) { const FT_Outline* outline = (const FT_Outline*)params->source; const FT_Bitmap* target_map = params->target; + PWorker worker; - if ( !(&ras) || !ras.buff || !ras.sizeBuff ) + if ( !raster || !raster->buffer || !raster->buffer_size ) return Raster_Err_Not_Ini; /* return immediately if the outline is empty */ @@ -3311,6 +3329,8 @@ if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 ) return Raster_Err_Invalid; + worker = raster->worker; + /* this version of the raster does not support direct rendering, sorry */ if ( params->flags & FT_RASTER_FLAG_DIRECT ) return Raster_Err_Unsupported; @@ -3321,6 +3341,14 @@ ras.outline = *outline; ras.target = *target_map; + worker->buff = (PLong) raster->buffer; + worker->sizeBuff = worker->buff + + raster->buffer_size / sizeof ( Long ); +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + worker->grays = raster->grays; + worker->gray_width = raster->gray_width; +#endif + return ( ( params->flags & FT_RASTER_FLAG_AA ) ? Render_Gray_Glyph( RAS_VAR ) : Render_Glyph( RAS_VAR ) ); diff --git a/src/libs/freetype2/sfnt/rules.mk b/src/libs/freetype2/sfnt/rules.mk index c65f8abdd3..ff7840e7fe 100644 --- a/src/libs/freetype2/sfnt/rules.mk +++ b/src/libs/freetype2/sfnt/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006 by +# Copyright 1996-2000, 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, modified, diff --git a/src/libs/freetype2/sfnt/sfdriver.c b/src/libs/freetype2/sfnt/sfdriver.c index 9f4bbcf4b3..870932749b 100644 --- a/src/libs/freetype2/sfnt/sfdriver.c +++ b/src/libs/freetype2/sfnt/sfdriver.c @@ -412,9 +412,9 @@ { FT_UNUSED( face ); FT_UNUSED( stream ); - + return FT_Err_Unimplemented_Feature; - } + } FT_CALLBACK_DEF( void ) @@ -449,8 +449,8 @@ *astrike_index = 0x7FFFFFFFUL; - return tt_face_set_sbit_strike( face, &req, astrike_index ); - } + return tt_face_set_sbit_strike( face, &req, astrike_index ); + } FT_CALLBACK_DEF( FT_Error ) @@ -459,15 +459,15 @@ { FT_UNUSED( face ); FT_UNUSED( stream ); - + /* - * This function was originally implemented to load the sbit table. + * This function was originally implemented to load the sbit table. * However, it has been replaced by `tt_face_load_eblc', and this stub * is only there for some rogue clients which would want to call it * directly (which doesn't make much sense). */ return FT_Err_Unimplemented_Feature; - } + } FT_CALLBACK_DEF( void ) @@ -476,8 +476,8 @@ /* nothing to do in this stub */ FT_UNUSED( face ); } - - + + FT_CALLBACK_DEF( FT_Error ) tt_face_load_charmap_stub( TT_Face face, void* cmap, @@ -486,9 +486,9 @@ FT_UNUSED( face ); FT_UNUSED( cmap ); FT_UNUSED( input ); - + return FT_Err_Unimplemented_Feature; - } + } FT_CALLBACK_DEF( FT_Error ) @@ -497,10 +497,10 @@ { FT_UNUSED( face ); FT_UNUSED( cmap ); - + return 0; - } - + } + #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ @@ -600,7 +600,7 @@ 0, 0, 0, -#endif +#endif tt_face_get_metrics }; diff --git a/src/libs/freetype2/sfnt/sfobjs.c b/src/libs/freetype2/sfnt/sfobjs.c index 869269cdd1..ce19f7294f 100644 --- a/src/libs/freetype2/sfnt/sfobjs.c +++ b/src/libs/freetype2/sfnt/sfobjs.c @@ -4,7 +4,7 @@ /* */ /* SFNT object management (base). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -75,37 +75,6 @@ } - /* convert a UCS-4 name entry to ASCII */ - static FT_String* - tt_name_entry_ascii_from_ucs4( TT_NameEntry entry, - FT_Memory memory ) - { - FT_String* string; - FT_UInt len, code, n; - FT_Byte* read = (FT_Byte*)entry->string; - FT_Error error; - - - len = (FT_UInt)entry->stringLength / 4; - - if ( FT_NEW_ARRAY( string, len + 1 ) ) - return NULL; - - for ( n = 0; n < len; n++ ) - { - code = (FT_UInt)FT_NEXT_ULONG( read ); - if ( code < 32 || code > 127 ) - code = '?'; - - string[n] = (char)code; - } - - string[len] = 0; - - return string; - } - - /* convert an Apple Roman or symbol name entry to ASCII */ static FT_String* tt_name_entry_ascii_from_other( TT_NameEntry entry, @@ -165,9 +134,11 @@ FT_String* result = NULL; FT_UShort n; TT_NameEntryRec* rec; - FT_Int found_apple = -1; - FT_Int found_win = -1; - FT_Int found_unicode = -1; + FT_Int found_apple = -1; + FT_Int found_apple_roman = -1; + FT_Int found_apple_english = -1; + FT_Int found_win = -1; + FT_Int found_unicode = -1; FT_Bool is_english = 0; @@ -200,9 +171,14 @@ break; case TT_PLATFORM_MACINTOSH: + /* This is a bit special because some fonts will use either */ + /* an English language id, or a Roman encoding id, to indicate */ + /* the English version of its font name. */ + /* */ if ( rec->languageID == TT_MAC_LANGID_ENGLISH ) - found_apple = n; - + found_apple_english = n; + else if ( rec->encodingID == TT_MAC_ID_ROMAN ) + found_apple_roman = n; break; case TT_PLATFORM_MICROSOFT: @@ -232,6 +208,10 @@ } } + found_apple = found_apple_roman; + if ( found_apple_english >= 0 ) + found_apple = found_apple_english; + /* some fonts contain invalid Unicode or Macintosh formatted entries; */ /* we will thus favor names encoded in Windows formats if available */ /* (provided it is an English name) */ @@ -242,13 +222,19 @@ rec = face->name_table.names + found_win; switch ( rec->encodingID ) { + /* all Unicode strings are encoded using UTF-16BE */ case TT_MS_ID_UNICODE_CS: case TT_MS_ID_SYMBOL_CS: convert = tt_name_entry_ascii_from_utf16; break; case TT_MS_ID_UCS_4: - convert = tt_name_entry_ascii_from_ucs4; + /* Apparently, if this value is found in a name table entry, it is */ + /* documented as `full Unicode repertoire'. Experience with the */ + /* MsGothic font shipped with Windows Vista shows that this really */ + /* means UTF-16 encoded names (UCS-4 values are only used within */ + /* charmaps). */ + convert = tt_name_entry_ascii_from_utf16; break; default: @@ -915,7 +901,7 @@ FT_UInt i, count; -#if defined FT_OPTIMIZE_MEMORY && !defined FT_CONFIG_OPTION_OLD_INTERNALS +#if !defined FT_CONFIG_OPTION_OLD_INTERNALS count = face->sbit_num_strikes; #else count = (FT_UInt)face->num_sbit_strikes; @@ -1022,7 +1008,7 @@ } /* freeing the horizontal metrics */ -#if defined FT_OPTIMIZE_MEMORY && !defined FT_CONFIG_OPTION_OLD_INTERNALS +#if !defined FT_CONFIG_OPTION_OLD_INTERNALS { FT_Stream stream = FT_FACE_STREAM( face ); diff --git a/src/libs/freetype2/sfnt/ttcmap.c b/src/libs/freetype2/sfnt/ttcmap.c index 3a43aedc21..475fcf68e3 100644 --- a/src/libs/freetype2/sfnt/ttcmap.c +++ b/src/libs/freetype2/sfnt/ttcmap.c @@ -4,7 +4,7 @@ /* */ /* TrueType 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, */ @@ -708,7 +708,7 @@ tt_cmap4_next( TT_CMap4 cmap ) { FT_UInt charcode; - + if ( cmap->cur_charcode >= 0xFFFFUL ) goto Fail; @@ -862,18 +862,19 @@ FT_UInt start, end, offset, n; FT_UInt last_start = 0, last_end = 0; FT_Int delta; + FT_Byte* p_start = starts; + FT_Byte* p_end = ends; + FT_Byte* p_delta = deltas; + FT_Byte* p_offset = offsets; for ( n = 0; n < num_segs; n++ ) { - p = starts + n * 2; - start = TT_PEEK_USHORT( p ); - p = ends + n * 2; - end = TT_PEEK_USHORT( p ); - p = deltas + n * 2; - delta = TT_PEEK_SHORT( p ); - p = offsets + n * 2; - offset = TT_PEEK_USHORT( p ); + p = p_offset; + start = TT_NEXT_USHORT( p_start ); + end = TT_NEXT_USHORT( p_end ); + delta = TT_NEXT_SHORT( p_delta ); + offset = TT_NEXT_USHORT( p_offset ); if ( start > end ) FT_INVALID_DATA; @@ -983,7 +984,7 @@ for ( ; charcode <= 0xFFFFU; charcode++ ) { FT_Byte* q; - + p = cmap->data + 14; /* ends table */ q = cmap->data + 16 + num_segs2; /* starts table */ @@ -1039,7 +1040,7 @@ FT_UInt charcode = *pcharcode; FT_UInt gindex = 0; FT_Byte* p; - + p = cmap->data + 6; num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); @@ -1094,14 +1095,19 @@ /* search in segments before the current segment */ for ( i = max ; i > 0; i-- ) { - FT_UInt prev_end; + FT_UInt prev_end; + FT_Byte* old_p; - p = cmap->data + 14 + ( i - 1 ) * 2; + old_p = p; + p = cmap->data + 14 + ( i - 1 ) * 2; prev_end = TT_PEEK_USHORT( p ); if ( charcode > prev_end ) + { + p = old_p; break; + } end = prev_end; p += 2 + num_segs2; @@ -2273,7 +2279,7 @@ if ( offset && offset <= face->cmap_size - 2 ) { - FT_Byte* cmap = table + offset; + FT_Byte* volatile cmap = table + offset; volatile FT_UInt format = TT_PEEK_USHORT( cmap ); const TT_CMap_Class* volatile pclazz = tt_cmap_classes; TT_CMap_Class volatile clazz; diff --git a/src/libs/freetype2/sfnt/ttkern.c b/src/libs/freetype2/sfnt/ttkern.c index 30f6cdbf12..8eb2ff4876 100644 --- a/src/libs/freetype2/sfnt/ttkern.c +++ b/src/libs/freetype2/sfnt/ttkern.c @@ -5,7 +5,7 @@ /* Load the basic TrueType kerning table. This doesn't handle */ /* kerning data within the GPOS table at the moment. */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -41,8 +41,6 @@ #define TT_KERN_INDEX( g1, g2 ) ( ( (FT_ULong)(g1) << 16 ) | (g2) ) -#ifdef FT_OPTIMIZE_MEMORY - FT_LOCAL_DEF( FT_Error ) tt_face_load_kern( TT_Face face, FT_Stream stream ) @@ -289,206 +287,6 @@ return result; } -#else /* !OPTIMIZE_MEMORY */ - - FT_CALLBACK_DEF( int ) - tt_kern_pair_compare( const void* a, - const void* b ); - - - FT_LOCAL_DEF( FT_Error ) - tt_face_load_kern( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - FT_UInt n, num_tables; - - - /* the kern table is optional; exit silently if it is missing */ - error = face->goto_table( face, TTAG_kern, stream, 0 ); - if ( error ) - return SFNT_Err_Ok; - - if ( FT_FRAME_ENTER( 4L ) ) - goto Exit; - - (void)FT_GET_USHORT(); /* version */ - num_tables = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - - for ( n = 0; n < num_tables; n++ ) - { - FT_UInt coverage; - FT_UInt length; - - - if ( FT_FRAME_ENTER( 6L ) ) - goto Exit; - - (void)FT_GET_USHORT(); /* version */ - length = FT_GET_USHORT() - 6; /* substract header length */ - coverage = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - - if ( coverage == 0x0001 ) - { - FT_UInt num_pairs; - TT_Kern0_Pair pair; - TT_Kern0_Pair limit; - - - /* found a horizontal format 0 kerning table! */ - if ( FT_FRAME_ENTER( 8L ) ) - goto Exit; - - num_pairs = FT_GET_USHORT(); - - /* skip the rest */ - - FT_FRAME_EXIT(); - - /* allocate array of kerning pairs */ - if ( FT_QNEW_ARRAY( face->kern_pairs, num_pairs ) || - FT_FRAME_ENTER( 6L * num_pairs ) ) - goto Exit; - - pair = face->kern_pairs; - limit = pair + num_pairs; - for ( ; pair < limit; pair++ ) - { - pair->left = FT_GET_USHORT(); - pair->right = FT_GET_USHORT(); - pair->value = FT_GET_USHORT(); - } - - FT_FRAME_EXIT(); - - face->num_kern_pairs = num_pairs; - face->kern_table_index = n; - - /* ensure that the kerning pair table is sorted (yes, some */ - /* fonts have unsorted tables!) */ - - if ( num_pairs > 0 ) - { - TT_Kern0_Pair pair0 = face->kern_pairs; - FT_ULong prev = TT_KERN_INDEX( pair0->left, pair0->right ); - - - for ( pair0++; pair0 < limit; pair0++ ) - { - FT_ULong next = TT_KERN_INDEX( pair0->left, pair0->right ); - - - if ( next < prev ) - goto SortIt; - - prev = next; - } - goto Exit; - - SortIt: - ft_qsort( (void*)face->kern_pairs, (int)num_pairs, - sizeof ( TT_Kern0_PairRec ), tt_kern_pair_compare ); - } - - goto Exit; - } - - if ( FT_STREAM_SKIP( length ) ) - goto Exit; - } - - /* no kern table found -- doesn't matter */ - face->kern_table_index = -1; - face->num_kern_pairs = 0; - face->kern_pairs = NULL; - - Exit: - return error; - } - - - FT_CALLBACK_DEF( int ) - tt_kern_pair_compare( const void* a, - const void* b ) - { - TT_Kern0_Pair pair1 = (TT_Kern0_Pair)a; - TT_Kern0_Pair pair2 = (TT_Kern0_Pair)b; - - FT_ULong index1 = TT_KERN_INDEX( pair1->left, pair1->right ); - FT_ULong index2 = TT_KERN_INDEX( pair2->left, pair2->right ); - - return index1 < index2 ? -1 - : ( index1 > index2 ? 1 - : 0 ); - } - - - FT_LOCAL_DEF( void ) - tt_face_done_kern( TT_Face face ) - { - FT_Memory memory = face->root.stream->memory; - - - FT_FREE( face->kern_pairs ); - face->num_kern_pairs = 0; - } - - - FT_LOCAL_DEF( FT_Int ) - tt_face_get_kerning( TT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph ) - { - FT_Int result = 0; - TT_Kern0_Pair pair; - - - if ( face && face->kern_pairs ) - { - /* there are some kerning pairs in this font file! */ - FT_ULong search_tag = TT_KERN_INDEX( left_glyph, right_glyph ); - FT_Long left, right; - - - left = 0; - right = face->num_kern_pairs - 1; - - while ( left <= right ) - { - FT_Long middle = left + ( ( right - left ) >> 1 ); - FT_ULong cur_pair; - - - pair = face->kern_pairs + middle; - cur_pair = TT_KERN_INDEX( pair->left, pair->right ); - - if ( cur_pair == search_tag ) - goto Found; - - if ( cur_pair < search_tag ) - left = middle + 1; - else - right = middle - 1; - } - } - - Exit: - return result; - - Found: - result = pair->value; - goto Exit; - } - -#endif /* !OPTIMIZE_MEMORY */ - - #undef TT_KERN_INDEX /* END */ diff --git a/src/libs/freetype2/sfnt/ttkern.h b/src/libs/freetype2/sfnt/ttkern.h index 18b1381b4e..df1da9b273 100644 --- a/src/libs/freetype2/sfnt/ttkern.h +++ b/src/libs/freetype2/sfnt/ttkern.h @@ -5,7 +5,7 @@ /* Load the basic TrueType kerning table. This doesn't handle */ /* kerning data within the GPOS table at the moment. */ /* */ -/* Copyright 1996-2001, 2002, 2005 by */ +/* Copyright 1996-2001, 2002, 2005, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,11 +41,7 @@ FT_BEGIN_HEADER FT_UInt left_glyph, FT_UInt right_glyph ); -#ifdef FT_OPTIMIZE_MEMORY -# define TT_FACE_HAS_KERNING( face ) ( (face)->kern_avail_bits != 0 ) -#else -# define TT_FACE_HAS_KERNING( face ) ( (face)->kern_pairs != NULL ) -#endif +#define TT_FACE_HAS_KERNING( face ) ( (face)->kern_avail_bits != 0 ) FT_END_HEADER diff --git a/src/libs/freetype2/sfnt/ttload.c b/src/libs/freetype2/sfnt/ttload.c index c81f80d5e1..4d2604a10a 100644 --- a/src/libs/freetype2/sfnt/ttload.c +++ b/src/libs/freetype2/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 by */ +/* Copyright 1996-2001, 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, */ @@ -1138,6 +1138,14 @@ FT_FRAME_EXIT(); + /* only support versions 0 and 1 of the table */ + if ( face->gasp.version >= 2 ) + { + face->gasp.numRanges = 0; + error = SFNT_Err_Invalid_Table; + goto Exit; + } + num_ranges = face->gasp.numRanges; FT_TRACE3(( "numRanges: %u\n", num_ranges )); diff --git a/src/libs/freetype2/sfnt/ttmtx.c b/src/libs/freetype2/sfnt/ttmtx.c index d0140b3a18..46e93329ac 100644 --- a/src/libs/freetype2/sfnt/ttmtx.c +++ b/src/libs/freetype2/sfnt/ttmtx.c @@ -4,7 +4,7 @@ /* */ /* Load the metrics tables common to TTF and OTF fonts (body). */ /* */ -/* 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, */ @@ -60,7 +60,7 @@ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ -#if defined FT_OPTIMIZE_MEMORY && !defined FT_CONFIG_OPTION_OLD_INTERNALS +#if !defined FT_CONFIG_OPTION_OLD_INTERNALS FT_LOCAL_DEF( FT_Error ) tt_face_load_hmtx( TT_Face face, @@ -68,34 +68,30 @@ FT_Bool vertical ) { FT_Error error; - FT_ULong table_size; - FT_Byte** ptable; + FT_ULong tag, table_size; + FT_ULong* ptable_offset; FT_ULong* ptable_size; - - + + if ( vertical ) { - error = face->goto_table( face, TTAG_vmtx, stream, &table_size ); - if ( error ) - goto Fail; - - ptable = &face->vert_metrics; - ptable_size = &face->vert_metrics_size; + tag = TTAG_vmtx; + ptable_offset = &face->vert_metrics_offset; + ptable_size = &face->vert_metrics_size; } else { - error = face->goto_table( face, TTAG_hmtx, stream, &table_size ); - if ( error ) - goto Fail; - - ptable = &face->horz_metrics; - ptable_size = &face->horz_metrics_size; + tag = TTAG_hmtx; + ptable_offset = &face->horz_metrics_offset; + ptable_size = &face->horz_metrics_size; } - - if ( FT_FRAME_EXTRACT( table_size, *ptable ) ) + + error = face->goto_table( face, tag, stream, &table_size ); + if ( error ) goto Fail; - - *ptable_size = table_size; + + *ptable_size = table_size; + *ptable_offset = FT_STREAM_POS(); Fail: return error; @@ -116,6 +112,7 @@ TT_LongMetrics * longs; TT_ShortMetrics** shorts; + FT_Byte* p; if ( vertical ) @@ -175,6 +172,8 @@ if ( FT_FRAME_ENTER( table_len ) ) goto Fail; + p = stream->cursor; + { TT_LongMetrics cur = *longs; TT_LongMetrics limit = cur + num_longs; @@ -182,8 +181,8 @@ for ( ; cur < limit; cur++ ) { - cur->advance = FT_GET_USHORT(); - cur->bearing = FT_GET_SHORT(); + cur->advance = FT_NEXT_USHORT( p ); + cur->bearing = FT_NEXT_SHORT( p ); } } @@ -195,7 +194,7 @@ for ( ; cur < limit; cur++ ) - *cur = FT_GET_SHORT(); + *cur = FT_NEXT_SHORT( p ); /* We fill up the missing left side bearings with the */ /* last valid value. Since this will occur for buggy CJK */ @@ -313,7 +312,7 @@ /*************************************************************************/ /* */ /* <Function> */ - /* tt_face_get_metrics */ + /* tt_face_get_metrics */ /* */ /* <Description> */ /* Returns the horizontal or vertical metrics in font units for a */ @@ -331,7 +330,7 @@ /* */ /* advance :: The advance width resp. advance height. */ /* */ -#if defined FT_OPTIMIZE_MEMORY && !defined FT_CONFIG_OPTION_OLD_INTERNALS +#if !defined FT_CONFIG_OPTION_OLD_INTERNALS FT_LOCAL_DEF( FT_Error ) tt_face_get_metrics( TT_Face face, @@ -340,50 +339,61 @@ FT_Short *abearing, FT_UShort *aadvance ) { + FT_Error error; + FT_Stream stream = face->root.stream; TT_HoriHeader* header; - FT_Byte* p; - FT_Byte* limit; + FT_ULong table_pos, table_size, table_end; FT_UShort k; if ( vertical ) { - header = (TT_HoriHeader*)&face->vertical; - p = face->vert_metrics; - limit = p + face->vert_metrics_size; + header = (TT_HoriHeader*)&face->vertical; + table_pos = face->vert_metrics_offset; + table_size = face->vert_metrics_size; } else { - header = &face->horizontal; - p = face->horz_metrics; - limit = p + face->horz_metrics_size; + header = &face->horizontal; + table_pos = face->horz_metrics_offset; + table_size = face->horz_metrics_size; } + table_end = table_pos + table_size; + k = header->number_Of_HMetrics; if ( k > 0 ) { if ( gindex < (FT_UInt)k ) { - p += 4 * gindex; - if ( p + 4 > limit ) + table_pos += 4 * gindex; + if ( table_pos + 6 > table_end ) goto NoData; - *aadvance = FT_NEXT_USHORT( p ); - *abearing = FT_NEXT_SHORT( p ); + if ( FT_STREAM_SEEK( table_pos ) || + FT_READ_USHORT( *aadvance) || + FT_READ_SHORT( *abearing ) ) + goto NoData; } else { - p += 4 * ( k - 1 ); - if ( p + 4 > limit ) + table_pos += 4 * ( k - 1 ); + if ( table_pos + 4 > table_end ) goto NoData; - *aadvance = FT_NEXT_USHORT( p ); - p += 2 + 2 * ( gindex - k ); - if ( p + 2 > limit ) + if ( FT_STREAM_SEEK( table_pos ) || + FT_READ_USHORT( *aadvance ) ) + goto NoData; + + table_pos += 4 + 2 * ( gindex - k ); + if ( table_pos + 2 > table_end ) *abearing = 0; else - *abearing = FT_PEEK_SHORT( p ); + { + if ( !FT_STREAM_SEEK( table_pos ) ) + (void)FT_READ_SHORT( *abearing ); + } } } else @@ -396,7 +406,7 @@ return SFNT_Err_Ok; } -#else /* !OPTIMIZE_MEMORY || OLD_INTERNALS */ +#else /* OLD_INTERNALS */ FT_LOCAL_DEF( FT_Error ) tt_face_get_metrics( TT_Face face, diff --git a/src/libs/freetype2/sfnt/ttsbit.c b/src/libs/freetype2/sfnt/ttsbit.c index 21f30efdd4..eff49dadd9 100644 --- a/src/libs/freetype2/sfnt/ttsbit.c +++ b/src/libs/freetype2/sfnt/ttsbit.c @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -24,11 +24,11 @@ * Alas, the memory-optimized sbit loader can't be used when implementing * the `old internals' hack */ -#if defined FT_OPTIMIZE_MEMORY && !defined FT_CONFIG_OPTION_OLD_INTERNALS +#if !defined FT_CONFIG_OPTION_OLD_INTERNALS #include "ttsbit0.c" -#else /* !OPTIMIZE_MEMORY || OLD_INTERNALS */ +#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H @@ -222,7 +222,7 @@ /*************************************************************************/ /* */ /* <Function> */ - /* TT_Load_SBit_Const_Metrics */ + /* Load_SBit_Const_Metrics */ /* */ /* <Description> */ /* Loads the metrics for `EBLC' index tables format 2 and 5. */ @@ -252,7 +252,7 @@ /*************************************************************************/ /* */ /* <Function> */ - /* TT_Load_SBit_Range_Codes */ + /* Load_SBit_Range_Codes */ /* */ /* <Description> */ /* Loads the range codes for `EBLC' index tables format 4 and 5. */ @@ -317,7 +317,7 @@ /*************************************************************************/ /* */ /* <Function> */ - /* TT_Load_SBit_Range */ + /* Load_SBit_Range */ /* */ /* <Description> */ /* Loads a given `EBLC' index/range table. */ @@ -398,7 +398,7 @@ /*************************************************************************/ /* */ /* <Function> */ - /* tt_face_load_sbit_strikes */ + /* tt_face_load_eblc */ /* */ /* <Description> */ /* Loads the table of embedded bitmap sizes for this face. */ @@ -598,7 +598,7 @@ /*************************************************************************/ /* */ /* <Function> */ - /* tt_face_free_sbit_strikes */ + /* tt_face_free_eblc */ /* */ /* <Description> */ /* Releases the embedded bitmap tables. */ @@ -1495,7 +1495,7 @@ return error; } -#endif /* !OPTIMIZE_MEMORY || OLD_INTERNALS */ +#endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */ /* END */ diff --git a/src/libs/freetype2/sfnt/ttsbit.h b/src/libs/freetype2/sfnt/ttsbit.h index af52742de4..c6067c0e3e 100644 --- a/src/libs/freetype2/sfnt/ttsbit.h +++ b/src/libs/freetype2/sfnt/ttsbit.h @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -45,7 +45,7 @@ FT_BEGIN_HEADER FT_ULong strike_index, FT_Size_Metrics* metrics ); -#if !defined FT_OPTIMIZE_MEMORY || defined FT_CONFIG_OPTION_OLD_INTERNALS +#if defined FT_CONFIG_OPTION_OLD_INTERNALS FT_LOCAL( FT_Error ) tt_find_sbit_image( TT_Face face, FT_UInt glyph_index, @@ -59,7 +59,7 @@ FT_BEGIN_HEADER TT_SBit_Range range, TT_SBit_Metrics metrics ); -#endif /* !FT_OPTIMIZE_MEMORY || FT_CONFIG_OPTION_OLD_INTERNALS */ +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ FT_LOCAL( FT_Error ) tt_face_load_sbit_image( TT_Face face, diff --git a/src/libs/freetype2/sfnt/ttsbit0.c b/src/libs/freetype2/sfnt/ttsbit0.c index 56ab236c0b..edbfa103d3 100644 --- a/src/libs/freetype2/sfnt/ttsbit0.c +++ b/src/libs/freetype2/sfnt/ttsbit0.c @@ -5,7 +5,7 @@ /* TrueType and OpenType embedded bitmap support (body). */ /* This is a heap-optimized version. */ /* */ -/* Copyright 2005, 2006 by */ +/* Copyright 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,6 +17,9 @@ /***************************************************************************/ +/* This file is included by ttsbit.c */ + + #include <ft2build.h> #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H @@ -137,7 +140,7 @@ * paranoid there and don't trust the data. */ count = (FT_UInt)num_strikes; - if ( 8 +48UL * count > table_size ) + if ( 8 + 48UL * count > table_size ) count = (FT_UInt)( ( p_limit - p ) / 48 ); face->sbit_num_strikes = count; @@ -180,7 +183,7 @@ FT_Size_Metrics* metrics ) { FT_Byte* strike; - + if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) return SFNT_Err_Invalid_Argument; diff --git a/src/libs/freetype2/sfnt/ttsbit0.h b/src/libs/freetype2/sfnt/ttsbit0.h deleted file mode 100644 index 396ddc555e..0000000000 --- a/src/libs/freetype2/sfnt/ttsbit0.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * ttsbit0.h - * - * This is a dummy file, used to please the build system. It is never - * included by the sfnt sources. - * - */ diff --git a/src/libs/freetype2/smooth/ftgrays.c b/src/libs/freetype2/smooth/ftgrays.c index 3d61d79360..da722cc410 100644 --- a/src/libs/freetype2/smooth/ftgrays.c +++ b/src/libs/freetype2/smooth/ftgrays.c @@ -4,7 +4,7 @@ /* */ /* A new `perfect' anti-aliasing renderer (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2005, 2006 by */ +/* Copyright 2000-2001, 2002, 2003, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -81,11 +81,6 @@ /*************************************************************************/ - -/* experimental support for gamma correction within the rasterizer */ -#define xxxGRAYS_USE_GAMMA - - /*************************************************************************/ /* */ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ @@ -96,7 +91,6 @@ #define FT_COMPONENT trace_smooth -#define ErrRaster_MemoryOverflow -4 #ifdef _STANDALONE_ @@ -113,8 +107,10 @@ #define ft_jmp_buf jmp_buf -#define ErrRaster_Invalid_Mode -2 -#define ErrRaster_Invalid_Outline -1 +#define ErrRaster_Invalid_Mode -2 +#define ErrRaster_Invalid_Outline -1 +#define ErrRaster_Invalid_Argument -3 +#define ErrRaster_Memory_Overflow -4 #define FT_BEGIN_HEADER #define FT_END_HEADER @@ -138,9 +134,7 @@ #define FT_TRACE( x ) do ; while ( 0 ) /* nothing */ #endif - -#else /* _STANDALONE_ */ - +#else /* !_STANDALONE_ */ #include <ft2build.h> #include "ftgrays.h" @@ -152,9 +146,10 @@ #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_ */ +#endif /* !_STANDALONE_ */ #ifndef FT_MEM_SET @@ -168,18 +163,19 @@ /* define this to dump debugging information */ #define xxxDEBUG_GRAYS + /* as usual, for the speed hungry :-) */ #ifndef FT_STATIC_RASTER -#define RAS_ARG PRaster raster -#define RAS_ARG_ PRaster raster, +#define RAS_ARG PWorker worker +#define RAS_ARG_ PWorker worker, -#define RAS_VAR raster -#define RAS_VAR_ raster, +#define RAS_VAR worker +#define RAS_VAR_ worker, -#define ras (*raster) +#define ras (*worker) #else /* FT_STATIC_RASTER */ @@ -190,7 +186,7 @@ #define RAS_VAR /* empty */ #define RAS_VAR_ /* empty */ - static TRaster ras; + static TWorker ras; #endif /* FT_STATIC_RASTER */ @@ -215,12 +211,6 @@ #define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) ) #endif - /* Define this if you want to use a more compact storage scheme. This */ - /* increases the number of cells available in the render pool but slows */ - /* down the rendering a bit. It is useful if you have a really tiny */ - /* render pool. */ -#undef GRAYS_COMPACT - /*************************************************************************/ /* */ @@ -240,7 +230,7 @@ #if PIXEL_BITS <= 7 - typedef int TArea; + typedef int TArea; #else /* PIXEL_BITS >= 8 */ @@ -248,7 +238,7 @@ #if FT_UINT_MAX == 0xFFFFU typedef long TArea; #else - typedef int TArea; + typedef int TArea; #endif #endif /* PIXEL_BITS >= 8 */ @@ -258,45 +248,33 @@ #define FT_MAX_GRAY_SPANS 32 -#ifdef GRAYS_COMPACT + typedef struct TCell_* PCell; typedef struct TCell_ { - short x : 14; - short y : 14; - int cover : PIXEL_BITS + 2; - int area : PIXEL_BITS * 2 + 2; + int x; + int cover; + TArea area; + PCell next; - } TCell, *PCell; + } TCell; -#else /* GRAYS_COMPACT */ - typedef struct TCell_ + typedef struct TWorker_ { - TCoord x; - TCoord y; - int cover; - TArea area; - - } TCell, *PCell; - -#endif /* GRAYS_COMPACT */ - - - typedef struct TRaster_ - { - PCell cells; - int max_cells; - int num_cells; - + TCoord ex, ey; TPos min_ex, max_ex; TPos min_ey, max_ey; + TPos count_ex, count_ey; TArea area; int cover; int invalid; - TCoord ex, ey; + PCell cells; + int max_cells; + int num_cells; + TCoord cx, cy; TPos x, y; @@ -321,16 +299,29 @@ int conic_level; int cubic_level; - void* memory; ft_jmp_buf jump_buffer; -#ifdef GRAYS_USE_GAMMA - unsigned char gamma[257]; -#endif + void* buffer; + long buffer_size; + + PCell* ycells; + int ycount; + + } TWorker, *PWorker; + + + typedef struct TRaster_ + { + void* buffer; + long buffer_size; + int band_size; + void* memory; + PWorker worker; } TRaster, *PRaster; + /*************************************************************************/ /* */ /* Initialize the cells table. */ @@ -339,12 +330,16 @@ gray_init_cells( RAS_ARG_ void* buffer, long byte_size ) { - ras.cells = (PCell)buffer; - ras.max_cells = (int)( byte_size / sizeof ( TCell ) ); - ras.num_cells = 0; - ras.area = 0; - ras.cover = 0; - ras.invalid = 1; + ras.buffer = buffer; + ras.buffer_size = byte_size; + + ras.ycells = (PCell*) buffer; + ras.cells = NULL; + ras.max_cells = 0; + ras.num_cells = 0; + ras.area = 0; + ras.cover = 0; + ras.invalid = 1; } @@ -396,22 +391,52 @@ /* */ /* Record the current cell in the table. */ /* */ + static PCell + gray_find_cell( RAS_ARG ) + { + PCell *pcell, cell; + int x = ras.ex; + + + pcell = &ras.ycells[ras.ey]; + for (;;) + { + cell = *pcell; + if ( cell == NULL || cell->x > x ) + break; + + if ( cell->x == x ) + goto Exit; + + pcell = &cell->next; + } + + if ( ras.num_cells >= ras.max_cells ) + ft_longjmp( ras.jump_buffer, 1 ); + + cell = ras.cells + ras.num_cells++; + cell->x = x; + cell->area = 0; + cell->cover = 0; + + cell->next = *pcell; + *pcell = cell; + + Exit: + return cell; + } + + static void gray_record_cell( RAS_ARG ) { - PCell cell; - - if ( !ras.invalid && ( ras.area | ras.cover ) ) { - if ( ras.num_cells >= ras.max_cells ) - ft_longjmp( ras.jump_buffer, 1 ); + PCell cell = gray_find_cell( RAS_VAR ); - cell = ras.cells + ras.num_cells++; - cell->x = (TCoord)(ras.ex - ras.min_ex); - cell->y = (TCoord)(ras.ey - ras.min_ey); - cell->area = ras.area; - cell->cover = ras.cover; + + cell->area += ras.area; + cell->cover += ras.cover; } } @@ -424,9 +449,6 @@ gray_set_cell( RAS_ARG_ TCoord ex, TCoord ey ) { - int invalid, record, clean; - - /* Move the cell pointer to a new position. We set the `invalid' */ /* flag to indicate that the cell isn't part of those we're interested */ /* in during the render phase. This means that: */ @@ -437,39 +459,28 @@ /* Note that if a cell is to the left of the clipping region, it is */ /* actually set to the (min_ex-1) horizontal position. */ - record = 0; - clean = 1; + /* All cells that are on the left of the clipping region go to the */ + /* min_ex - 1 horizontal position. */ + ey -= ras.min_ey; + ex -= ras.min_ex; + if ( ex < 0 ) + ex = -1; - invalid = ( ey < ras.min_ey || ey >= ras.max_ey || ex >= ras.max_ex ); - if ( !invalid ) + /* are we moving to a different cell ? */ + if ( ex != ras.ex || ey != ras.ey ) { - /* All cells that are on the left of the clipping region go to the */ - /* min_ex - 1 horizontal position. */ - if ( ex < ras.min_ex ) - ex = (TCoord)(ras.min_ex - 1); + /* record the current one if it is valid */ + if ( !ras.invalid ) + gray_record_cell( RAS_VAR ); - /* if our position is new, then record the previous cell */ - if ( ex != ras.ex || ey != ras.ey ) - record = 1; - else - clean = ras.invalid; /* do not clean if we didn't move from */ - /* a valid cell */ - } - - /* record the previous cell if needed (i.e., if we changed the cell */ - /* position, or changed the `invalid' flag) */ - if ( ras.invalid != invalid || record ) - gray_record_cell( RAS_VAR ); - - if ( clean ) - { ras.area = 0; ras.cover = 0; } - ras.invalid = invalid; ras.ex = ex; ras.ey = ey; + ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey || + ex >= ras.count_ex ); } @@ -478,16 +489,16 @@ /* Start a new contour at a given cell. */ /* */ static void - gray_start_cell( RAS_ARG_ TCoord ex, - TCoord ey ) + gray_start_cell( RAS_ARG_ TCoord ex, + TCoord ey ) { if ( ex < ras.min_ex ) - ex = (TCoord)(ras.min_ex - 1); + ex = (TCoord)( ras.min_ex - 1 ); ras.area = 0; ras.cover = 0; - ras.ex = ex; - ras.ey = ey; + ras.ex = ex - ras.min_ex; + ras.ey = ey - ras.min_ey; ras.last_ey = SUBPIXELS( ey ); ras.invalid = 0; @@ -500,11 +511,11 @@ /* Render a scanline as one or more cells. */ /* */ static void - gray_render_scanline( RAS_ARG_ TCoord ey, - TPos x1, - TCoord y1, - TPos x2, - TCoord y2 ) + gray_render_scanline( RAS_ARG_ TCoord ey, + TPos x1, + TCoord y1, + TPos x2, + TCoord y2 ) { TCoord ex1, ex2, fx1, fx2, delta; long p, first, dx; @@ -513,8 +524,8 @@ dx = x2 - x1; - ex1 = TRUNC( x1 ); /* if (ex1 >= ras.max_ex) ex1 = ras.max_ex-1; */ - ex2 = TRUNC( x2 ); /* if (ex2 >= ras.max_ex) ex2 = ras.max_ex-1; */ + ex1 = TRUNC( x1 ); + ex2 = TRUNC( x2 ); fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) ); fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) ); @@ -617,7 +628,7 @@ ey1 = TRUNC( ras.last_ey ); - ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */ + ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */ fy1 = (TCoord)( ras.y - ras.last_ey ); fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); @@ -672,7 +683,7 @@ ras.cover += delta; ey1 += incr; - gray_set_cell( raster, ex, ey1 ); + gray_set_cell( &ras, ex, ey1 ); delta = (int)( first + first - ONE_PIXEL ); area = (TArea)two_fx * delta; @@ -681,12 +692,14 @@ ras.area += area; ras.cover += delta; ey1 += incr; - gray_set_cell( raster, ex, ey1 ); + + gray_set_cell( &ras, ex, ey1 ); } delta = (int)( fy2 - ONE_PIXEL + first ); ras.area += (TArea)two_fx * delta; ras.cover += delta; + goto End; } @@ -813,7 +826,7 @@ { /* we compute the mid-point directly in order to avoid */ /* calling gray_split_conic() */ - TPos to_x, to_y, mid_x, mid_y; + TPos to_x, to_y, mid_x, mid_y; to_x = UPSCALE( to->x ); @@ -823,6 +836,7 @@ gray_render_line( RAS_VAR_ mid_x, mid_y ); gray_render_line( RAS_VAR_ to_x, to_y ); + return; } @@ -884,6 +898,7 @@ arc -= 2; } } + return; } @@ -1032,230 +1047,39 @@ arc -= 3; } } + return; } - /* a macro comparing two cell pointers. Returns true if a <= b. */ -#if 1 - -#define PACK( a ) ( ( (long)(a)->y << 16 ) + (a)->x ) -#define LESS_THAN( a, b ) ( PACK( a ) < PACK( b ) ) - -#else /* 1 */ - -#define LESS_THAN( a, b ) ( (a)->y < (b)->y || \ - ( (a)->y == (b)->y && (a)->x < (b)->x ) ) - -#endif /* 1 */ - -#define SWAP_CELLS( a, b, temp ) do \ - { \ - temp = *(a); \ - *(a) = *(b); \ - *(b) = temp; \ - } while ( 0 ) -#define DEBUG_SORT -#define QUICK_SORT - -#ifdef SHELL_SORT - - /* a simple shell sort algorithm that works directly on our */ - /* cells table */ - static void - gray_shell_sort ( PCell cells, - int count ) - { - PCell i, j, limit = cells + count; - TCell temp; - int gap; - - - /* compute initial gap */ - for ( gap = 0; ++gap < count; gap *= 3 ) - ; - - while ( gap /= 3 ) - { - for ( i = cells + gap; i < limit; i++ ) - { - for ( j = i - gap; ; j -= gap ) - { - PCell k = j + gap; - - - if ( LESS_THAN( j, k ) ) - break; - - SWAP_CELLS( j, k, temp ); - - if ( j < cells + gap ) - break; - } - } - } - } - -#endif /* SHELL_SORT */ - - -#ifdef QUICK_SORT - - /* This is a non-recursive quicksort that directly process our cells */ - /* array. It should be faster than calling the stdlib qsort(), and we */ - /* can even tailor our insertion threshold... */ - -#define QSORT_THRESHOLD 9 /* below this size, a sub-array will be sorted */ - /* through a normal insertion sort */ - - static void - gray_quick_sort( PCell cells, - int count ) - { - PCell stack[40]; /* should be enough ;-) */ - PCell* top; /* top of stack */ - PCell base, limit; - TCell temp; - - - limit = cells + count; - base = cells; - top = stack; - - for (;;) - { - int len = (int)( limit - base ); - PCell i, j, pivot; - - - if ( len > QSORT_THRESHOLD ) - { - /* we use base + len/2 as the pivot */ - pivot = base + len / 2; - SWAP_CELLS( base, pivot, temp ); - - i = base + 1; - j = limit - 1; - - /* now ensure that *i <= *base <= *j */ - if ( LESS_THAN( j, i ) ) - SWAP_CELLS( i, j, temp ); - - if ( LESS_THAN( base, i ) ) - SWAP_CELLS( base, i, temp ); - - if ( LESS_THAN( j, base ) ) - SWAP_CELLS( base, j, temp ); - - for (;;) - { - do i++; while ( LESS_THAN( i, base ) ); - do j--; while ( LESS_THAN( base, j ) ); - - if ( i > j ) - break; - - SWAP_CELLS( i, j, temp ); - } - - SWAP_CELLS( base, j, temp ); - - /* now, push the largest sub-array */ - if ( j - base > limit - i ) - { - top[0] = base; - top[1] = j; - base = i; - } - else - { - top[0] = i; - top[1] = limit; - limit = j; - } - top += 2; - } - else - { - /* the sub-array is small, perform insertion sort */ - j = base; - i = j + 1; - - for ( ; i < limit; j = i, i++ ) - { - for ( ; LESS_THAN( j + 1, j ); j-- ) - { - SWAP_CELLS( j + 1, j, temp ); - if ( j == base ) - break; - } - } - if ( top > stack ) - { - top -= 2; - base = top[0]; - limit = top[1]; - } - else - break; - } - } - } - -#endif /* QUICK_SORT */ - - -#ifdef DEBUG_GRAYS -#ifdef DEBUG_SORT - - static int - gray_check_sort( PCell cells, - int count ) - { - PCell p, q; - - - for ( p = cells + count - 2; p >= cells; p-- ) - { - q = p + 1; - if ( !LESS_THAN( p, q ) ) - return 0; - } - return 1; - } - -#endif /* DEBUG_SORT */ -#endif /* DEBUG_GRAYS */ - static int gray_move_to( const FT_Vector* to, - FT_Raster raster ) + PWorker worker ) { TPos x, y; /* record current cell, if any */ - gray_record_cell( (PRaster)raster ); + gray_record_cell( worker ); /* start to a new position */ x = UPSCALE( to->x ); y = UPSCALE( to->y ); - gray_start_cell( (PRaster)raster, TRUNC( x ), TRUNC( y ) ); + gray_start_cell( worker, TRUNC( x ), TRUNC( y ) ); - ((PRaster)raster)->x = x; - ((PRaster)raster)->y = y; + worker->x = x; + worker->y = y; return 0; } static int gray_line_to( const FT_Vector* to, - FT_Raster raster ) + PWorker worker ) { - gray_render_line( (PRaster)raster, - UPSCALE( to->x ), UPSCALE( to->y ) ); + gray_render_line( worker, UPSCALE( to->x ), UPSCALE( to->y ) ); return 0; } @@ -1263,9 +1087,9 @@ static int gray_conic_to( const FT_Vector* control, const FT_Vector* to, - FT_Raster raster ) + PWorker worker ) { - gray_render_conic( (PRaster)raster, control, to ); + gray_render_conic( worker, control, to ); return 0; } @@ -1274,9 +1098,9 @@ gray_cubic_to( const FT_Vector* control1, const FT_Vector* control2, const FT_Vector* to, - FT_Raster raster ) + PWorker worker ) { - gray_render_cubic( (PRaster)raster, control1, control2, to ); + gray_render_cubic( worker, control1, control2, to ); return 0; } @@ -1285,10 +1109,10 @@ gray_render_span( int y, int count, const FT_Span* spans, - PRaster raster ) + PWorker worker ) { unsigned char* p; - FT_Bitmap* map = &raster->target; + FT_Bitmap* map = &worker->target; /* first of all, compute the scanline offset */ @@ -1301,64 +1125,46 @@ unsigned char coverage = spans->coverage; -#ifdef GRAYS_USE_GAMMA - coverage = raster->gamma[coverage]; -#endif - if ( coverage ) -#if 1 - FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len ); -#else /* 1 */ { - q = p + spans->x; - limit = q + spans->len; - for ( ; q < limit; q++ ) - q[0] = (unsigned char)coverage; + /* For small-spans it is faster to do it by ourselves than + * calling `memset'. This is mainly due to the cost of the + * function call. + */ + if ( spans->len >= 8 ) + FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len ); + else + { + unsigned char* q = p + spans->x; + + + switch ( spans->len ) + { + case 7: *q++ = (unsigned char)coverage; + case 6: *q++ = (unsigned char)coverage; + case 5: *q++ = (unsigned char)coverage; + case 4: *q++ = (unsigned char)coverage; + case 3: *q++ = (unsigned char)coverage; + case 2: *q++ = (unsigned char)coverage; + case 1: *q = (unsigned char)coverage; + default: + ; + } + } } -#endif /* 1 */ } } -#ifdef DEBUG_GRAYS - -#include <stdio.h> - - static void - gray_dump_cells( RAS_ARG ) - { - PCell cell, limit; - int y = -1; - - - cell = ras.cells; - limit = cell + ras.num_cells; - - for ( ; cell < limit; cell++ ) - { - if ( cell->y != y ) - { - fprintf( stderr, "\n%2d: ", cell->y ); - y = cell->y; - } - fprintf( stderr, "[%d %d %d]", - cell->x, cell->area, cell->cover ); - } - fprintf(stderr, "\n" ); - } - -#endif /* DEBUG_GRAYS */ - - static void gray_hline( RAS_ARG_ TCoord x, TCoord y, TPos area, int acount ) { - FT_Span* span; - int count; - int coverage; + FT_Span* span; + int count; + int coverage; /* compute the coverage line's coverage, depending on the */ @@ -1392,13 +1198,13 @@ if ( coverage ) { - /* see if we can add this span to the current list */ + /* see whether we can add this span to the current list */ count = ras.num_gray_spans; span = ras.gray_spans + count - 1; if ( count > 0 && ras.span_y == y && (int)span->x + span->len == (int)x && - span->coverage == coverage ) + span->coverage == coverage ) { span->len = (unsigned short)( span->len + acount ); return; @@ -1441,17 +1247,40 @@ span->x = (short)x; span->len = (unsigned short)acount; span->coverage = (unsigned char)coverage; + ras.num_gray_spans++; } } +#ifdef DEBUG_GRAYS + + /* to be called while in the debugger */ + gray_dump_cells( RAS_ARG ) + { + int yindex; + + + for ( yindex = 0; yindex < ras.ycount; yindex++ ) + { + PCell cell; + + + printf( "%3d:", yindex ); + + for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next ) + printf( " (%3d, c:%4d, a:%6d)", cell->x, cell->cover, cell->area ); + printf( "\n" ); + } + } + +#endif /* DEBUG_GRAYS */ + + static void gray_sweep( RAS_ARG_ const FT_Bitmap* target ) { - TCoord x, y, cover; - TArea area; - PCell start, cur, limit; + int yindex; FT_UNUSED( target ); @@ -1459,86 +1288,41 @@ if ( ras.num_cells == 0 ) return; - cur = ras.cells; - limit = cur + ras.num_cells; - - cover = 0; - ras.span_y = -1; ras.num_gray_spans = 0; - for (;;) + for ( yindex = 0; yindex < ras.ycount; yindex++ ) { - start = cur; - y = start->y; - x = start->x; + PCell cell = ras.ycells[yindex]; + TCoord cover = 0; + TCoord x = 0; - area = start->area; - cover += start->cover; - /* accumulate all start cells */ - for (;;) + for ( ; cell != NULL; cell = cell->next ) { - ++cur; - if ( cur >= limit || cur->y != start->y || cur->x != start->x ) - break; + TArea area; - area += cur->area; - cover += cur->cover; + + if ( cell->x > x && cover != 0 ) + gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), + cell->x - x ); + + cover += cell->cover; + area = cover * ( ONE_PIXEL * 2 ) - cell->area; + + if ( area != 0 && cell->x >= 0 ) + gray_hline( RAS_VAR_ cell->x, yindex, area, 1 ); + + x = cell->x + 1; } - /* if the start cell has a non-null area, we must draw an */ - /* individual gray pixel there */ - if ( area && x >= 0 ) - { - gray_hline( RAS_VAR_ x, y, cover * ( ONE_PIXEL * 2 ) - area, 1 ); - x++; - } - - if ( x < 0 ) - x = 0; - - if ( cur < limit && start->y == cur->y ) - { - /* draw a gray span between the start cell and the current one */ - if ( cur->x > x ) - gray_hline( RAS_VAR_ x, y, - cover * ( ONE_PIXEL * 2 ), cur->x - x ); - } - else - { - /* draw a gray span until the end of the clipping region */ - if ( cover && x < ras.max_ex - ras.min_ex ) - gray_hline( RAS_VAR_ x, y, - cover * ( ONE_PIXEL * 2 ), - (int)( ras.max_ex - x - ras.min_ex ) ); - cover = 0; - } - - if ( cur >= limit ) - break; + if ( cover != 0 ) + gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), + ras.count_ex - x ); } if ( ras.render_span && ras.num_gray_spans > 0 ) ras.render_span( ras.span_y, ras.num_gray_spans, ras.gray_spans, ras.render_span_data ); - -#ifdef DEBUG_GRAYS - - { - int n; - FT_Span* span; - - - fprintf( stderr, "y=%3d ", ras.span_y ); - span = ras.gray_spans; - for ( n = 0; n < ras.num_gray_spans; n++, span++ ) - fprintf( stderr, "[%d..%d]:%02x ", - span->x, span->x + span->len - 1, span->coverage ); - fprintf( stderr, "\n" ); - } - -#endif /* DEBUG_GRAYS */ - } @@ -1621,8 +1405,11 @@ v_start = outline->points[first]; v_last = outline->points[last]; - v_start.x = SCALED( v_start.x ); v_start.y = SCALED( v_start.y ); - v_last.x = SCALED( v_last.x ); v_last.y = SCALED( v_last.y ); + v_start.x = SCALED( v_start.x ); + v_start.y = SCALED( v_start.y ); + + v_last.x = SCALED( v_last.x ); + v_last.y = SCALED( v_last.y ); v_control = v_start; @@ -1705,7 +1492,8 @@ if ( tag == FT_CURVE_TAG_ON ) { - error = func_interface->conic_to( &v_control, &vec, user ); + error = func_interface->conic_to( &v_control, &vec, + user ); if ( error ) goto Exit; continue; @@ -1717,7 +1505,8 @@ v_middle.x = ( v_control.x + vec.x ) / 2; v_middle.y = ( v_control.y + vec.y ) / 2; - error = func_interface->conic_to( &v_control, &v_middle, user ); + error = func_interface->conic_to( &v_control, &v_middle, + user ); if ( error ) goto Exit; @@ -1725,7 +1514,8 @@ goto Do_Conic; } - error = func_interface->conic_to( &v_control, &v_start, user ); + error = func_interface->conic_to( &v_control, &v_start, + user ); goto Close; } @@ -1741,8 +1531,11 @@ point += 2; tags += 2; - vec1.x = SCALED( point[-2].x ); vec1.y = SCALED( point[-2].y ); - vec2.x = SCALED( point[-1].x ); vec2.y = SCALED( point[-1].y ); + vec1.x = SCALED( point[-2].x ); + vec1.y = SCALED( point[-2].y ); + + vec2.x = SCALED( point[-1].x ); + vec2.y = SCALED( point[-1].y ); if ( point <= limit ) { @@ -1816,7 +1609,7 @@ } else { - error = ErrRaster_MemoryOverflow; + error = ErrRaster_Memory_Overflow; } return error; @@ -1849,6 +1642,9 @@ if ( ras.max_ex > clip->xMax ) ras.max_ex = clip->xMax; if ( ras.max_ey > clip->yMax ) ras.max_ey = clip->yMax; + 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 */ /* the code in gray_render_conic() and gray_render_cubic() for more */ /* details */ @@ -1859,9 +1655,9 @@ int level = 0; - if ( ras.max_ex > 24 || ras.max_ey > 24 ) + if ( ras.count_ex > 24 || ras.count_ey > 24 ) level++; - if ( ras.max_ex > 120 || ras.max_ey > 120 ) + if ( ras.count_ex > 120 || ras.count_ey > 120 ) level++; ras.conic_level <<= level; @@ -1893,46 +1689,61 @@ TPos bottom, top, middle; int error; + { + PCell cells_max; + int yindex; + long cell_start, cell_end, cell_mod; + + + ras.ycells = (PCell*)ras.buffer; + ras.ycount = band->max - band->min; + + cell_start = sizeof ( PCell ) * ras.ycount; + cell_mod = cell_start % sizeof ( TCell ); + if ( cell_mod > 0 ) + cell_start += sizeof ( TCell ) - cell_mod; + + cell_end = ras.buffer_size; + cell_end -= cell_end % sizeof( TCell ); + + cells_max = (PCell)( (char*)ras.buffer + cell_end ); + ras.cells = (PCell)( (char*)ras.buffer + cell_start ); + if ( ras.cells >= cells_max ) + goto ReduceBands; + + ras.max_cells = cells_max - ras.cells; + if ( ras.max_cells < 2 ) + goto ReduceBands; + + for ( yindex = 0; yindex < ras.ycount; yindex++ ) + ras.ycells[yindex] = NULL; + } ras.num_cells = 0; ras.invalid = 1; ras.min_ey = band->min; ras.max_ey = band->max; + ras.count_ey = band->max - band->min; -#if 1 error = gray_convert_glyph_inner( RAS_VAR ); -#else - error = FT_Outline_Decompose( outline, &func_interface, &ras ) || - gray_record_cell( RAS_VAR ); -#endif if ( !error ) { -#ifdef SHELL_SORT - gray_shell_sort( ras.cells, ras.num_cells ); -#else - gray_quick_sort( ras.cells, ras.num_cells ); -#endif - -#ifdef DEBUG_GRAYS - gray_check_sort( ras.cells, ras.num_cells ); - gray_dump_cells( RAS_VAR ); -#endif - - gray_sweep( RAS_VAR_ &ras.target ); + gray_sweep( RAS_VAR_ &ras.target ); band--; continue; } - else if ( error != ErrRaster_MemoryOverflow ) + else if ( error != ErrRaster_Memory_Overflow ) return 1; - /* render pool overflow, we will reduce the render band by half */ + ReduceBands: + /* render pool overflow; we will reduce the render band by half */ bottom = band->min; top = band->max; middle = bottom + ( ( top - bottom ) >> 1 ); - /* waoow! This is too complex for a single scanline, something */ - /* must be really rotten here! */ + /* This is too complex for a single scanline; there must */ + /* be some problems. */ if ( middle == bottom ) { #ifdef DEBUG_GRAYS @@ -1965,10 +1776,11 @@ { const FT_Outline* outline = (const FT_Outline*)params->source; const FT_Bitmap* target_map = params->target; + PWorker worker; - if ( !raster || !raster->cells || !raster->max_cells ) - return -1; + if ( !raster || !raster->buffer || !raster->buffer_size ) + return ErrRaster_Invalid_Argument; /* return immediately if the outline is empty */ if ( outline->n_points == 0 || outline->n_contours <= 0 ) @@ -1981,10 +1793,21 @@ outline->contours[outline->n_contours - 1] + 1 ) return ErrRaster_Invalid_Outline; + worker = raster->worker; + /* if direct mode is not set, we must have a target bitmap */ - if ( ( params->flags & FT_RASTER_FLAG_DIRECT ) == 0 && - ( !target_map || !target_map->buffer ) ) - return -1; + if ( ( params->flags & FT_RASTER_FLAG_DIRECT ) == 0 ) + { + if ( !target_map ) + return ErrRaster_Invalid_Argument; + + /* nothing to do */ + if ( !target_map->width || !target_map->rows ) + return 0; + + if ( !target_map->buffer ) + return ErrRaster_Invalid_Argument; + } /* this version does not support monochrome rendering */ if ( !( params->flags & FT_RASTER_FLAG_AA ) ) @@ -2011,9 +1834,13 @@ ras.clip_box.yMax = 32767L; } + 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.num_gray_spans = 0; if ( target_map ) ras.target = *target_map; @@ -2027,42 +1854,13 @@ ras.render_span_data = params->user; } - return gray_convert_glyph( (PRaster)raster ); + return gray_convert_glyph( worker ); } /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ /**** a static object. *****/ -#ifdef GRAYS_USE_GAMMA - - /* initialize the "gamma" table. Yes, this is really a crummy function */ - /* but the results look pretty good for something that simple. */ - /* */ -#define M_MAX 255 -#define M_X 128 -#define M_Y 192 - - static void - grays_init_gamma( PRaster raster ) - { - unsigned int x, a; - - - for ( x = 0; x < 256; x++ ) - { - if ( x <= M_X ) - a = ( x * M_Y + M_X / 2) / M_X; - else - a = M_Y + ( ( x - M_X ) * ( M_MAX - M_Y ) + - ( M_MAX - M_X ) / 2 ) / ( M_MAX - M_X ); - - raster->gamma[x] = (unsigned char)a; - } - } - -#endif /* GRAYS_USE_GAMMA */ - #ifdef _STANDALONE_ static int @@ -2077,10 +1875,6 @@ *araster = (FT_Raster)&the_raster; FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); -#ifdef GRAYS_USE_GAMMA - grays_init_gamma( (PRaster)*araster ); -#endif - return 0; } @@ -2107,10 +1901,6 @@ { raster->memory = memory; *araster = (FT_Raster)raster; - -#ifdef GRAYS_USE_GAMMA - grays_init_gamma( raster ); -#endif } return error; @@ -2130,17 +1920,37 @@ static void - gray_raster_reset( FT_Raster raster, - char* pool_base, - long pool_size ) + gray_raster_reset( FT_Raster raster, + char* pool_base, + long pool_size ) { PRaster rast = (PRaster)raster; - if ( raster && pool_base && pool_size >= 4096 ) - gray_init_cells( rast, (char*)pool_base, pool_size ); + if ( raster ) + { + if ( pool_base && pool_size >= (long)sizeof ( TWorker ) + 2048 ) + { + PWorker worker = (PWorker)pool_base; - rast->band_size = (int)( ( pool_size / sizeof ( TCell ) ) / 8 ); + + rast->worker = worker; + rast->buffer = pool_base + + ( ( sizeof ( TWorker ) + sizeof ( TCell ) - 1 ) & + ~( sizeof ( TCell ) - 1 ) ); + rast->buffer_size = (long)( ( pool_base + pool_size ) - + (char*)rast->buffer ) & + ~( sizeof ( TCell ) - 1 ); + rast->band_size = (int)( rast->buffer_size / + ( sizeof ( TCell ) * 8 ) ); + } + else + { + rast->buffer = NULL; + rast->buffer_size = 0; + rast->worker = NULL; + } + } } diff --git a/src/libs/freetype2/smooth/ftsmooth.c b/src/libs/freetype2/smooth/ftsmooth.c index 54bf9e7575..85d04eb458 100644 --- a/src/libs/freetype2/smooth/ftsmooth.c +++ b/src/libs/freetype2/smooth/ftsmooth.c @@ -4,7 +4,7 @@ /* */ /* Anti-aliasing renderer interface (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -98,16 +98,17 @@ FT_GlyphSlot slot, FT_Render_Mode mode, const FT_Vector* origin, - FT_Render_Mode required_mode, - FT_Int hmul, - FT_Int vmul ) + FT_Render_Mode required_mode ) { FT_Error error; FT_Outline* outline = NULL; FT_BBox cbox; - FT_UInt width, height, pitch; + FT_UInt width, height, height_org, width_org, pitch; FT_Bitmap* bitmap; FT_Memory memory; + FT_Int hmul = mode == FT_RENDER_MODE_LCD; + FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; + FT_Pos x_shift, y_shift, x_left, y_top; FT_Raster_Params params; @@ -142,6 +143,9 @@ bitmap = &slot->bitmap; memory = render->root.memory; + width_org = width; + height_org = height; + /* release old bitmap buffer */ if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) { @@ -153,12 +157,42 @@ pitch = width; if ( hmul ) { - width = width * hmul; + width = width * 3; pitch = FT_PAD_CEIL( width, 4 ); } if ( vmul ) - height *= vmul; + height *= 3; + + x_shift = (FT_Int) cbox.xMin; + y_shift = (FT_Int) cbox.yMin; + x_left = (FT_Int)( cbox.xMin >> 6 ); + y_top = (FT_Int)( cbox.yMax >> 6 ); + +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + + if ( slot->library->lcd_filter_func ) + { + FT_Int extra = slot->library->lcd_extra; + + + if ( hmul ) + { + x_shift -= 64 * ( extra >> 1 ); + width += 3 * extra; + pitch = FT_PAD_CEIL( width, 4 ); + x_left -= extra >> 1; + } + + if ( vmul ) + { + y_shift -= 64 * ( extra >> 1 ); + height += 3 * extra; + y_top += extra >> 1; + } + } + +#endif bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; bitmap->num_grays = 256; @@ -166,32 +200,35 @@ bitmap->rows = height; bitmap->pitch = pitch; + /* translate outline to render it into the bitmap */ + FT_Outline_Translate( outline, -x_shift, -y_shift ); + if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) goto Exit; slot->internal->flags |= FT_GLYPH_OWN_BITMAP; - /* translate outline to render it into the bitmap */ - FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); - /* set up parameters */ params.target = bitmap; params.source = outline; params.flags = FT_RASTER_FLAG_AA; +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + /* implode outline if needed */ { - FT_Int n; + FT_Vector* points = outline->points; + FT_Vector* points_end = points + outline->n_points; FT_Vector* vec; if ( hmul ) - for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ ) - vec->x *= hmul; + for ( vec = points; vec < points_end; vec++ ) + vec->x *= 3; if ( vmul ) - for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ ) - vec->y *= vmul; + for ( vec = points; vec < points_end; vec++ ) + vec->y *= 3; } /* render outline into the bitmap */ @@ -199,27 +236,86 @@ /* deflate outline if needed */ { - FT_Int n; + FT_Vector* points = outline->points; + FT_Vector* points_end = points + outline->n_points; FT_Vector* vec; if ( hmul ) - for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ ) - vec->x /= hmul; + for ( vec = points; vec < points_end; vec++ ) + vec->x /= 3; if ( vmul ) - for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ ) - vec->y /= vmul; + for ( vec = points; vec < points_end; vec++ ) + vec->y /= 3; } - FT_Outline_Translate( outline, cbox.xMin, cbox.yMin ); + if ( slot->library->lcd_filter_func ) + slot->library->lcd_filter_func( bitmap, mode, slot->library ); + +#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + /* render outline into bitmap */ + error = render->raster_render( render->raster, ¶ms ); + + /* expand it horizontally */ + if ( hmul ) + { + FT_Byte* line = bitmap->buffer; + FT_UInt hh; + + + for ( hh = height_org; hh > 0; hh--, line += pitch ) + { + FT_UInt xx; + FT_Byte* end = line + width; + + + for ( xx = width_org; xx > 0; xx-- ) + { + FT_UInt pixel = line[xx-1]; + + + end[-3] = (FT_Byte)pixel; + end[-2] = (FT_Byte)pixel; + end[-1] = (FT_Byte)pixel; + end -= 3; + } + } + } + + /* expand it vertically */ + if ( vmul ) + { + FT_Byte* read = bitmap->buffer + ( height - height_org ) * pitch; + FT_Byte* write = bitmap->buffer; + FT_UInt hh; + + + for ( hh = height_org; hh > 0; hh-- ) + { + memcpy( write, read, pitch ); + write += pitch; + + memcpy( write, read, pitch ); + write += pitch; + + memcpy( write, read, pitch ); + write += pitch; + read += pitch; + } + } + +#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + FT_Outline_Translate( outline, x_shift, y_shift ); if ( error ) goto Exit; slot->format = FT_GLYPH_FORMAT_BITMAP; - slot->bitmap_left = (FT_Int)( cbox.xMin >> 6 ); - slot->bitmap_top = (FT_Int)( cbox.yMax >> 6 ); + slot->bitmap_left = x_left; + slot->bitmap_top = y_top; Exit: if ( outline && origin ) @@ -240,8 +336,7 @@ mode = FT_RENDER_MODE_NORMAL; return ft_smooth_render_generic( render, slot, mode, origin, - FT_RENDER_MODE_NORMAL, - 0, 0 ); + FT_RENDER_MODE_NORMAL ); } @@ -255,8 +350,7 @@ FT_Error error; error = ft_smooth_render_generic( render, slot, mode, origin, - FT_RENDER_MODE_LCD, - 3, 0 ); + FT_RENDER_MODE_LCD ); if ( !error ) slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD; @@ -274,8 +368,7 @@ FT_Error error; error = ft_smooth_render_generic( render, slot, mode, origin, - FT_RENDER_MODE_LCD_V, - 0, 3 ); + FT_RENDER_MODE_LCD_V ); if ( !error ) slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD_V; diff --git a/src/libs/freetype2/truetype/truetype.c b/src/libs/freetype2/truetype/truetype.c index 4abb01ec5c..b36473a72d 100644 --- a/src/libs/freetype2/truetype/truetype.c +++ b/src/libs/freetype2/truetype/truetype.c @@ -4,7 +4,7 @@ /* */ /* FreeType TrueType driver component (body only). */ /* */ -/* Copyright 1996-2001, 2004 by */ +/* Copyright 1996-2001, 2004, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,7 +24,7 @@ #include "ttgload.c" /* glyph loader */ #include "ttobjs.c" /* object manager */ -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER #include "ttinterp.c" #endif diff --git a/src/libs/freetype2/truetype/ttdriver.c b/src/libs/freetype2/truetype/ttdriver.c index fa25c25ede..e1b3d7e8f4 100644 --- a/src/libs/freetype2/truetype/ttdriver.c +++ b/src/libs/freetype2/truetype/ttdriver.c @@ -4,7 +4,7 @@ /* */ /* TrueType font driver implementation (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -187,15 +187,15 @@ { TT_Face ttface = (TT_Face)size->face; SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; - FT_ULong index; + FT_ULong strike_index; - error = sfnt->set_sbit_strike( ttface, req, &index ); + error = sfnt->set_sbit_strike( ttface, req, &strike_index ); if ( error ) ttsize->strike_index = 0xFFFFFFFFUL; else - return tt_size_select( size, index ); + return tt_size_select( size, strike_index ); } #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ @@ -243,6 +243,7 @@ { TT_GlyphSlot slot = (TT_GlyphSlot)ttslot; TT_Size size = (TT_Size)ttsize; + FT_Face face = ttslot->face; FT_Error error; @@ -252,6 +253,9 @@ if ( !size ) return TT_Err_Invalid_Size_Handle; + if ( !face || glyph_index >= (FT_UInt)face->num_glyphs ) + return TT_Err_Invalid_Argument; + if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) ) { load_flags |= FT_LOAD_NO_HINTING | @@ -294,7 +298,7 @@ static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = { -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING FT_TRUETYPE_ENGINE_TYPE_UNPATENTED @@ -302,11 +306,11 @@ FT_TRUETYPE_ENGINE_TYPE_PATENTED #endif -#else /* !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#else /* !TT_USE_BYTECODE_INTERPRETER */ FT_TRUETYPE_ENGINE_TYPE_NONE -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#endif /* TT_USE_BYTECODE_INTERPRETER */ }; static const FT_ServiceDescRec tt_services[] = @@ -354,7 +358,7 @@ { FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_SCALABLE | -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER FT_MODULE_DRIVER_HAS_HINTER, #else 0, diff --git a/src/libs/freetype2/truetype/ttgload.c b/src/libs/freetype2/truetype/ttgload.c index 158111384e..c595487f06 100644 --- a/src/libs/freetype2/truetype/ttgload.c +++ b/src/libs/freetype2/truetype/ttgload.c @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -188,6 +188,9 @@ if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) ) return error; + loader->cursor = stream->cursor; + loader->limit = stream->limit; + return TT_Err_Ok; } @@ -205,26 +208,26 @@ FT_CALLBACK_DEF( FT_Error ) TT_Load_Glyph_Header( TT_Loader loader ) { - FT_Stream stream = loader->stream; - FT_Int byte_len = loader->byte_len - 10; + FT_Byte* p = loader->cursor; + FT_Byte* limit = loader->limit; - if ( byte_len < 0 ) + if ( p + 10 > limit ) return TT_Err_Invalid_Outline; - loader->n_contours = FT_GET_SHORT(); + loader->n_contours = FT_NEXT_SHORT( p ); - loader->bbox.xMin = FT_GET_SHORT(); - loader->bbox.yMin = FT_GET_SHORT(); - loader->bbox.xMax = FT_GET_SHORT(); - loader->bbox.yMax = FT_GET_SHORT(); + loader->bbox.xMin = FT_NEXT_SHORT( p ); + loader->bbox.yMin = FT_NEXT_SHORT( p ); + loader->bbox.xMax = FT_NEXT_SHORT( p ); + loader->bbox.yMax = FT_NEXT_SHORT( p ); FT_TRACE5(( " # of contours: %d\n", loader->n_contours )); FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin, loader->bbox.xMax )); FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin, loader->bbox.yMax )); - loader->byte_len = byte_len; + loader->cursor = p; return TT_Err_Ok; } @@ -234,14 +237,14 @@ TT_Load_Simple_Glyph( TT_Loader load ) { FT_Error error; - FT_Stream stream = load->stream; + FT_Byte* p = load->cursor; + FT_Byte* limit = load->limit; FT_GlyphLoader gloader = load->gloader; FT_Int n_contours = load->n_contours; FT_Outline* outline; TT_Face face = (TT_Face)load->face; FT_UShort n_ins; FT_Int n, n_points; - FT_Int byte_len = load->byte_len; FT_Byte *flag, *flag_limit; FT_Byte c, count; @@ -260,12 +263,11 @@ cont_limit = cont + n_contours; /* check space for contours array + instructions count */ - byte_len -= 2 * ( n_contours + 1 ); - if ( byte_len < 0 ) + if ( n_contours >= 0xFFF || p + (n_contours + 1) * 2 > limit ) goto Invalid_Outline; for ( ; cont < cont_limit; cont++ ) - cont[0] = FT_GET_USHORT(); + cont[0] = FT_NEXT_USHORT( p ); n_points = 0; if ( n_contours > 0 ) @@ -287,7 +289,10 @@ load->glyph->control_len = 0; load->glyph->control_data = 0; - n_ins = FT_GET_USHORT(); + if ( p + 2 > limit ) + goto Invalid_Outline; + + n_ins = FT_NEXT_USHORT( p ); FT_TRACE5(( " Instructions size: %u\n", n_ins )); @@ -298,27 +303,26 @@ goto Fail; } - byte_len -= (FT_Int)n_ins; - if ( byte_len < 0 ) + if ( ( limit - p ) < n_ins ) { FT_TRACE0(( "TT_Load_Simple_Glyph: Instruction count mismatch!\n" )); error = TT_Err_Too_Many_Hints; goto Fail; } -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER if ( IS_HINTED( load->load_flags ) ) { load->glyph->control_len = n_ins; load->glyph->control_data = load->exec->glyphIns; - FT_MEM_COPY( load->exec->glyphIns, stream->cursor, (FT_Long)n_ins ); + FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins ); } -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#endif /* TT_USE_BYTECODE_INTERPRETER */ - stream->cursor += (FT_Int)n_ins; + p += n_ins; /* reading the point tags */ flag = (FT_Byte*)outline->tags; @@ -328,16 +332,16 @@ while ( flag < flag_limit ) { - if ( --byte_len < 0 ) + if ( p + 1 > limit ) goto Invalid_Outline; - *flag++ = c = FT_GET_BYTE(); + *flag++ = c = FT_NEXT_BYTE( p ); if ( c & 8 ) { - if ( --byte_len < 0 ) + if ( p + 1 > limit ) goto Invalid_Outline; - count = FT_GET_BYTE(); + count = FT_NEXT_BYTE( p ); if ( flag + (FT_Int)count > flag_limit ) goto Invalid_Outline; @@ -346,23 +350,6 @@ } } - /* check that there is enough room to load the coordinates */ - for ( flag = (FT_Byte*)outline->tags; flag < flag_limit; flag++ ) - { - if ( *flag & 2 ) - byte_len -= 1; - else if ( ( *flag & 16 ) == 0 ) - byte_len -= 2; - - if ( *flag & 4 ) - byte_len -= 1; - else if ( ( *flag & 32 ) == 0 ) - byte_len -= 2; - } - - if ( byte_len < 0 ) - goto Invalid_Outline; - /* reading the X coordinates */ vec = outline->points; @@ -377,12 +364,20 @@ if ( *flag & 2 ) { - y = (FT_Pos)FT_GET_BYTE(); + if ( p + 1 > limit ) + goto Invalid_Outline; + + y = (FT_Pos)FT_NEXT_BYTE( p ); if ( ( *flag & 16 ) == 0 ) y = -y; } else if ( ( *flag & 16 ) == 0 ) - y = (FT_Pos)FT_GET_SHORT(); + { + if ( p + 2 > limit ) + goto Invalid_Outline; + + y = (FT_Pos)FT_NEXT_SHORT( p ); + } x += y; vec->x = x; @@ -402,12 +397,20 @@ if ( *flag & 4 ) { - y = (FT_Pos)FT_GET_BYTE(); + if ( p +1 > limit ) + goto Invalid_Outline; + + y = (FT_Pos)FT_NEXT_BYTE( p ); if ( ( *flag & 32 ) == 0 ) y = -y; } else if ( ( *flag & 32 ) == 0 ) - y = (FT_Pos)FT_GET_SHORT(); + { + if ( p + 2 > limit ) + goto Invalid_Outline; + + y = (FT_Pos)FT_NEXT_SHORT( p ); + } x += y; vec->y = x; @@ -420,7 +423,7 @@ outline->n_points = (FT_UShort)n_points; outline->n_contours = (FT_Short) n_contours; - load->byte_len = byte_len; + load->cursor = p; Fail: return error; @@ -435,11 +438,11 @@ TT_Load_Composite_Glyph( TT_Loader loader ) { FT_Error error; - FT_Stream stream = loader->stream; + FT_Byte* p = loader->cursor; + FT_Byte* limit = loader->limit; FT_GlyphLoader gloader = loader->gloader; FT_SubGlyph subglyph; FT_UInt num_subglyphs; - FT_Int byte_len = loader->byte_len; num_subglyphs = 0; @@ -447,6 +450,7 @@ do { FT_Fixed xx, xy, yy, yx; + FT_UInt count; /* check that we can load a new subglyph */ @@ -455,41 +459,40 @@ goto Fail; /* check space */ - byte_len -= 4; - if ( byte_len < 0 ) + if ( p + 4 > limit ) goto Invalid_Composite; subglyph = gloader->current.subglyphs + num_subglyphs; subglyph->arg1 = subglyph->arg2 = 0; - subglyph->flags = FT_GET_USHORT(); - subglyph->index = FT_GET_USHORT(); + subglyph->flags = FT_NEXT_USHORT( p ); + subglyph->index = FT_NEXT_USHORT( p ); /* check space */ - byte_len -= 2; + count = 2; if ( subglyph->flags & ARGS_ARE_WORDS ) - byte_len -= 2; + count += 2; if ( subglyph->flags & WE_HAVE_A_SCALE ) - byte_len -= 2; + count += 2; else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) - byte_len -= 4; + count += 4; else if ( subglyph->flags & WE_HAVE_A_2X2 ) - byte_len -= 8; + count += 8; - if ( byte_len < 0 ) + if ( p + count > limit ) goto Invalid_Composite; /* read arguments */ if ( subglyph->flags & ARGS_ARE_WORDS ) { - subglyph->arg1 = FT_GET_SHORT(); - subglyph->arg2 = FT_GET_SHORT(); + subglyph->arg1 = FT_NEXT_SHORT( p ); + subglyph->arg2 = FT_NEXT_SHORT( p ); } else { - subglyph->arg1 = FT_GET_CHAR(); - subglyph->arg2 = FT_GET_CHAR(); + subglyph->arg1 = FT_NEXT_CHAR( p ); + subglyph->arg2 = FT_NEXT_CHAR( p ); } /* read transform */ @@ -498,20 +501,20 @@ if ( subglyph->flags & WE_HAVE_A_SCALE ) { - xx = (FT_Fixed)FT_GET_SHORT() << 2; + xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; yy = xx; } else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) { - xx = (FT_Fixed)FT_GET_SHORT() << 2; - yy = (FT_Fixed)FT_GET_SHORT() << 2; + xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; } else if ( subglyph->flags & WE_HAVE_A_2X2 ) { - xx = (FT_Fixed)FT_GET_SHORT() << 2; - yx = (FT_Fixed)FT_GET_SHORT() << 2; - xy = (FT_Fixed)FT_GET_SHORT() << 2; - yy = (FT_Fixed)FT_GET_SHORT() << 2; + xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + yx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + xy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; } subglyph->transform.xx = xx; @@ -525,20 +528,23 @@ gloader->current.num_subglyphs = num_subglyphs; -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER { + FT_Stream stream = loader->stream; + + /* we must undo the FT_FRAME_ENTER in order to point to the */ /* composite instructions, if we find some. */ /* we will process them later... */ /* */ loader->ins_pos = (FT_ULong)( FT_STREAM_POS() + - stream->cursor - stream->limit ); + p - limit ); } #endif - loader->byte_len = byte_len; + loader->cursor = p; Fail: return error; @@ -570,8 +576,10 @@ zone->n_contours = (FT_Short) ( load->outline.n_contours - start_contour ); zone->org = load->extra_points + start_point; zone->cur = load->outline.points + start_point; + zone->orus = load->extra_points2 + start_point; zone->tags = (FT_Byte*)load->outline.tags + start_point; zone->contours = (FT_UShort*)load->outline.contours + start_contour; + zone->first_point = (FT_UShort)start_point; } @@ -584,9 +592,6 @@ /* Hint the glyph using the zone prepared by the caller. Note that */ /* the zone is supposed to include four phantom points. */ /* */ -#define cur_to_org( n, zone ) \ - FT_ARRAY_COPY( (zone)->org, (zone)->cur, (n) ) - static FT_Error TT_Hint_Glyph( TT_Loader loader, FT_Bool is_composite ) @@ -594,14 +599,14 @@ TT_GlyphZone zone = &loader->zone; FT_Pos origin; -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER FT_UInt n_ins; #else FT_UNUSED( is_composite ); #endif -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER n_ins = loader->glyph->control_len; #endif @@ -610,10 +615,10 @@ if ( origin ) translate_array( zone->n_points, zone->cur, origin, 0 ); -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER /* save original point positioin in org */ if ( n_ins > 0 ) - cur_to_org( zone->n_points, zone ); + FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points ); #endif /* round pp2 and pp4 */ @@ -622,7 +627,7 @@ zone->cur[zone->n_points - 1].y = FT_PIX_ROUND( zone->cur[zone->n_points - 1].y ); -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER if ( n_ins > 0 ) { @@ -638,8 +643,8 @@ loader->exec->is_composite = is_composite; loader->exec->pts = *zone; - debug = !( loader->load_flags & FT_LOAD_NO_SCALE ) && - ( (TT_Size)loader->size )->debug; + debug = FT_BOOL( !( loader->load_flags & FT_LOAD_NO_SCALE ) && + ((TT_Size)loader->size)->debug ); error = TT_Run_Context( loader->exec, debug ); if ( error && loader->exec->pedantic_hinting ) @@ -725,6 +730,14 @@ #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + if ( IS_HINTED( loader->load_flags ) ) + { + tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 ); + + FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur, + loader->zone.n_points + 4 ); + } + /* scale the glyph */ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { @@ -748,7 +761,6 @@ if ( IS_HINTED( loader->load_flags ) ) { - tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 ); loader->zone.n_points += 4; error = TT_Hint_Glyph( loader, 0 ); @@ -932,6 +944,7 @@ { FT_Error error; FT_Outline* outline; + FT_UInt i; outline = &loader->gloader->base.outline; @@ -953,7 +966,7 @@ outline->tags[outline->n_points + 2] = 0; outline->tags[outline->n_points + 3] = 0; -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER { FT_Stream stream = loader->stream; @@ -989,6 +1002,13 @@ tt_prepare_zone( &loader->zone, &loader->gloader->base, start_point, start_contour ); + + /* Some points are likely touched during execution of */ + /* instructions on components. So let's untouch them. */ + for ( i = start_point; i < loader->zone.n_points; i++ ) + loader->zone.tags[i] &= ~( FT_CURVE_TAG_TOUCH_X | + FT_CURVE_TAG_TOUCH_Y ); + loader->zone.n_points += 4; return TT_Hint_Glyph( loader, 1 ); @@ -1415,7 +1435,7 @@ loader->ins_pos = ins_pos; if ( IS_HINTED( loader->load_flags ) && -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER subglyph->flags & WE_HAVE_INSTR && @@ -1695,21 +1715,47 @@ FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) ); -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER /* load execution context */ + if ( IS_HINTED( load_flags ) ) { TT_ExecContext exec; + FT_Bool grayscale; + if ( !size->cvt_ready ) + { + FT_Error error = tt_size_ready_bytecode( size ); + if ( error ) + return error; + } + /* query new execution context */ exec = size->debug ? size->context : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; if ( !exec ) return TT_Err_Could_Not_Find_Context; + grayscale = + FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_RENDER_MODE_MONO ); + TT_Load_Context( exec, face, size ); + /* a change from mono to grayscale rendering (and vice versa) */ + /* requires a re-execution of the CVT program */ + if ( grayscale != exec->grayscale ) + { + FT_UInt i; + + + exec->grayscale = grayscale; + + for ( i = 0; i < size->cvt_size; i++ ) + size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); + tt_size_run_prep( size ); + } + /* see if the cvt program has disabled hinting */ if ( exec->GS.instruct_control & 1 ) load_flags |= FT_LOAD_NO_HINTING; @@ -1719,14 +1765,11 @@ exec->GS = tt_default_graphics_state; exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); - exec->grayscale = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_LOAD_TARGET_MONO ); - loader->exec = exec; loader->instructions = exec->glyphIns; } -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#endif /* TT_USE_BYTECODE_INTERPRETER */ /* seek to the beginning of the glyph table. For Type 42 fonts */ /* the table might be accessed from a Postscript stream or something */ diff --git a/src/libs/freetype2/truetype/ttgload.h b/src/libs/freetype2/truetype/ttgload.h index 665c224878..b261e97dee 100644 --- a/src/libs/freetype2/truetype/ttgload.h +++ b/src/libs/freetype2/truetype/ttgload.h @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,7 +23,7 @@ #include <ft2build.h> #include "ttobjs.h" -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER #include "ttinterp.h" #endif diff --git a/src/libs/freetype2/truetype/ttgxvar.h b/src/libs/freetype2/truetype/ttgxvar.h index e86c7eeccb..706cb4d369 100644 --- a/src/libs/freetype2/truetype/ttgxvar.h +++ b/src/libs/freetype2/truetype/ttgxvar.h @@ -32,7 +32,7 @@ FT_BEGIN_HEADER /* <Struct> */ /* GX_AVarCorrespondenceRec */ /* */ - /* <Description> */ + /* <Description> */ /* A data structure representing `shortFracCorrespondence' in `avar' */ /* table according to the specifications from Apple. */ /* */ @@ -94,7 +94,7 @@ FT_BEGIN_HEADER FT_UInt gv_glyphcnt; FT_ULong* glyphoffsets; - + } GX_BlendRec; diff --git a/src/libs/freetype2/truetype/ttinterp.c b/src/libs/freetype2/truetype/ttinterp.c index bb08a5ae22..640001b696 100644 --- a/src/libs/freetype2/truetype/ttinterp.c +++ b/src/libs/freetype2/truetype/ttinterp.c @@ -4,7 +4,7 @@ /* */ /* TrueType bytecode interpreter (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -16,6 +16,11 @@ /***************************************************************************/ + /* define FIX_BYTECODE to implement the bytecode interpreter fixes */ + /* needed to match Windows behaviour more accurately */ +/* #define FIX_BYTECODE */ + + #include <ft2build.h> #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_CALC_H @@ -27,7 +32,7 @@ #include "tterrors.h" -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER #define TT_MULFIX FT_MulFix @@ -505,15 +510,16 @@ Update_Max( FT_Memory memory, FT_ULong* size, FT_Long multiplier, - void** buff, + void* _pbuff, FT_ULong new_max ) { FT_Error error; + void** pbuff = (void**)_pbuff; if ( *size < new_max ) { - if ( FT_REALLOC( *buff, *size * multiplier, new_max * multiplier ) ) + if ( FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) ) return error; *size = new_max; } @@ -594,7 +600,7 @@ error = Update_Max( exec->memory, &tmp, sizeof ( FT_F26Dot6 ), - (void**)&exec->stack, + (void*)&exec->stack, maxp->maxStackElements + 32 ); exec->stackSize = (FT_UInt)tmp; if ( error ) @@ -604,7 +610,7 @@ error = Update_Max( exec->memory, &tmp, sizeof ( FT_Byte ), - (void**)&exec->glyphIns, + (void*)&exec->glyphIns, maxp->maxSizeOfInstructions ); exec->glyphSize = (FT_UShort)tmp; if ( error ) @@ -4781,7 +4787,35 @@ if ( CUR.opcode & 1 ) D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); else + { + +#ifdef FIX_BYTECODE + + FT_Vector vec1, vec2; + + + if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) + FT_ARRAY_COPY( CUR.twilight.orus, + CUR.twilight.org, + CUR.twilight.n_points ); + + /* get scaled orus coordinates */ + vec1 = CUR.zp0.orus[L]; + vec2 = CUR.zp1.orus[K]; + + vec1.x = TT_MULFIX( vec1.x, CUR.metrics.x_scale ); + vec1.y = TT_MULFIX( vec1.y, CUR.metrics.y_scale ); + vec2.x = TT_MULFIX( vec2.x, CUR.metrics.x_scale ); + vec2.y = TT_MULFIX( vec2.y, CUR.metrics.y_scale ); + + D = CUR_Func_dualproj( &vec1, &vec2 ); + +#else + D = CUR_Func_dualproj( CUR.zp0.org + L, CUR.zp1.org + K ); + +#endif /* FIX_BYTECODE */ + } } args[0] = D; @@ -5215,6 +5249,7 @@ { if ( CUR.pedantic_hinting ) CUR.error = TT_Err_Invalid_Reference; + *refp = 0; return FAILURE; } @@ -5379,9 +5414,11 @@ if ( contour == 0 ) first_point = 0; else - first_point = (FT_UShort)(CUR.pts.contours[contour - 1] + 1); + first_point = (FT_UShort)( CUR.pts.contours[contour - 1] + 1 - + CUR.pts.first_point ); - last_point = CUR.pts.contours[contour]; + last_point = (FT_UShort)( CUR.pts.contours[contour] - + CUR.pts.first_point ); /* XXX: this is probably wrong... at least it prevents memory */ /* corruption when zp2 is the twilight zone */ @@ -5694,10 +5731,37 @@ /* XXX: Is there some undocumented feature while in the */ /* twilight zone? */ +#ifdef FIX_BYTECODE + + { + FT_Vector vec1, vec2; + + + if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) + FT_ARRAY_COPY( CUR.twilight.orus, + CUR.twilight.org, + CUR.twilight.n_points ); + + vec1 = CUR.zp1.orus[point]; + vec2 = CUR.zp0.orus[CUR.GS.rp0]; + + vec1.x = TT_MULFIX( vec1.x, CUR.metrics.x_scale ); + vec1.y = TT_MULFIX( vec1.y, CUR.metrics.y_scale ); + + vec2.x = TT_MULFIX( vec2.x, CUR.metrics.x_scale ); + vec2.y = TT_MULFIX( vec2.y, CUR.metrics.y_scale ); + + org_dist = CUR_Func_dualproj( &vec1, &vec2 ); + } + +#else + org_dist = CUR_Func_dualproj( CUR.zp1.org + point, CUR.zp0.org + CUR.GS.rp0 ); - /* single width cutin test */ +#endif /* FIX_BYTECODE */ + + /* single width cut-in test */ if ( FT_ABS( org_dist - CUR.GS.single_width_value ) < CUR.GS.single_width_cutin ) @@ -6052,7 +6116,7 @@ { FT_F26Dot6 org_a, org_b, org_x, cur_a, cur_b, cur_x, - distance; + distance = 0; FT_UShort point; FT_UNUSED_ARG; @@ -6064,6 +6128,25 @@ return; } +#ifdef FIX_BYTECODE + + /* We need to deal in a special way with the twilight zone. The easiest + * solution is simply to copy the coordinates from `org' to `orus' + * whenever someone tries to perform intersections based on some of its + * points. + * + * Otherwise, by definition, value of CUR.twilight[n] is (0,0), + * whatever value of `n'. + */ + if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0 ) + { + FT_ARRAY_COPY( CUR.twilight.orus, + CUR.twilight.org, + CUR.twilight.n_points ); + } + +#endif /* FIX_BYTECODE */ + /* XXX: There are some glyphs in some braindead but popular */ /* fonts out there (e.g. [aeu]grave in monotype.ttf) */ /* calling IP[] with bad values of rp[12]. */ @@ -6077,9 +6160,29 @@ } else { + +#ifdef FIX_BYTECODE + + FT_Vector vec1, vec2; + + + vec1 = CUR.zp0.orus[CUR.GS.rp1]; + vec2 = CUR.zp1.orus[CUR.GS.rp2]; + vec1.x = TT_MULFIX( vec1.x, CUR.metrics.x_scale ); + vec1.y = TT_MULFIX( vec1.y, CUR.metrics.y_scale ); + vec2.x = TT_MULFIX( vec2.x, CUR.metrics.x_scale ); + vec2.y = TT_MULFIX( vec2.y, CUR.metrics.y_scale ); + + org_a = CUR_Func_dualproj( &vec1, NULL_Vector ); + org_b = CUR_Func_dualproj( &vec2, NULL_Vector ); + +#else + org_a = CUR_Func_dualproj( CUR.zp0.org + CUR.GS.rp1, NULL_Vector ); org_b = CUR_Func_dualproj( CUR.zp1.org + CUR.GS.rp2, NULL_Vector ); +#endif /* FIX_BYTECODE */ + cur_a = CUR_Func_project( CUR.zp0.cur + CUR.GS.rp1, NULL_Vector ); cur_b = CUR_Func_project( CUR.zp1.cur + CUR.GS.rp2, NULL_Vector ); } @@ -6099,7 +6202,24 @@ } else { + +#ifdef FIX_BYTECODE + + FT_Vector vec; + + + vec = CUR.zp2.orus[point]; + vec.x = TT_MULFIX( vec.x, CUR.metrics.x_scale ); + vec.y = TT_MULFIX( vec.y, CUR.metrics.y_scale ); + + org_x = CUR_Func_dualproj( &vec, NULL_Vector ); + +#else + org_x = CUR_Func_dualproj( CUR.zp2.org + point, NULL_Vector ); + +#endif /* FIX_BYTECODE */ + cur_x = CUR_Func_project ( CUR.zp2.cur + point, NULL_Vector ); if ( ( org_a <= org_b && org_x <= org_a ) || @@ -6112,7 +6232,7 @@ distance = ( cur_b - org_b ) + ( org_x - cur_x ); - else + else if ( org_b != org_a ) /* note: it seems that rounding this value isn't a good */ /* idea (cf. width of capital `S' in Times) */ @@ -6166,109 +6286,122 @@ /* Local variables for Ins_IUP: */ - struct LOC_Ins_IUP + typedef struct { FT_Vector* orgs; /* original and current coordinate */ FT_Vector* curs; /* arrays */ - }; + FT_Vector* orus; + + } IUP_WorkerRec, *IUP_Worker; static void - Shift( FT_UInt p1, - FT_UInt p2, - FT_UInt p, - struct LOC_Ins_IUP* LINK ) + _iup_worker_shift( IUP_Worker worker, + FT_UInt p1, + FT_UInt p2, + FT_UInt p ) { FT_UInt i; - FT_F26Dot6 x; + FT_F26Dot6 dx; - x = LINK->curs[p].x - LINK->orgs[p].x; + dx = worker->curs[p].x - worker->orgs[p].x; + if ( dx != 0 ) + { + for ( i = p1; i < p; i++ ) + worker->curs[i].x += dx; - for ( i = p1; i < p; i++ ) - LINK->curs[i].x += x; - - for ( i = p + 1; i <= p2; i++ ) - LINK->curs[i].x += x; + for ( i = p + 1; i <= p2; i++ ) + worker->curs[i].x += dx; + } } static void - Interp( FT_UInt p1, - FT_UInt p2, - FT_UInt ref1, - FT_UInt ref2, - struct LOC_Ins_IUP* LINK ) + _iup_worker_interpolate( IUP_Worker worker, + FT_UInt p1, + FT_UInt p2, + FT_UInt ref1, + FT_UInt ref2 ) { FT_UInt i; - FT_F26Dot6 x, x1, x2, d1, d2; + FT_F26Dot6 orus1, orus2, org1, org2, delta1, delta2; if ( p1 > p2 ) return; - x1 = LINK->orgs[ref1].x; - d1 = LINK->curs[ref1].x - LINK->orgs[ref1].x; - x2 = LINK->orgs[ref2].x; - d2 = LINK->curs[ref2].x - LINK->orgs[ref2].x; + orus1 = worker->orus[ref1].x; + orus2 = worker->orus[ref2].x; - if ( x1 == x2 ) + if ( orus1 > orus2 ) { - for ( i = p1; i <= p2; i++ ) - { - x = LINK->orgs[i].x; + FT_F26Dot6 tmp_o; + FT_UInt tmp_r; - if ( x <= x1 ) - x += d1; - else - x += d2; - LINK->curs[i].x = x; - } - return; + tmp_o = orus1; + orus1 = orus2; + orus2 = tmp_o; + + tmp_r = ref1; + ref1 = ref2; + ref2 = tmp_r; } - if ( x1 < x2 ) + org1 = worker->orgs[ref1].x; + org2 = worker->orgs[ref2].x; + delta1 = worker->curs[ref1].x - org1; + delta2 = worker->curs[ref2].x - org2; + + if ( orus1 == orus2 ) { + /* simple shift of untouched points */ for ( i = p1; i <= p2; i++ ) { - x = LINK->orgs[i].x; + FT_F26Dot6 x = worker->orgs[i].x; + + + if ( x <= org1 ) + x += delta1; + else + x += delta2; + + worker->curs[i].x = x; + } + } + else + { + FT_Fixed scale = 0; + FT_Bool scale_valid = 0; + + + /* interpolation */ + for ( i = p1; i <= p2; i++ ) + { + FT_F26Dot6 x = worker->orgs[i].x; + + + if ( x <= org1 ) + x += delta1; + + else if ( x >= org2 ) + x += delta2; - if ( x <= x1 ) - x += d1; else { - if ( x >= x2 ) - x += d2; - else - x = LINK->curs[ref1].x + - TT_MULDIV( x - x1, - LINK->curs[ref2].x - LINK->curs[ref1].x, - x2 - x1 ); + if ( !scale_valid ) + { + scale_valid = 1; + scale = TT_MULDIV( org2 + delta2 - ( org1 + delta1 ), + 0x10000, orus2 - orus1 ); + } + + x = ( org1 + delta1 ) + + TT_MULFIX( worker->orus[i].x - orus1, scale ); } - LINK->curs[i].x = x; + worker->curs[i].x = x; } - return; - } - - /* x2 < x1 */ - - for ( i = p1; i <= p2; i++ ) - { - x = LINK->orgs[i].x; - if ( x <= x2 ) - x += d2; - else - { - if ( x >= x1 ) - x += d1; - else - x = LINK->curs[ref1].x + - TT_MULDIV( x - x1, - LINK->curs[ref2].x - LINK->curs[ref1].x, - x2 - x1 ); - } - LINK->curs[i].x = x; } } @@ -6282,8 +6415,8 @@ static void Ins_IUP( INS_ARG ) { - struct LOC_Ins_IUP V; - FT_Byte mask; + IUP_WorkerRec V; + FT_Byte mask; FT_UInt first_point; /* first point of contour */ FT_UInt end_point; /* end point (last+1) of contour */ @@ -6302,12 +6435,14 @@ mask = FT_CURVE_TAG_TOUCH_X; V.orgs = CUR.pts.org; V.curs = CUR.pts.cur; + V.orus = CUR.pts.orus; } else { mask = FT_CURVE_TAG_TOUCH_Y; V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 ); V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 ); + V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 ); } contour = 0; @@ -6315,7 +6450,7 @@ do { - end_point = CUR.pts.contours[contour]; + end_point = CUR.pts.contours[contour] - CUR.pts.first_point; first_point = point; while ( point <= end_point && (CUR.pts.tags[point] & mask) == 0 ) @@ -6333,11 +6468,11 @@ if ( ( CUR.pts.tags[point] & mask ) != 0 ) { if ( point > 0 ) - Interp( cur_touched + 1, - point - 1, - cur_touched, - point, - &V ); + _iup_worker_interpolate( &V, + cur_touched + 1, + point - 1, + cur_touched, + point ); cur_touched = point; } @@ -6345,21 +6480,21 @@ } if ( cur_touched == first_touched ) - Shift( first_point, end_point, cur_touched, &V ); + _iup_worker_shift( &V, first_point, end_point, cur_touched ); else { - Interp( (FT_UShort)( cur_touched + 1 ), - end_point, - cur_touched, - first_touched, - &V ); + _iup_worker_interpolate( &V, + (FT_UShort)( cur_touched + 1 ), + end_point, + cur_touched, + first_touched ); if ( first_touched > 0 ) - Interp( first_point, - first_touched - 1, - cur_touched, - first_touched, - &V ); + _iup_worker_interpolate( &V, + first_point, + first_touched - 1, + cur_touched, + first_touched ); } } contour++; @@ -6381,11 +6516,14 @@ FT_ULong C; FT_Long B; + #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING /* Delta hinting is covered by US Patent 5159668. */ if ( CUR.face->unpatented_hinting ) - { - FT_Long n = args[0] * 2; + { + FT_Long n = args[0] * 2; + + if ( CUR.args < n ) { CUR.error = TT_Err_Too_Few_Arguments; @@ -6586,7 +6724,7 @@ /* Are we hinting for grayscale? */ if ( ( args[0] & 32 ) != 0 && CUR.grayscale ) - K |= (1 << 12); + K |= 1 << 12; args[0] = K; } @@ -7684,7 +7822,7 @@ } -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#endif /* TT_USE_BYTECODE_INTERPRETER */ /* END */ diff --git a/src/libs/freetype2/truetype/ttobjs.c b/src/libs/freetype2/truetype/ttobjs.c index 89ef75d918..9f8683a915 100644 --- a/src/libs/freetype2/truetype/ttobjs.c +++ b/src/libs/freetype2/truetype/ttobjs.c @@ -4,7 +4,7 @@ /* */ /* Objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -29,7 +29,7 @@ #include "tterrors.h" -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER #include "ttinterp.h" #endif @@ -51,7 +51,7 @@ #define FT_COMPONENT trace_ttobjs -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER /*************************************************************************/ /* */ @@ -83,6 +83,7 @@ FT_FREE( zone->tags ); FT_FREE( zone->cur ); FT_FREE( zone->org ); + FT_FREE( zone->orus ); zone->max_points = zone->n_points = 0; zone->max_contours = zone->n_contours = 0; @@ -126,6 +127,7 @@ if ( FT_NEW_ARRAY( zone->org, maxPoints ) || FT_NEW_ARRAY( zone->cur, maxPoints ) || + FT_NEW_ARRAY( zone->orus, maxPoints ) || FT_NEW_ARRAY( zone->tags, maxPoints ) || FT_NEW_ARRAY( zone->contours, maxContours ) ) { @@ -139,7 +141,7 @@ return error; } -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#endif /* TT_USE_BYTECODE_INTERPRETER */ /*************************************************************************/ @@ -203,7 +205,7 @@ goto Bad_Format; } -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER face->root.face_flags |= FT_FACE_FLAG_HINTER; #endif @@ -244,22 +246,58 @@ } -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - - /* Determine whether unpatented hinting is to be used for this face. */ - face->unpatented_hinting = FT_BOOL - ( library->debug_hooks[ FT_DEBUG_HOOK_UNPATENTED_HINTING ] != NULL ); +#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ + !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) { - int i; + FT_Bool unpatented_hinting; + int i; + /* Determine whether unpatented hinting is to be used for this face. */ + unpatented_hinting = FT_BOOL + ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL ); + for ( i = 0; i < num_params && !face->unpatented_hinting; i++ ) if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING ) - face->unpatented_hinting = TRUE; + unpatented_hinting = TRUE; + + /* Compare the face with a list of well-known `tricky' fonts. */ + /* This list shall be expanded as we find more of them. */ + if ( !unpatented_hinting ) + { + static const char* const trick_names[] = + { + "DFKaiSho-SB", /* dfkaisb.ttf */ + "DFKai-SB", /* kaiu.ttf */ + "HuaTianSongTi?", /* htst3.ttf */ + "MingLiU", /* mingliu.ttf & mingliu.ttc */ + "PMingLiU", /* mingliu.ttc */ + "MingLi43", /* mingli.ttf */ + NULL + }; + int nn; + + + /* Note that we only check the face name at the moment; it might */ + /* be worth to do more checks for a few special cases. */ + for ( nn = 0; trick_names[nn] != NULL; nn++ ) + { + if ( ttface->family_name && + ft_strcmp( ttface->family_name, trick_names[nn] ) == 0 ) + { + unpatented_hinting = 1; + break; + } + } + } + + ttface->internal->ignore_unpatented_hinter = + FT_BOOL( !unpatented_hinting ); } -#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */ +#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING && + !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ /* initialize standard glyph loading routines */ TT_Init_Glyph_Loading( face ); @@ -329,7 +367,7 @@ /* */ /*************************************************************************/ -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER /*************************************************************************/ /* */ @@ -479,32 +517,60 @@ return error; } -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#endif /* TT_USE_BYTECODE_INTERPRETER */ - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_size_init */ - /* */ - /* <Description> */ - /* Initialize a new TrueType size object. */ - /* */ - /* <InOut> */ - /* size :: A handle to the size object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_size_init( FT_Size ttsize ) /* TT_Size */ +#ifdef TT_USE_BYTECODE_INTERPRETER + + static void + tt_size_done_bytecode( FT_Size ftsize ) { - TT_Size size = (TT_Size)ttsize; - FT_Error error = TT_Err_Ok; + TT_Size size = (TT_Size)ftsize; + TT_Face face = (TT_Face)ftsize->face; + FT_Memory memory = face->root.memory; -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - TT_Face face = (TT_Face)size->root.face; + if ( size->debug ) + { + /* the debug context must be deleted by the debugger itself */ + size->context = NULL; + size->debug = FALSE; + } + + FT_FREE( size->cvt ); + size->cvt_size = 0; + + /* free storage area */ + FT_FREE( size->storage ); + size->storage_size = 0; + + /* twilight zone */ + tt_glyphzone_done( &size->twilight ); + + FT_FREE( size->function_defs ); + FT_FREE( size->instruction_defs ); + + size->num_function_defs = 0; + size->max_function_defs = 0; + size->num_instruction_defs = 0; + size->max_instruction_defs = 0; + + size->max_func = 0; + size->max_ins = 0; + + size->bytecode_ready = 0; + size->cvt_ready = 0; + } + + + /* Initialize bytecode-related fields in the size object. */ + /* We do this only if bytecode interpretation is really needed. */ + static FT_Error + tt_size_init_bytecode( FT_Size ftsize ) + { + FT_Error error; + TT_Size size = (TT_Size)ftsize; + TT_Face face = (TT_Face)ftsize->face; FT_Memory memory = face->root.memory; FT_Int i; @@ -512,6 +578,9 @@ TT_MaxProfile* maxp = &face->max_profile; + size->bytecode_ready = 1; + size->cvt_ready = 0; + size->max_function_defs = maxp->maxFunctionDefs; size->max_instruction_defs = maxp->maxInstructionDefs; @@ -546,11 +615,7 @@ FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) || FT_NEW_ARRAY( size->cvt, size->cvt_size ) || FT_NEW_ARRAY( size->storage, size->storage_size ) ) - { - tt_size_done( ttsize ); - - return error; - } + goto Exit; /* reserve twilight zone */ n_twilight = maxp->maxTwilightPoints; @@ -560,11 +625,7 @@ error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight ); if ( error ) - { - tt_size_done( ttsize ); - - return error; - } + goto Exit; size->twilight.n_points = n_twilight; @@ -584,10 +645,96 @@ /* Fine, now run the font program! */ error = tt_size_run_fpgm( size ); + Exit: if ( error ) - tt_size_done( ttsize ); + tt_size_done_bytecode( ftsize ); -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + tt_size_ready_bytecode( TT_Size size ) + { + FT_Error error = TT_Err_Ok; + + + if ( !size->bytecode_ready ) + { + error = tt_size_init_bytecode( (FT_Size)size ); + if ( error ) + goto Exit; + } + + /* rescale CVT when needed */ + if ( !size->cvt_ready ) + { + FT_UInt i; + TT_Face face = (TT_Face) size->root.face; + + + /* Scale the cvt values to the new ppem. */ + /* We use by default the y ppem to scale the CVT. */ + for ( i = 0; i < size->cvt_size; i++ ) + size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); + + /* all twilight points are originally zero */ + for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ ) + { + size->twilight.org[i].x = 0; + size->twilight.org[i].y = 0; + size->twilight.cur[i].x = 0; + size->twilight.cur[i].y = 0; + } + + /* clear storage area */ + for ( i = 0; i < (FT_UInt)size->storage_size; i++ ) + size->storage[i] = 0; + + size->GS = tt_default_graphics_state; + + error = tt_size_run_prep( size ); + } + Exit: + return error; + } + +#else /* !TT_USE_BYTECODE_INTERPRETER */ + + FT_LOCAL_DEF( FT_Error ) + tt_size_ready_bytecode( TT_Size size ) + { + FT_UNUSED( ftsize ); + return 0; + } + +#endif /* !TT_USE_BYTECODE_INTERPRETER */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_size_init */ + /* */ + /* <Description> */ + /* Initialize a new TrueType size object. */ + /* */ + /* <InOut> */ + /* size :: A handle to the size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_size_init( FT_Size ttsize ) /* TT_Size */ + { + TT_Size size = (TT_Size)ttsize; + FT_Error error = TT_Err_Ok; + +#ifdef TT_USE_BYTECODE_INTERPRETER + size->bytecode_ready = 0; + size->cvt_ready = 0; +#endif size->ttmetrics.valid = FALSE; size->strike_index = 0xFFFFFFFFUL; @@ -610,41 +757,12 @@ FT_LOCAL_DEF( void ) tt_size_done( FT_Size ttsize ) /* TT_Size */ { - TT_Size size = (TT_Size)ttsize; - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - FT_Memory memory = size->root.face->memory; + TT_Size size = (TT_Size)ttsize; - if ( size->debug ) - { - /* the debug context must be deleted by the debugger itself */ - size->context = NULL; - size->debug = FALSE; - } - - FT_FREE( size->cvt ); - size->cvt_size = 0; - - /* free storage area */ - FT_FREE( size->storage ); - size->storage_size = 0; - - /* twilight zone */ - tt_glyphzone_done( &size->twilight ); - - FT_FREE( size->function_defs ); - FT_FREE( size->instruction_defs ); - - size->num_function_defs = 0; - size->max_function_defs = 0; - size->num_instruction_defs = 0; - size->max_instruction_defs = 0; - - size->max_func = 0; - size->max_ins = 0; - +#ifdef TT_USE_BYTECODE_INTERPRETER + if ( size->bytecode_ready ) + tt_size_done_bytecode( ttsize ); #endif size->ttmetrics.valid = FALSE; @@ -725,37 +843,9 @@ size->ttmetrics.y_ratio = 0x10000L; } - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - { - FT_UInt i; - - - /* Scale the cvt values to the new ppem. */ - /* We use by default the y ppem to scale the CVT. */ - for ( i = 0; i < size->cvt_size; i++ ) - size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); - - /* All twilight points are originally zero */ - for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ ) - { - size->twilight.org[i].x = 0; - size->twilight.org[i].y = 0; - size->twilight.cur[i].x = 0; - size->twilight.cur[i].y = 0; - } - - /* clear storage area */ - for ( i = 0; i < (FT_UInt)size->storage_size; i++ ) - size->storage[i] = 0; - - size->GS = tt_default_graphics_state; - - error = tt_size_run_prep( size ); - } - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#ifdef TT_USE_BYTECODE_INTERPRETER + size->cvt_ready = 0; +#endif /* TT_USE_BYTECODE_INTERPRETER */ if ( !error ) size->ttmetrics.valid = TRUE; @@ -782,7 +872,7 @@ tt_driver_init( FT_Module ttdriver ) /* TT_Driver */ { -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER TT_Driver driver = (TT_Driver)ttdriver; @@ -814,7 +904,7 @@ FT_LOCAL_DEF( void ) tt_driver_done( FT_Module ttdriver ) /* TT_Driver */ { -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER TT_Driver driver = (TT_Driver)ttdriver; diff --git a/src/libs/freetype2/truetype/ttobjs.h b/src/libs/freetype2/truetype/ttobjs.h index b42b73594b..652ead33e9 100644 --- a/src/libs/freetype2/truetype/ttobjs.h +++ b/src/libs/freetype2/truetype/ttobjs.h @@ -4,7 +4,7 @@ /* */ /* Objects manager (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -109,7 +109,7 @@ FT_BEGIN_HEADER } TT_GraphicsState; -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER FT_LOCAL( void ) tt_glyphzone_done( TT_GlyphZone zone ); @@ -120,7 +120,7 @@ FT_BEGIN_HEADER FT_Short maxContours, TT_GlyphZone zone ); -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#endif /* TT_USE_BYTECODE_INTERPRETER */ @@ -324,7 +324,7 @@ FT_BEGIN_HEADER FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */ -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER FT_UInt num_function_defs; /* number of function definitions */ FT_UInt max_function_defs; @@ -358,7 +358,10 @@ FT_BEGIN_HEADER FT_Bool debug; TT_ExecContext context; -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + FT_Bool bytecode_ready; + FT_Bool cvt_ready; + +#endif /* TT_USE_BYTECODE_INTERPRETER */ } TT_SizeRec; @@ -412,7 +415,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) tt_size_done( FT_Size ttsize ); /* TT_Size */ -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER FT_LOCAL( FT_Error ) tt_size_run_fpgm( TT_Size size ); @@ -420,11 +423,14 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) tt_size_run_prep( TT_Size size ); -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#endif /* TT_USE_BYTECODE_INTERPRETER */ FT_LOCAL( FT_Error ) tt_size_reset( TT_Size size ); + FT_LOCAL( FT_Error ) + tt_size_ready_bytecode( TT_Size size ); + /*************************************************************************/ /* */ diff --git a/src/libs/freetype2/truetype/ttpload.c b/src/libs/freetype2/truetype/ttpload.c index 36e5a66069..9d3381bf05 100644 --- a/src/libs/freetype2/truetype/ttpload.c +++ b/src/libs/freetype2/truetype/ttpload.c @@ -4,7 +4,7 @@ /* */ /* TrueType-specific tables loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -58,7 +58,6 @@ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ -#ifdef FT_OPTIMIZE_MEMORY FT_LOCAL_DEF( FT_Error ) tt_face_load_loca( TT_Face face, @@ -183,135 +182,6 @@ } -#else /* !FT_OPTIMIZE_MEMORY */ - - - FT_LOCAL_DEF( FT_Error ) - tt_face_load_loca( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_Short LongOffsets; - FT_ULong table_len; - - - /* we need the size of the `glyf' table for malformed `loca' tables */ - error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len ); - if ( error ) - goto Exit; - - FT_TRACE2(( "Locations " )); - LongOffsets = face->header.Index_To_Loc_Format; - - error = face->goto_table( face, TTAG_loca, stream, &table_len ); - if ( error ) - { - error = TT_Err_Locations_Missing; - goto Exit; - } - - if ( LongOffsets != 0 ) - { - face->num_locations = (FT_UShort)( table_len >> 2 ); - - FT_TRACE2(( "(32bit offsets): %12d ", face->num_locations )); - - if ( FT_NEW_ARRAY( face->glyph_locations, face->num_locations ) ) - goto Exit; - - if ( FT_FRAME_ENTER( face->num_locations * 4L ) ) - goto Exit; - - { - FT_Long* loc = face->glyph_locations; - FT_Long* limit = loc + face->num_locations; - - - for ( ; loc < limit; loc++ ) - *loc = FT_GET_LONG(); - } - - FT_FRAME_EXIT(); - } - else - { - face->num_locations = (FT_UShort)( table_len >> 1 ); - - FT_TRACE2(( "(16bit offsets): %12d ", face->num_locations )); - - if ( FT_NEW_ARRAY( face->glyph_locations, face->num_locations ) ) - goto Exit; - - if ( FT_FRAME_ENTER( face->num_locations * 2L ) ) - goto Exit; - - { - FT_Long* loc = face->glyph_locations; - FT_Long* limit = loc + face->num_locations; - - - for ( ; loc < limit; loc++ ) - *loc = (FT_Long)( (FT_ULong)FT_GET_USHORT() * 2 ); - } - - FT_FRAME_EXIT(); - } - - FT_TRACE2(( "loaded\n" )); - - Exit: - return error; - } - - - FT_LOCAL_DEF( FT_ULong ) - tt_face_get_location( TT_Face face, - FT_UInt gindex, - FT_UInt *asize ) - { - FT_ULong offset; - FT_UInt count; - - - offset = face->glyph_locations[gindex]; - count = 0; - - if ( gindex < (FT_UInt)face->num_locations - 1 ) - { - FT_ULong offset1 = face->glyph_locations[gindex + 1]; - - - /* It isn't mentioned explicitly that the `loca' table must be */ - /* ordered, but implicitly it refers to the length of an entry */ - /* as the difference between the current and the next position. */ - /* Anyway, there do exist (malformed) fonts which don't obey */ - /* this rule, so we are only able to provide an upper bound for */ - /* the size. */ - if ( offset1 >= offset ) - count = (FT_UInt)( offset1 - offset ); - else - count = (FT_UInt)( face->glyf_len - offset ); - } - - *asize = count; - return offset; - } - - - FT_LOCAL_DEF( void ) - tt_face_done_loca( TT_Face face ) - { - FT_Memory memory = face->root.memory; - - - FT_FREE( face->glyph_locations ); - face->num_locations = 0; - } - - -#endif /* !FT_OPTIMIZE_MEMORY */ - /*************************************************************************/ /* */ @@ -334,7 +204,7 @@ tt_face_load_cvt( TT_Face face, FT_Stream stream ) { -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER FT_Error error; FT_Memory memory = stream->memory; @@ -383,7 +253,7 @@ Exit: return error; -#else /* !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#else /* !TT_USE_BYTECODE_INTERPRETER */ FT_UNUSED( face ); FT_UNUSED( stream ); @@ -415,7 +285,7 @@ tt_face_load_fpgm( TT_Face face, FT_Stream stream ) { -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER FT_Error error; FT_ULong table_len; @@ -445,7 +315,7 @@ Exit: return error; -#else /* !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#else /* !TT_USE_BYTECODE_INTERPRETER */ FT_UNUSED( face ); FT_UNUSED( stream ); @@ -477,7 +347,7 @@ tt_face_load_prep( TT_Face face, FT_Stream stream ) { -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER FT_Error error; FT_ULong table_len; @@ -506,7 +376,7 @@ Exit: return error; -#else /* !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#else /* !TT_USE_BYTECODE_INTERPRETER */ FT_UNUSED( face ); FT_UNUSED( stream ); @@ -533,7 +403,6 @@ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ -#ifdef FT_OPTIMIZE_MEMORY FT_LOCAL_DEF( FT_Error ) tt_face_load_hdmx( TT_Face face, @@ -562,7 +431,23 @@ num_records = FT_NEXT_USHORT( p ); record_size = FT_NEXT_ULONG( p ); - if ( version != 0 || num_records > 255 || record_size > 0x40000 ) + /* The maximum number of bytes in an hdmx device record is the */ + /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */ + /* the reason why `record_size' is a long (which we read as */ + /* unsigned long for convenience). In practice, two bytes */ + /* sufficient to hold the size value. */ + /* */ + /* There are at least two fonts, HANNOM-A and HANNOM-B version */ + /* 2.0 (2005), which get this wrong: The upper two bytes of */ + /* the size value are set to 0xFF instead of 0x00. We catch */ + /* and fix this. */ + + if ( record_size >= 0xFFFF0000UL ) + record_size &= 0xFFFFU; + + /* The limit for `num_records' is a heuristic value. */ + + if ( version != 0 || num_records > 255 || record_size > 0x10001L ) { error = TT_Err_Invalid_File_Format; goto Fail; @@ -605,101 +490,6 @@ FT_FRAME_RELEASE( face->hdmx_table ); } -#else /* !FT_OPTIMIZE_MEMORY */ - - FT_LOCAL_DEF( FT_Error ) - tt_face_load_hdmx( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - TT_Hdmx hdmx = &face->hdmx; - FT_Short num_records; - FT_Long num_glyphs; - FT_Long record_size; - - - hdmx->version = 0; - hdmx->num_records = 0; - hdmx->records = 0; - - /* this table is optional */ - error = face->goto_table( face, TTAG_hdmx, stream, 0 ); - if ( error ) - return TT_Err_Ok; - - if ( FT_FRAME_ENTER( 8L ) ) - goto Exit; - - hdmx->version = FT_GET_USHORT(); - num_records = FT_GET_SHORT(); - record_size = FT_GET_LONG(); - - FT_FRAME_EXIT(); - - if ( record_size < 0 || num_records < 0 ) - return TT_Err_Invalid_File_Format; - - /* Only recognize format 0 */ - if ( hdmx->version != 0 ) - goto Exit; - - /* we can't use FT_QNEW_ARRAY here; otherwise tt_face_free_hdmx */ - /* could fail during deallocation */ - if ( FT_NEW_ARRAY( hdmx->records, num_records ) ) - goto Exit; - - hdmx->num_records = num_records; - num_glyphs = face->root.num_glyphs; - record_size -= num_glyphs + 2; - - { - TT_HdmxEntry cur = hdmx->records; - TT_HdmxEntry limit = cur + hdmx->num_records; - - - for ( ; cur < limit; cur++ ) - { - /* read record */ - if ( FT_READ_BYTE( cur->ppem ) || - FT_READ_BYTE( cur->max_width ) ) - goto Exit; - - if ( FT_QALLOC( cur->widths, num_glyphs ) || - FT_STREAM_READ( cur->widths, num_glyphs ) ) - goto Exit; - - /* skip padding bytes */ - if ( record_size > 0 && FT_STREAM_SKIP( record_size ) ) - goto Exit; - } - } - - Exit: - return error; - } - - - FT_LOCAL_DEF( void ) - tt_face_free_hdmx( TT_Face face ) - { - if ( face ) - { - FT_Int n; - FT_Memory memory = face->root.driver->root.memory; - - - for ( n = 0; n < face->hdmx.num_records; n++ ) - FT_FREE( face->hdmx.records[n].widths ); - - FT_FREE( face->hdmx.records ); - face->hdmx.num_records = 0; - } - } - -#endif /* !OPTIMIZE_MEMORY */ - /*************************************************************************/ /* */ @@ -711,8 +501,6 @@ FT_UInt ppem, FT_UInt gindex ) { -#ifdef FT_OPTIMIZE_MEMORY - FT_UInt nn; FT_Byte* result = NULL; FT_ULong record_size = face->hdmx_record_size; @@ -729,19 +517,6 @@ } return result; - -#else - - FT_UShort n; - - - for ( n = 0; n < face->hdmx.num_records; n++ ) - if ( face->hdmx.records[n].ppem == ppem ) - return &face->hdmx.records[n].widths[gindex]; - - return NULL; - -#endif } diff --git a/src/libs/freetype2/type1/t1afm.c b/src/libs/freetype2/type1/t1afm.c index 379b33067d..373848b9af 100644 --- a/src/libs/freetype2/type1/t1afm.c +++ b/src/libs/freetype2/type1/t1afm.c @@ -4,7 +4,7 @@ /* */ /* AFM support for Type 1 fonts (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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, */ @@ -73,7 +73,7 @@ #undef KERN_INDEX -#define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)g1 << 16 ) | g2 ) +#define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)(g1) << 16 ) | (g2) ) /* compare two kerning pairs */ @@ -233,14 +233,9 @@ T1_Font t1_font = &( (T1_Face)t1_face )->type1; - if ( FT_NEW( fi ) ) - return error; - - if ( FT_FRAME_ENTER( stream->size ) ) - { - FT_FREE( fi ); - return error; - } + if ( FT_NEW( fi ) || + FT_FRAME_ENTER( stream->size ) ) + goto Exit; fi->FontBBox = t1_font->font_bbox; fi->Ascender = t1_font->font_bbox.yMax; @@ -270,8 +265,9 @@ FT_Byte* start = stream->cursor; + /* MS Windows allows versions up to 0x3FF without complaining */ if ( stream->size > 6 && - start[0] == 0x00 && start[1] == 0x01 && + start[1] < 4 && FT_PEEK_ULONG_LE( start + 2 ) == stream->size ) error = T1_Read_PFM( t1_face, stream, fi ); } @@ -292,11 +288,16 @@ { t1_face->face_flags |= FT_FACE_FLAG_KERNING; ( (T1_Face)t1_face )->afm_data = fi; + fi = NULL; } } FT_FRAME_EXIT(); + Exit: + if ( fi != NULL ) + T1_Done_Metrics( memory, fi ); + return error; } diff --git a/src/libs/freetype2/type1/t1gload.c b/src/libs/freetype2/type1/t1gload.c index 28190001f5..e08a428974 100644 --- a/src/libs/freetype2/type1/t1gload.c +++ b/src/libs/freetype2/type1/t1gload.c @@ -155,6 +155,8 @@ PSAux_Service psaux = (PSAux_Service)face->psaux; + FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); + *max_advance = 0; /* initialize load decoder */ @@ -173,9 +175,12 @@ decoder.builder.metrics_only = 1; decoder.builder.load_points = 0; - decoder.num_subrs = type1->num_subrs; - decoder.subrs = type1->subrs; - decoder.subrs_len = type1->subrs_len; + decoder.num_subrs = type1->num_subrs; + decoder.subrs = type1->subrs; + decoder.subrs_len = type1->subrs_len; + + decoder.buildchar = face->buildchar; + decoder.len_buildchar = face->len_buildchar; *max_advance = 0; @@ -191,6 +196,8 @@ /* ignore the error if one occurred - skip to next glyph */ } + psaux->t1_decoder_funcs->done( &decoder ); + return T1_Err_Ok; } @@ -212,11 +219,20 @@ FT_Matrix font_matrix; FT_Vector font_offset; FT_Data glyph_data; + FT_Bool must_finish_decoder = FALSE; #ifdef FT_CONFIG_OPTION_INCREMENTAL FT_Bool glyph_data_loaded = 0; #endif + if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) + { + error = T1_Err_Invalid_Argument; + goto Exit; + } + + FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); + if ( load_flags & FT_LOAD_NO_RECURSE ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; @@ -243,12 +259,17 @@ if ( error ) goto Exit; + must_finish_decoder = TRUE; + decoder.builder.no_recurse = FT_BOOL( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); - decoder.num_subrs = type1->num_subrs; - decoder.subrs = type1->subrs; - decoder.subrs_len = type1->subrs_len; + decoder.num_subrs = type1->num_subrs; + decoder.subrs = type1->subrs; + decoder.subrs_len = type1->subrs_len; + + decoder.buildchar = face->buildchar; + decoder.len_buildchar = face->len_buildchar; /* now load the unscaled outline */ error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index, @@ -265,6 +286,8 @@ /* save new glyph tables */ decoder_funcs->done( &decoder ); + must_finish_decoder = FALSE; + /* now, set the metrics -- this is rather simple, as */ /* the left side bearing is the xMin, and the top side */ /* bearing the yMax */ @@ -310,11 +333,14 @@ #if 1 /* apply the font matrix, if any */ - FT_Outline_Transform( &glyph->root.outline, &font_matrix ); + if ( font_matrix.xx != 0x10000L || font_matrix.yy != font_matrix.xx || + font_matrix.xy != 0 || font_matrix.yx != 0 ) + FT_Outline_Transform( &glyph->root.outline, &font_matrix ); - FT_Outline_Translate( &glyph->root.outline, - font_offset.x, - font_offset.y ); + if ( font_offset.x || font_offset.y ) + FT_Outline_Translate( &glyph->root.outline, + font_offset.x, + font_offset.y ); advance.x = metrics->horiAdvance; advance.y = 0; @@ -386,6 +412,9 @@ } #endif + if ( must_finish_decoder ) + decoder_funcs->done( &decoder ); + return error; } diff --git a/src/libs/freetype2/type1/t1load.c b/src/libs/freetype2/type1/t1load.c index 219563a03b..93c9e01c73 100644 --- a/src/libs/freetype2/type1/t1load.c +++ b/src/libs/freetype2/type1/t1load.c @@ -4,7 +4,7 @@ /* */ /* Type 1 font loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 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,6 +107,8 @@ if ( FT_NEW( blend ) ) goto Exit; + blend->num_default_design_vector = 0; + face->blend = blend; } @@ -242,7 +244,7 @@ return axismap->design_points[j - 1] + FT_MulDiv( t, - axismap->design_points[j] - + axismap->design_points[j] - axismap->design_points[j - 1], 1L ); } @@ -353,8 +355,9 @@ blend->num_axis ); for ( i = 0; i < mmaster.num_axis; ++i ) - mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i], - axiscoords[i] ); + mmvar->axis[i].def = + FT_INT_TO_FIXED( mm_axis_unmap( &blend->design_map[i], + axiscoords[i] ) ); } *master = mmvar; @@ -732,7 +735,7 @@ FT_Memory memory = face->root.memory; - T1_ToTokenArray( parser, axis_tokens, + T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis ); if ( num_axis < 0 ) { @@ -877,6 +880,18 @@ } + /* e.g., /BuildCharArray [0 0 0 0 0 0 0 0] def */ + /* we're only interested in the number of array elements */ + static void + parse_buildchar( T1_Face face, + T1_Loader loader ) + { + face->len_buildchar = T1_ToFixedArray( &loader->parser, 0, NULL, 0 ); + + return; + } + + #endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ @@ -950,6 +965,26 @@ } break; + case T1_FIELD_LOCATION_LOADER: + dummy_object = loader; + objects = &dummy_object; + max_objects = 0; + break; + + case T1_FIELD_LOCATION_FACE: + dummy_object = face; + objects = &dummy_object; + max_objects = 0; + break; + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + case T1_FIELD_LOCATION_BLEND: + dummy_object = face->blend; + objects = &dummy_object; + max_objects = 0; + break; +#endif + default: dummy_object = &face->type1; objects = &dummy_object; @@ -969,12 +1004,13 @@ } - static int - is_space( FT_Byte c ) + static void + parse_private( T1_Face face, + T1_Loader loader ) { - return ( c == ' ' || c == '\t' || - c == '\r' || c == '\n' || c == '\f' || - c == '\0' ); + FT_UNUSED( face ); + + loader->keywords_encountered |= T1_PRIVATE; } @@ -1161,9 +1197,9 @@ /* we stop when we encounter a `def' or `]' */ if ( *cur == 'd' && cur + 3 < limit ) { - if ( cur[1] == 'e' && - cur[2] == 'f' && - is_space( cur[3] ) ) + if ( cur[1] == 'e' && + cur[2] == 'f' && + IS_PS_DELIM( cur[3] ) ) { FT_TRACE6(( "encoding end\n" )); cur += 3; @@ -1443,7 +1479,7 @@ break; /* we stop when we find a `def' or `end' keyword */ - if ( cur + 3 < limit && is_space( cur[3] ) ) + if ( cur + 3 < limit && IS_PS_DELIM( cur[3] ) ) { if ( cur[0] == 'd' && cur[1] == 'e' && @@ -1677,19 +1713,31 @@ #include "t1tokens.h" /* now add the special functions... */ - T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix ) - T1_FIELD_CALLBACK( "Encoding", parse_encoding ) - T1_FIELD_CALLBACK( "Subrs", parse_subrs ) - T1_FIELD_CALLBACK( "CharStrings", parse_charstrings ) + T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "Encoding", parse_encoding, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "Subrs", parse_subrs, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_CALLBACK( "CharStrings", parse_charstrings, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_CALLBACK( "Private", parse_private, + T1_FIELD_DICT_FONTDICT ) #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT - T1_FIELD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions ) - T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map ) - T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types ) - T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector ) + T1_FIELD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "BuildCharArray", parse_buildchar, + T1_FIELD_DICT_PRIVATE ) #endif - { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 } + { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } }; @@ -1701,8 +1749,7 @@ parse_dict( T1_Face face, T1_Loader loader, FT_Byte* base, - FT_Long size, - FT_Byte* keyword_flags ) + FT_Long size ) { T1_Parser parser = &loader->parser; FT_Byte *limit, *start_binary = NULL; @@ -1724,59 +1771,24 @@ cur = parser->root.cursor; - /* look for `FontDirectory' which causes problems for some fonts */ - if ( *cur == 'F' && cur + 25 < limit && - ft_strncmp( (char*)cur, "FontDirectory", 13 ) == 0 ) - { - FT_Byte* cur2; - - - /* skip the `FontDirectory' keyword */ - T1_Skip_PS_Token( parser ); - T1_Skip_Spaces ( parser ); - cur = cur2 = parser->root.cursor; - - /* look up the `known' keyword */ - while ( cur < limit ) - { - if ( *cur == 'k' && cur + 5 < limit && - ft_strncmp( (char*)cur, "known", 5 ) == 0 ) - break; - - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - goto Exit; - T1_Skip_Spaces( parser ); - cur = parser->root.cursor; - } - - if ( cur < limit ) - { - T1_TokenRec token; - - - /* skip the `known' keyword and the token following it */ - T1_Skip_PS_Token( parser ); - T1_ToToken( parser, &token ); - - /* if the last token was an array, skip it! */ - if ( token.type == T1_TOKEN_TYPE_ARRAY ) - cur2 = parser->root.cursor; - } - parser->root.cursor = cur2; - have_integer = 0; - } - /* look for `eexec' */ - else if ( *cur == 'e' && cur + 5 < limit && - ft_strncmp( (char*)cur, "eexec", 5 ) == 0 ) + if ( IS_PS_TOKEN( cur, limit, "eexec" ) ) break; /* look for `closefile' which ends the eexec section */ - else if ( *cur == 'c' && cur + 9 < limit && - ft_strncmp( (char*)cur, "closefile", 9 ) == 0 ) + else if ( IS_PS_TOKEN( cur, limit, "closefile" ) ) break; + /* in a synthetic font the base font starts after a */ + /* `FontDictionary' token that is placed after a Private dict */ + else if ( IS_PS_TOKEN( cur, limit, "FontDirectory" ) ) + { + if ( loader->keywords_encountered & T1_PRIVATE ) + loader->keywords_encountered |= + T1_FONTDIR_AFTER_PRIVATE; + parser->root.cursor += 13; + } + /* check whether we have an integer */ else if ( ft_isdigit( *cur ) ) { @@ -1834,8 +1846,7 @@ if ( len > 0 && len < 22 && parser->root.cursor < limit ) { /* now compare the immediate name to the keyword table */ - T1_Field keyword = (T1_Field)t1_keywords; - FT_Byte* keyword_flag = keyword_flags; + T1_Field keyword = (T1_Field)t1_keywords; for (;;) @@ -1851,21 +1862,54 @@ len == (FT_PtrDist)ft_strlen( (const char *)name ) && ft_memcmp( cur, name, len ) == 0 ) { - /* We found it -- run the parsing callback! */ - /* We only record the first instance of any */ - /* field to deal adequately with synthetic */ - /* fonts; /Subrs and /CharStrings are */ - /* handled specially. */ - if ( keyword_flag[0] == 0 || - ft_strcmp( (const char*)name, "Subrs" ) == 0 || + /* We found it -- run the parsing callback! */ + /* We record every instance of every field */ + /* (until we reach the base font of a */ + /* synthetic font) to deal adequately with */ + /* multiple master fonts; this is also */ + /* necessary because later PostScript */ + /* definitions override earlier ones. */ + + /* Once we encounter `FontDirectory' after */ + /* `/Private', we know that this is a synthetic */ + /* font; except for `/CharStrings' we are not */ + /* interested in anything that follows this */ + /* `FontDirectory'. */ + + /* MM fonts have more than one /Private token at */ + /* the top level; let's hope that all the junk */ + /* that follows the first /Private token is not */ + /* interesting to us. */ + + /* According to Adobe Tech Note #5175 (CID-Keyed */ + /* Font Installation for ATM Software) a `begin' */ + /* must be followed by exactly one `end', and */ + /* `begin' -- `end' pairs must be accurately */ + /* paired. We could use this to dinstinguish */ + /* between the global Private and the Private */ + /* dict that is a member of the Blend dict. */ + + const FT_UInt dict = + ( loader->keywords_encountered & T1_PRIVATE ) + ? T1_FIELD_DICT_PRIVATE + : T1_FIELD_DICT_FONTDICT; + + if ( !( dict & keyword->dict ) ) + { + FT_TRACE1(( "parse_dict: found %s but ignoring it " + "since it is in the wrong dictionary\n", + keyword->ident )); + break; + } + + if ( !( loader->keywords_encountered & + T1_FONTDIR_AFTER_PRIVATE ) || ft_strcmp( (const char*)name, "CharStrings" ) == 0 ) { parser->root.error = t1_load_keyword( face, loader, keyword ); - if ( parser->root.error == T1_Err_Ok ) - keyword_flag[0] = 1; - else + if ( parser->root.error != T1_Err_Ok ) { if ( FT_ERROR_BASE( parser->root.error ) == FT_Err_Ignore ) parser->root.error = T1_Err_Ok; @@ -1877,7 +1921,6 @@ } keyword++; - keyword_flag++; } } @@ -1910,12 +1953,13 @@ loader->num_chars = 0; /* initialize the tables -- simply set their `init' field to 0 */ - loader->encoding_table.init = 0; - loader->charstrings.init = 0; - loader->glyph_names.init = 0; - loader->subrs.init = 0; - loader->swap_table.init = 0; - loader->fontdata = 0; + loader->encoding_table.init = 0; + loader->charstrings.init = 0; + loader->glyph_names.init = 0; + loader->subrs.init = 0; + loader->swap_table.init = 0; + loader->fontdata = 0; + loader->keywords_encountered = 0; } @@ -1945,7 +1989,6 @@ T1_Font type1 = &face->type1; PS_Private priv = &type1->private_dict; FT_Error error; - FT_Byte keyword_flags[T1_FIELD_COUNT]; PSAux_Service psaux = (PSAux_Service)face->psaux; @@ -1953,6 +1996,10 @@ t1_init_loader( &loader, face ); /* default values */ + face->ndv_idx = -1; + face->cdv_idx = -1; + face->len_buildchar = 0; + priv->blue_shift = 7; priv->blue_fuzz = 1; priv->lenIV = 4; @@ -1967,16 +2014,8 @@ if ( error ) goto Exit; - { - FT_UInt n; - - - for ( n = 0; n < T1_FIELD_COUNT; n++ ) - keyword_flags[n] = 0; - } - - error = parse_dict( face, &loader, parser->base_dict, parser->base_len, - keyword_flags ); + error = parse_dict( face, &loader, + parser->base_dict, parser->base_len ); if ( error ) goto Exit; @@ -1984,17 +2023,29 @@ if ( error ) goto Exit; - error = parse_dict( face, &loader, parser->private_dict, - parser->private_len, - keyword_flags ); + error = parse_dict( face, &loader, + parser->private_dict, parser->private_len ); if ( error ) goto Exit; - + /* ensure even-ness of `num_blue_values' */ priv->num_blue_values &= ~1; #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + if ( face->blend && + face->blend->num_default_design_vector != 0 && + face->blend->num_default_design_vector != face->blend->num_axis ) + { + /* we don't use it currently so just warn, reset, and ignore */ + FT_ERROR(( "T1_Open_Face(): /DesignVector contains %u entries " + "while there are %u axes.\n", + face->blend->num_default_design_vector, + face->blend->num_axis )); + + face->blend->num_default_design_vector = 0; + } + /* the following can happen for MM instances; we then treat the */ /* font as a normal PS font */ if ( face->blend && @@ -2015,6 +2066,22 @@ } } + if ( face->blend ) + { + if ( face->len_buildchar > 0 ) + { + FT_Memory memory = face->root.memory; + + + if ( FT_NEW_ARRAY( face->buildchar, face->len_buildchar ) ) + { + FT_ERROR(( "T1_Open_Face: cannot allocate BuildCharArray\n" )); + face->len_buildchar = 0; + goto Exit; + } + } + } + #endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ /* now, propagate the subrs, charstrings, and glyphnames tables */ diff --git a/src/libs/freetype2/type1/t1load.h b/src/libs/freetype2/type1/t1load.h index 9823f53e0b..717ae6138c 100644 --- a/src/libs/freetype2/type1/t1load.h +++ b/src/libs/freetype2/type1/t1load.h @@ -4,7 +4,7 @@ /* */ /* Type 1 font loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2004 by */ +/* Copyright 1996-2001, 2002, 2004, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -48,9 +48,18 @@ FT_BEGIN_HEADER PS_TableRec subrs; FT_Bool fontdata; + FT_UInt keywords_encountered; /* T1_LOADER_ENCOUNTERED_XXX */ + } T1_LoaderRec, *T1_Loader; + /* treatment of some keywords differs depending on whether */ + /* they preceed or follow certain other keywords */ + +#define T1_PRIVATE ( 1 << 0 ) +#define T1_FONTDIR_AFTER_PRIVATE ( 1 << 1 ) + + FT_LOCAL( FT_Error ) T1_Open_Face( T1_Face face ); diff --git a/src/libs/freetype2/type1/t1objs.c b/src/libs/freetype2/type1/t1objs.c index aa95122e30..095e7f16c8 100644 --- a/src/libs/freetype2/type1/t1objs.c +++ b/src/libs/freetype2/type1/t1objs.c @@ -201,6 +201,16 @@ #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT /* release multiple masters information */ + FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); + + if ( face->buildchar ) + { + FT_FREE( face->buildchar ); + + face->buildchar = NULL; + face->len_buildchar = 0; + } + T1_Done_Blend( face ); face->blend = 0; #endif diff --git a/src/libs/freetype2/type1/t1objs.h b/src/libs/freetype2/type1/t1objs.h index ba258d267a..e5e90293d7 100644 --- a/src/libs/freetype2/type1/t1objs.h +++ b/src/libs/freetype2/type1/t1objs.h @@ -152,7 +152,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) T1_GlyphSlot_Init( T1_GlyphSlot slot ); - + FT_LOCAL( void ) T1_GlyphSlot_Done( T1_GlyphSlot slot ); diff --git a/src/libs/freetype2/type1/t1parse.c b/src/libs/freetype2/type1/t1parse.c index db1a613cbb..1b252c7483 100644 --- a/src/libs/freetype2/type1/t1parse.c +++ b/src/libs/freetype2/type1/t1parse.c @@ -105,18 +105,18 @@ if ( FT_STREAM_SEEK( 0 ) ) goto Exit; - + error = read_pfb_tag( stream, &tag, &size ); if ( error ) goto Exit; - + if ( tag != 0x8001U && FT_STREAM_SEEK( 0 ) ) goto Exit; - + if ( !FT_FRAME_ENTER( header_length ) ) { error = 0; - + if ( ft_memcmp( stream->cursor, header_string, header_length ) != 0 ) error = T1_Err_Unknown_File_Format; diff --git a/src/libs/freetype2/type1/t1tokens.h b/src/libs/freetype2/type1/t1tokens.h index a3cc952e00..788c811b04 100644 --- a/src/libs/freetype2/type1/t1tokens.h +++ b/src/libs/freetype2/type1/t1tokens.h @@ -4,7 +4,7 @@ /* */ /* Type 1 tokenizer (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,17 +21,26 @@ #undef T1CODE #define T1CODE T1_FIELD_LOCATION_FONT_INFO - T1_FIELD_STRING( "version", version ) - T1_FIELD_STRING( "Notice", notice ) - T1_FIELD_STRING( "FullName", full_name ) - T1_FIELD_STRING( "FamilyName", family_name ) - T1_FIELD_STRING( "Weight", weight ) + T1_FIELD_STRING( "version", version, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_STRING( "Notice", notice, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_STRING( "FullName", full_name, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_STRING( "FamilyName", family_name, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_STRING( "Weight", weight, + T1_FIELD_DICT_FONTDICT ) /* we use pointers to detect modifications made by synthetic fonts */ - T1_FIELD_NUM ( "ItalicAngle", italic_angle ) - T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch ) - T1_FIELD_NUM ( "UnderlinePosition", underline_position ) - T1_FIELD_NUM ( "UnderlineThickness", underline_thickness ) + T1_FIELD_NUM ( "ItalicAngle", italic_angle, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_NUM ( "UnderlinePosition", underline_position, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, + T1_FIELD_DICT_FONTDICT ) #undef FT_STRUCTURE @@ -39,28 +48,45 @@ #undef T1CODE #define T1CODE T1_FIELD_LOCATION_PRIVATE - T1_FIELD_NUM ( "UniqueID", unique_id ) - T1_FIELD_NUM ( "lenIV", lenIV ) - T1_FIELD_NUM ( "LanguageGroup", language_group ) - T1_FIELD_NUM ( "password", password ) + T1_FIELD_NUM ( "UniqueID", unique_id, + T1_FIELD_DICT_FONTDICT | T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM ( "lenIV", lenIV, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM ( "LanguageGroup", language_group, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM ( "password", password, + T1_FIELD_DICT_PRIVATE ) - T1_FIELD_FIXED_1000( "BlueScale", blue_scale ) - T1_FIELD_NUM ( "BlueShift", blue_shift ) - T1_FIELD_NUM ( "BlueFuzz", blue_fuzz ) + T1_FIELD_FIXED_1000( "BlueScale", blue_scale, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM ( "BlueShift", blue_shift, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM ( "BlueFuzz", blue_fuzz, + T1_FIELD_DICT_PRIVATE ) - T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14 ) - T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10 ) - T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14 ) - T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10 ) + T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10, + T1_FIELD_DICT_PRIVATE ) - T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1 ) - T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1 ) - T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2 ) + T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2, + T1_FIELD_DICT_PRIVATE ) - T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 ) - T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 ) + T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12, + T1_FIELD_DICT_PRIVATE ) - T1_FIELD_FIXED ( "ExpansionFactor", expansion_factor ) + T1_FIELD_FIXED ( "ExpansionFactor", expansion_factor, + T1_FIELD_DICT_PRIVATE ) #undef FT_STRUCTURE @@ -68,17 +94,41 @@ #undef T1CODE #define T1CODE T1_FIELD_LOCATION_FONT_DICT - T1_FIELD_KEY ( "FontName", font_name ) - T1_FIELD_NUM ( "PaintType", paint_type ) - T1_FIELD_NUM ( "FontType", font_type ) - T1_FIELD_FIXED( "StrokeWidth", stroke_width ) + T1_FIELD_KEY ( "FontName", font_name, T1_FIELD_DICT_FONTDICT ) + T1_FIELD_NUM ( "PaintType", paint_type, T1_FIELD_DICT_FONTDICT ) + T1_FIELD_NUM ( "FontType", font_type, T1_FIELD_DICT_FONTDICT ) + T1_FIELD_FIXED( "StrokeWidth", stroke_width, T1_FIELD_DICT_FONTDICT ) + #undef FT_STRUCTURE #define FT_STRUCTURE FT_BBox #undef T1CODE #define T1CODE T1_FIELD_LOCATION_BBOX - T1_FIELD_BBOX("FontBBox", xMin ) + T1_FIELD_BBOX( "FontBBox", xMin, T1_FIELD_DICT_FONTDICT ) + + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + +#undef FT_STRUCTURE +#define FT_STRUCTURE T1_FaceRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FACE + + T1_FIELD_NUM( "NDV", ndv_idx, T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM( "CDV", cdv_idx, T1_FIELD_DICT_PRIVATE ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_BlendRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_BLEND + + T1_FIELD_NUM_TABLE( "DesignVector", default_design_vector, + T1_MAX_MM_DESIGNS, T1_FIELD_DICT_FONTDICT ) + + +#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ /* END */ diff --git a/src/libs/freetype2/type42/t42drivr.c b/src/libs/freetype2/type42/t42drivr.c index e3c469742b..82eb0ba1e0 100644 --- a/src/libs/freetype2/type42/t42drivr.c +++ b/src/libs/freetype2/type42/t42drivr.c @@ -199,7 +199,7 @@ { FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_SCALABLE | -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER FT_MODULE_DRIVER_HAS_HINTER, #else 0, diff --git a/src/libs/freetype2/type42/t42objs.c b/src/libs/freetype2/type42/t42objs.c index 30d9dcc8fe..ecd0473647 100644 --- a/src/libs/freetype2/type42/t42objs.c +++ b/src/libs/freetype2/type42/t42objs.c @@ -209,6 +209,9 @@ if ( info->is_fixed_pitch ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + /* We only set this flag if we have the patented bytecode interpreter. */ + /* There are no known `tricky' Type42 fonts that could be loaded with */ + /* the unpatented interpreter. */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER root->face_flags |= FT_FACE_FLAG_HINTER; #endif diff --git a/src/libs/freetype2/type42/t42objs.h b/src/libs/freetype2/type42/t42objs.h index aff26751f2..289dedcc69 100644 --- a/src/libs/freetype2/type42/t42objs.h +++ b/src/libs/freetype2/type42/t42objs.h @@ -4,7 +4,7 @@ /* */ /* Type 42 objects manager (specification). */ /* */ -/* Copyright 2002, 2003, 2006 by Roberto Alameda. */ +/* Copyright 2002, 2003, 2006, 2007 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 */ @@ -86,7 +86,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) T42_Size_Select( T42_Size size, - FT_ULong index ); + FT_ULong strike_index ); FT_LOCAL( void ) diff --git a/src/libs/freetype2/type42/t42parse.c b/src/libs/freetype2/type42/t42parse.c index 6e1a683278..9233985581 100644 --- a/src/libs/freetype2/type42/t42parse.c +++ b/src/libs/freetype2/type42/t42parse.c @@ -49,6 +49,8 @@ T42_Loader loader ); + /* as Type42 fonts have no Private dict, */ + /* we set the last argument of T1_FIELD_XXX to 0 */ static const T1_FieldRec t42_keywords[] = { @@ -57,39 +59,39 @@ #undef T1CODE #define T1CODE T1_FIELD_LOCATION_FONT_INFO - T1_FIELD_STRING( "version", version ) - T1_FIELD_STRING( "Notice", notice ) - T1_FIELD_STRING( "FullName", full_name ) - T1_FIELD_STRING( "FamilyName", family_name ) - T1_FIELD_STRING( "Weight", weight ) - T1_FIELD_NUM ( "ItalicAngle", italic_angle ) - T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch ) - T1_FIELD_NUM ( "UnderlinePosition", underline_position ) - T1_FIELD_NUM ( "UnderlineThickness", underline_thickness ) + T1_FIELD_STRING( "version", version, 0 ) + T1_FIELD_STRING( "Notice", notice, 0 ) + T1_FIELD_STRING( "FullName", full_name, 0 ) + T1_FIELD_STRING( "FamilyName", family_name, 0 ) + T1_FIELD_STRING( "Weight", weight, 0 ) + T1_FIELD_NUM ( "ItalicAngle", italic_angle, 0 ) + T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch, 0 ) + T1_FIELD_NUM ( "UnderlinePosition", underline_position, 0 ) + T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, 0 ) #undef FT_STRUCTURE #define FT_STRUCTURE T1_FontRec #undef T1CODE #define T1CODE T1_FIELD_LOCATION_FONT_DICT - T1_FIELD_KEY ( "FontName", font_name ) - T1_FIELD_NUM ( "PaintType", paint_type ) - T1_FIELD_NUM ( "FontType", font_type ) - T1_FIELD_FIXED( "StrokeWidth", stroke_width ) + T1_FIELD_KEY ( "FontName", font_name, 0 ) + T1_FIELD_NUM ( "PaintType", paint_type, 0 ) + T1_FIELD_NUM ( "FontType", font_type, 0 ) + T1_FIELD_FIXED( "StrokeWidth", stroke_width, 0 ) #undef FT_STRUCTURE #define FT_STRUCTURE FT_BBox #undef T1CODE #define T1CODE T1_FIELD_LOCATION_BBOX - T1_FIELD_BBOX("FontBBox", xMin ) + T1_FIELD_BBOX("FontBBox", xMin, 0 ) - T1_FIELD_CALLBACK( "FontMatrix", t42_parse_font_matrix ) - T1_FIELD_CALLBACK( "Encoding", t42_parse_encoding ) - T1_FIELD_CALLBACK( "CharStrings", t42_parse_charstrings ) - T1_FIELD_CALLBACK( "sfnts", t42_parse_sfnts ) + T1_FIELD_CALLBACK( "FontMatrix", t42_parse_font_matrix, 0 ) + T1_FIELD_CALLBACK( "Encoding", t42_parse_encoding, 0 ) + T1_FIELD_CALLBACK( "CharStrings", t42_parse_charstrings, 0 ) + T1_FIELD_CALLBACK( "sfnts", t42_parse_sfnts, 0 ) - { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 } + { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } }; diff --git a/src/libs/freetype2/winfonts/winfnt.c b/src/libs/freetype2/winfonts/winfnt.c index 3523b14f81..d3d602426e 100644 --- a/src/libs/freetype2/winfonts/winfnt.c +++ b/src/libs/freetype2/winfonts/winfnt.c @@ -649,7 +649,8 @@ FT_UNUSED( load_flags ); - if ( !face || !font ) + if ( !face || !font || + glyph_index >= (FT_UInt)( FT_FACE( face )->num_glyphs ) ) { error = FNT_Err_Invalid_Argument; goto Exit;