diff options
Diffstat (limited to 'third_party')
246 files changed, 10060 insertions, 4419 deletions
diff --git a/third_party/BUILD.gn b/third_party/BUILD.gn index 78afcd0860..2055821f8e 100644 --- a/third_party/BUILD.gn +++ b/third_party/BUILD.gn @@ -43,7 +43,12 @@ config("fx_freetype_warnings") { if (is_clang) { # open_face_PS_from_sfnt_stream() and open_face_from_buffer() in # ftbase.h are unused. - cflags = [ "-Wno-unused-function" ] + # + # ttgload.c casts from unsigned int to unsigned long to void*. + cflags = [ + "-Wno-unused-function", + "-Wno-int-to-void-pointer-cast", + ] } } @@ -96,6 +101,7 @@ static_library("fx_freetype") { "freetype/include/freetype/internal/ftdebug.h", "freetype/include/freetype/internal/ftdriver.h", "freetype/include/freetype/internal/ftgloadr.h", + "freetype/include/freetype/internal/fthash.h", "freetype/include/freetype/internal/ftmemory.h", "freetype/include/freetype/internal/ftobjs.h", "freetype/include/freetype/internal/ftpic.h", @@ -110,6 +116,7 @@ static_library("fx_freetype") { "freetype/include/freetype/internal/services/svfntfmt.h", "freetype/include/freetype/internal/services/svgldict.h", "freetype/include/freetype/internal/services/svkern.h", + "freetype/include/freetype/internal/services/svmetric.h", "freetype/include/freetype/internal/services/svmm.h", "freetype/include/freetype/internal/services/svpostnm.h", "freetype/include/freetype/internal/services/svprop.h", diff --git a/third_party/freetype/0000-include.patch b/third_party/freetype/0000-include.patch index d7478e7811..d6c837471c 100644 --- a/third_party/freetype/0000-include.patch +++ b/third_party/freetype/0000-include.patch @@ -1,28 +1,6 @@ -diff -ru freetype-2.6.1/include/freetype/config/ftmodule.h include/freetype/config/ftmodule.h ---- freetype-2.6.1/include/freetype/config/ftmodule.h 2015-11-05 13:52:36.734733186 -0800 -+++ include/freetype/config/ftmodule.h 2015-11-05 13:44:54.445479822 -0800 -@@ -1,3 +1,20 @@ -+/***************************************************************************/ -+/* */ -+/* ftmodule.h */ -+/* */ -+/* FreeType modules public interface (specification). */ -+/* */ -+/* Copyright 1996-2001, 2002, 2003 by */ -+/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -+/* */ -+/* This file is part of the FreeType project, and may only be used, */ -+/* 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. */ -+/* */ -+/***************************************************************************/ -+ - /* - * This file registers the FreeType modules compiled into the library. - * -@@ -10,15 +27,15 @@ +--- third_party/freetype/include/freetype/config/ftmodule.h 2017-03-07 20:15:52.781636524 -0800 ++++ third_party/freetype/include/freetype/config/ftmodule.h 2017-03-22 22:57:58.536233071 -0700 +@@ -10,15 +10,15 @@ * */ @@ -43,7 +21,7 @@ diff -ru freetype-2.6.1/include/freetype/config/ftmodule.h include/freetype/conf FT_USE_MODULE( FT_Module_Class, psaux_module_class ) FT_USE_MODULE( FT_Module_Class, psnames_module_class ) FT_USE_MODULE( FT_Module_Class, pshinter_module_class ) -@@ -27,6 +44,6 @@ +@@ -27,6 +27,6 @@ FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class ) FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class ) FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class ) @@ -51,10 +29,9 @@ diff -ru freetype-2.6.1/include/freetype/config/ftmodule.h include/freetype/conf +//FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class ) /* EOF */ -diff -ru freetype-2.6.1/include/freetype/config/ftoption.h include/freetype/config/ftoption.h ---- freetype-2.6.1/include/freetype/config/ftoption.h 2015-11-05 13:52:36.734733186 -0800 -+++ include/freetype/config/ftoption.h 2015-11-05 13:44:54.445479822 -0800 -@@ -92,7 +92,7 @@ +--- third_party/freetype/include/freetype/config/ftoption.h 2017-03-07 20:15:52.781636524 -0800 ++++ third_party/freetype/include/freetype/config/ftoption.h 2017-03-22 22:57:58.532233095 -0700 +@@ -122,7 +122,7 @@ /* This is done to allow FreeType clients to run unmodified, forcing */ /* them to display normal gray-level anti-aliased glyphs. */ /* */ @@ -63,16 +40,16 @@ diff -ru freetype-2.6.1/include/freetype/config/ftoption.h include/freetype/conf /*************************************************************************/ -@@ -163,7 +163,7 @@ +@@ -193,7 +193,7 @@ /* Define this macro if you want to enable this `feature'. See also */ /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ /* */ -#define FT_CONFIG_OPTION_USE_ZLIB -+//#define FT_CONFIG_OPTION_USE_ZLIB ++#undef FT_CONFIG_OPTION_USE_ZLIB /*************************************************************************/ -@@ -336,7 +336,7 @@ +@@ -366,7 +366,7 @@ /* */ /* Note that the `FOND' resource isn't checked. */ /* */ @@ -81,7 +58,7 @@ diff -ru freetype-2.6.1/include/freetype/config/ftoption.h include/freetype/conf /*************************************************************************/ -@@ -512,7 +512,7 @@ +@@ -556,7 +556,7 @@ /* embedded bitmaps in all formats using the SFNT module (namely */ /* TrueType & OpenType). */ /* */ @@ -90,7 +67,7 @@ diff -ru freetype-2.6.1/include/freetype/config/ftoption.h include/freetype/conf /*************************************************************************/ -@@ -681,7 +681,7 @@ +@@ -705,7 +705,7 @@ /* and avar tables). This has many similarities to Type 1 Multiple */ /* Masters support. */ /* */ @@ -99,7 +76,7 @@ diff -ru freetype-2.6.1/include/freetype/config/ftoption.h include/freetype/conf /*************************************************************************/ -@@ -689,7 +689,7 @@ +@@ -713,7 +713,7 @@ /* Define TT_CONFIG_OPTION_BDF if you want to include support for */ /* an embedded `BDF ' table within SFNT-based bitmap formats. */ /* */ @@ -108,7 +85,7 @@ diff -ru freetype-2.6.1/include/freetype/config/ftoption.h include/freetype/conf /*************************************************************************/ -@@ -725,7 +725,7 @@ +@@ -767,7 +767,7 @@ /* */ /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ /* */ @@ -117,4 +94,3 @@ diff -ru freetype-2.6.1/include/freetype/config/ftoption.h include/freetype/conf /*************************************************************************/ -Only in freetype-2.6.1/include/freetype: ftchapters.h diff --git a/third_party/freetype/README.pdfium b/third_party/freetype/README.pdfium index f8fad6f3b4..2054aab7f1 100644 --- a/third_party/freetype/README.pdfium +++ b/third_party/freetype/README.pdfium @@ -1,6 +1,7 @@ Name: FreeType URL: http://www.freetype.org/ -Version: 2.6.1 +Version: VER-2-7-1-updates +Revision: 66725768cdf758cfb3f9abf03cbf5e5a77f42088 Security Critical: yes License: FreeType License (FTL) License File: FTL.TXT @@ -11,24 +12,3 @@ FreeType library. Local Modifications: 0000-include.patch: Modifications to configuration header files. - -include/freetype/ftchapers.h is not included. - -The following directories in src/ are not included from -upstream FreeType as they are never used: - -autofit -bdf -bzip2 -cache -gxvalid -gzip -Jamfile -lzw -otvalid -pcf -pfr -tools -type42 -winfonts - diff --git a/third_party/freetype/include/freetype/config/ftconfig.h b/third_party/freetype/include/freetype/config/ftconfig.h index d4d79936df..9d7f8839b0 100644 --- a/third_party/freetype/include/freetype/config/ftconfig.h +++ b/third_party/freetype/include/freetype/config/ftconfig.h @@ -4,7 +4,7 @@ /* */ /* ANSI-specific configuration file (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,8 +35,8 @@ /* */ /*************************************************************************/ -#ifndef __FTCONFIG_H__ -#define __FTCONFIG_H__ +#ifndef FTCONFIG_H_ +#define FTCONFIG_H_ #include <ft2build.h> #include FT_CONFIG_OPTIONS_H @@ -143,6 +143,14 @@ FT_BEGIN_HEADER #endif + /* Fix compiler warning with sgi compiler */ +#if defined( __sgi ) && !defined( __GNUC__ ) +#if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 ) +#pragma set woff 3505 +#endif +#endif + + /*************************************************************************/ /* */ /* <Section> */ @@ -275,7 +283,13 @@ FT_BEGIN_HEADER /* */ #elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 ) -#if defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ +#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L + +#define FT_LONG64 +#define FT_INT64 long long int +#define FT_UINT64 unsigned long long int + +#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ /* this compiler provides the __int64 type */ #define FT_LONG64 @@ -309,7 +323,7 @@ FT_BEGIN_HEADER #define FT_INT64 long long int #define FT_UINT64 unsigned long long int -#endif /* _MSC_VER */ +#endif /* __STDC_VERSION__ >= 199901L */ #endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ @@ -332,10 +346,11 @@ FT_BEGIN_HEADER /* typeof condition taken from gnulib's `intprops.h' header file */ -#if ( __GNUC__ >= 2 || \ - defined( __IBM__TYPEOF__ ) || \ - ( __SUNPRO_C >= 0x5110 && !__STDC__ ) ) -#define FT_TYPEOF( type ) (__typeof__ (type)) +#if ( ( defined( __GNUC__ ) && __GNUC__ >= 2 ) || \ + ( defined( __IBMC__ ) && __IBMC__ >= 1210 && \ + defined( __IBM__TYPEOF__ ) ) || \ + ( defined( __SUNPRO_C ) && __SUNPRO_C >= 0x5110 && !__STDC__ ) ) +#define FT_TYPEOF( type ) ( __typeof__ ( type ) ) #else #define FT_TYPEOF( type ) /* empty */ #endif @@ -461,7 +476,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCONFIG_H__ */ +#endif /* FTCONFIG_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/config/ftheader.h b/third_party/freetype/include/freetype/config/ftheader.h index 55f833db0f..950d36c91f 100644 --- a/third_party/freetype/include/freetype/config/ftheader.h +++ b/third_party/freetype/include/freetype/config/ftheader.h @@ -4,7 +4,7 @@ /* */ /* Build macros of the FreeType 2 library. */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -15,8 +15,8 @@ /* */ /***************************************************************************/ -#ifndef __FT_HEADER_H__ -#define __FT_HEADER_H__ +#ifndef FTHEADER_H_ +#define FTHEADER_H_ /*@***********************************************************************/ @@ -753,8 +753,7 @@ * FT_UNPATENTED_HINTING_H * * @description: - * A macro used in #include statements to name the file containing the - * FreeType~2 API which performs color filtering for subpixel rendering. + * Deprecated. */ #define FT_UNPATENTED_HINTING_H <freetype/ttunpat.h> @@ -766,7 +765,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType~2 API which performs color filtering for subpixel rendering. + * FreeType~2 API which performs incremental glyph loading. */ #define FT_INCREMENTAL_H <freetype/ftincrem.h> @@ -828,7 +827,7 @@ #endif /* FT2_BUILD_LIBRARY */ -#endif /* __FT2_BUILD_H__ */ +#endif /* FTHEADER_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/config/ftmodule.h b/third_party/freetype/include/freetype/config/ftmodule.h index fb255743a7..0d31ce6932 100644 --- a/third_party/freetype/include/freetype/config/ftmodule.h +++ b/third_party/freetype/include/freetype/config/ftmodule.h @@ -1,20 +1,3 @@ -/***************************************************************************/ -/* */ -/* ftmodule.h */ -/* */ -/* FreeType modules public interface (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2003 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* 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. */ -/* */ -/***************************************************************************/ - /* * This file registers the FreeType modules compiled into the library. * diff --git a/third_party/freetype/include/freetype/config/ftoption.h b/third_party/freetype/include/freetype/config/ftoption.h index 886e64e9bf..802beb5036 100644 --- a/third_party/freetype/include/freetype/config/ftoption.h +++ b/third_party/freetype/include/freetype/config/ftoption.h @@ -4,7 +4,7 @@ /* */ /* User-selectable configuration macros (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTOPTION_H__ -#define __FTOPTION_H__ +#ifndef FTOPTION_H_ +#define FTOPTION_H_ #include <ft2build.h> @@ -77,6 +77,36 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ + /* If you enable this configuration option, FreeType recognizes an */ + /* environment variable called `FREETYPE_PROPERTIES', which can be used */ + /* to control the various font drivers and modules. The controllable */ + /* properties are listed in the section `Controlling FreeType Modules' */ + /* in the reference's table of contents; currently there are properties */ + /* for the auto-hinter (file `ftautoh.h'), CFF (file `ftcffdrv.h'), */ + /* TrueType (file `ftttdrv.h'), and PCF (file `ftpcfdrv.h'). */ + /* */ + /* `FREETYPE_PROPERTIES' has the following syntax form (broken here into */ + /* multiple lines for better readability). */ + /* */ + /* <optional whitespace> */ + /* <module-name1> ':' */ + /* <property-name1> '=' <property-value1> */ + /* <whitespace> */ + /* <module-name2> ':' */ + /* <property-name2> '=' <property-value2> */ + /* ... */ + /* */ + /* Example: */ + /* */ + /* FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ */ + /* cff:no-stem-darkening=1 \ */ + /* autofitter:warping=1 */ + /* */ +#define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + + + /*************************************************************************/ + /* */ /* 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. */ /* */ @@ -163,7 +193,7 @@ FT_BEGIN_HEADER /* Define this macro if you want to enable this `feature'. See also */ /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ /* */ -//#define FT_CONFIG_OPTION_USE_ZLIB +#undef FT_CONFIG_OPTION_USE_ZLIB /*************************************************************************/ @@ -492,7 +522,21 @@ FT_BEGIN_HEADER /* code will be used. */ /* */ /* Setting this macro is needed for systems that prohibit address */ - /* fixups, such as BREW. */ + /* fixups, such as BREW. [Note that standard compilers like gcc or */ + /* clang handle PIC generation automatically; you don't have to set */ + /* FT_CONFIG_OPTION_PIC, which is only necessary for very special */ + /* compilers.] */ + /* */ + /* Note that FT_CONFIG_OPTION_PIC support is not available for all */ + /* modules (see `modules.cfg' for a complete list). For building with */ + /* FT_CONFIG_OPTION_PIC support, do the following. */ + /* */ + /* 0. Clone the repository. */ + /* 1. Define FT_CONFIG_OPTION_PIC. */ + /* 2. Remove all subdirectories in `src' that don't have */ + /* FT_CONFIG_OPTION_PIC support. */ + /* 3. Comment out the corresponding modules in `modules.cfg'. */ + /* 4. Compile. */ /* */ /* #define FT_CONFIG_OPTION_PIC */ @@ -586,73 +630,53 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ - /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */ - /* replaces the native TrueType hinting mechanism when anything but */ - /* FT_RENDER_MODE_MONO is requested. */ - /* */ - /* Enabling this causes the TrueType driver to ignore instructions under */ - /* certain conditions. This is done in accordance with the guide here, */ - /* with some minor differences: */ - /* */ - /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ - /* */ - /* By undefining this, you only compile the code necessary to hint */ - /* TrueType glyphs with native TT hinting. */ + /* subpixel hinting support into the TrueType driver. This modifies the */ + /* TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is */ + /* requested. */ /* */ - /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ - /* defined. */ + /* In particular, it modifies the bytecode interpreter to interpret (or */ + /* not) instructions in a certain way so that all TrueType fonts look */ + /* like they do in a Windows ClearType (DirectWrite) environment. See */ + /* [1] for a technical overview on what this means. See `ttinterp.h' */ + /* for more details on the LEAN option. */ /* */ -/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - - /*************************************************************************/ - /* */ - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ - /* of the TrueType bytecode interpreter is used that doesn't implement */ - /* any of the patented opcodes and algorithms. The patents related to */ - /* TrueType hinting have expired worldwide since May 2010; this option */ - /* is now deprecated. */ - /* */ - /* Note that the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* */ - /* if you define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words, */ - /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ - /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ - /* */ - /* This macro is only useful for a small number of font files (mostly */ - /* for Asian scripts) that require bytecode interpretation to properly */ - /* load glyphs. For all other fonts, this produces unpleasant results, */ - /* thus the unpatented interpreter is never used to load glyphs from */ - /* TrueType fonts unless one of the following two options is used. */ + /* There are three options. */ /* */ - /* - The unpatented interpreter is explicitly activated by the user */ - /* through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag */ - /* when opening the FT_Face. */ + /* 1. This option is associated with the `Infinality' moniker. */ + /* Contributed by an individual nicknamed Infinality with the goal of */ + /* making TrueType fonts render better than on Windows. A high */ + /* amount of configurability and flexibility, down to rules for */ + /* single glyphs in fonts, but also very slow. Its experimental and */ + /* slow nature and the original developer losing interest meant that */ + /* this option was never enabled in default builds. */ /* */ - /* - FreeType detects that the FT_Face corresponds to one of the */ - /* `trick' fonts (e.g., `Mingliu') it knows about. The font engine */ - /* contains a hard-coded list of font names and other matching */ - /* parameters (see function `tt_face_init' in file */ - /* `src/truetype/ttobjs.c'). */ + /* 2. The new default mode for the TrueType driver. The Infinality code */ + /* base was stripped to the bare minimum and all configurability */ + /* removed in the name of speed and simplicity. The configurability */ + /* was mainly aimed at legacy fonts like Arial, Times New Roman, or */ + /* Courier. Legacy fonts are fonts that modify vertical stems to */ + /* achieve clean black-and-white bitmaps. The new mode focuses on */ + /* applying a minimal set of rules to all fonts indiscriminately so */ + /* that modern and web fonts render well while legacy fonts render */ + /* okay. */ /* */ - /* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */ + /* 3. Compile both. */ /* */ - /* { */ - /* FT_Parameter parameter; */ - /* FT_Open_Args open_args; */ + /* By undefining these, you get rendering behavior like on Windows */ + /* without ClearType, i.e., Windows XP without ClearType enabled and */ + /* Win9x (interpreter version v35). Or not, depending on how much */ + /* hinting blood and testing tears the font designer put into a given */ + /* font. If you define one or both subpixel hinting options, you can */ + /* switch between between v35 and the ones you define. */ /* */ + /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ + /* defined. */ /* */ - /* parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING; */ + /* [1] http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ /* */ - /* open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; */ - /* open_args.pathname = my_font_pathname; */ - /* open_args.num_params = 1; */ - /* open_args.params = ¶meter; */ - /* */ - /* error = FT_Open_Face( library, &open_args, index, &face ); */ - /* ... */ - /* } */ - /* */ -/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */ +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */ +#define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2 +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) */ /*************************************************************************/ @@ -693,6 +717,24 @@ FT_BEGIN_HEADER /*************************************************************************/ + /* */ + /* Option TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES controls the maximum */ + /* number of bytecode instructions executed for a single run of the */ + /* bytecode interpreter, needed to prevent infinite loops. You don't */ + /* want to change this except for very special situations (e.g., making */ + /* a library fuzzer spend less time to handle broken fonts). */ + /* */ + /* It is not expected that this value is ever modified by a configuring */ + /* script; instead, it gets surrounded with #ifndef ... #endif so that */ + /* the value can be set as a preprocessor option on the compiler's */ + /* command line. */ + /* */ +#ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES +#define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES 1000000L +#endif + + + /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ @@ -793,6 +835,33 @@ FT_BEGIN_HEADER /*************************************************************************/ /*************************************************************************/ /**** ****/ + /**** P C F D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* There are many PCF fonts just called `Fixed' which look completely */ + /* different, and which have nothing to do with each other. When */ + /* selecting `Fixed' in KDE or Gnome one gets results that appear rather */ + /* random, the style changes often if one changes the size and one */ + /* cannot select some fonts at all. This option makes the PCF module */ + /* prepend the foundry name (plus a space) to the family name. */ + /* */ + /* We also check whether we have `wide' characters; all put together, we */ + /* get family names like `Sony Fixed' or `Misc Fixed Wide'. */ + /* */ + /* If this option is activated, it can be controlled with the */ + /* `no-long-family-names' property of the pcf driver module. */ + /* */ +/* #define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */ + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ /**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/ /**** ****/ /*************************************************************************/ @@ -838,14 +907,19 @@ FT_BEGIN_HEADER /* - * This macro is defined if either unpatented or native TrueType - * hinting is requested by the definitions above. + * This macro is defined if native TrueType hinting is requested by the + * definitions above. */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER #define TT_USE_BYTECODE_INTERPRETER -#undef TT_CONFIG_OPTION_UNPATENTED_HINTING -#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING -#define TT_USE_BYTECODE_INTERPRETER + +#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1 +#define TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY +#endif + +#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2 +#define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL +#endif #endif @@ -880,7 +954,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTOPTION_H__ */ +#endif /* FTOPTION_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/config/ftstdlib.h b/third_party/freetype/include/freetype/config/ftstdlib.h index 4b471d4d15..05a4845fd5 100644 --- a/third_party/freetype/include/freetype/config/ftstdlib.h +++ b/third_party/freetype/include/freetype/config/ftstdlib.h @@ -5,7 +5,7 @@ /* ANSI-specific library and header configuration file (specification */ /* only). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,14 +23,13 @@ /* FreeType normally requires. It also defines macros to rename the */ /* standard functions within the FreeType source code. */ /* */ - /* Load a file which defines __FTSTDLIB_H__ before this one to override */ - /* it. */ + /* Load a file which defines FTSTDLIB_H_ before this one to override it. */ /* */ /*************************************************************************/ -#ifndef __FTSTDLIB_H__ -#define __FTSTDLIB_H__ +#ifndef FTSTDLIB_H_ +#define FTSTDLIB_H_ #include <stddef.h> @@ -64,6 +63,7 @@ #define FT_INT_MAX INT_MAX #define FT_INT_MIN INT_MIN #define FT_UINT_MAX UINT_MAX +#define FT_LONG_MIN LONG_MIN #define FT_LONG_MAX LONG_MAX #define FT_ULONG_MAX ULONG_MAX @@ -142,7 +142,8 @@ /**********************************************************************/ -#define ft_atol atol +#define ft_strtol strtol +#define ft_getenv getenv /**********************************************************************/ @@ -168,7 +169,7 @@ #include <stdarg.h> -#endif /* __FTSTDLIB_H__ */ +#endif /* FTSTDLIB_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/freetype.h b/third_party/freetype/include/freetype/freetype.h index b6247f510f..b6c6032528 100644 --- a/third_party/freetype/include/freetype/freetype.h +++ b/third_party/freetype/include/freetype/freetype.h @@ -4,7 +4,7 @@ /* */ /* FreeType high-level API and common types (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FREETYPE_H__ -#define __FREETYPE_H__ +#ifndef FREETYPE_H_ +#define FREETYPE_H_ #ifndef FT_FREETYPE_H @@ -141,7 +141,6 @@ FT_BEGIN_HEADER /* FT_FACE_FLAG_GLYPH_NAMES */ /* FT_FACE_FLAG_EXTERNAL_STREAM */ /* FT_FACE_FLAG_HINTER */ - /* FT_FACE_FLAG_TRICKY */ /* */ /* FT_HAS_HORIZONTAL */ /* FT_HAS_VERTICAL */ @@ -266,8 +265,8 @@ FT_BEGIN_HEADER /* FT_Glyph_Metrics */ /* */ /* <Description> */ - /* A structure used to model the metrics of a single glyph. The */ - /* values are expressed in 26.6 fractional pixel format; if the flag */ + /* A structure to model the metrics of a single glyph. The values */ + /* are expressed in 26.6 fractional pixel format; if the flag */ /* @FT_LOAD_NO_SCALE has been used while loading the glyph, values */ /* are expressed in font units instead. */ /* */ @@ -350,10 +349,10 @@ FT_BEGIN_HEADER /* */ /* <Note> */ /* Windows FNT: */ - /* The nominal size given in a FNT font is not reliable. Thus when */ - /* the driver finds it incorrect, it sets `size' to some calculated */ - /* values and sets `x_ppem' and `y_ppem' to the pixel width and */ - /* height given in the font, respectively. */ + /* The nominal size given in a FNT font is not reliable. If the */ + /* driver finds it incorrect, it sets `size' to some calculated */ + /* values, and `x_ppem' and `y_ppem' to the pixel width and height */ + /* given in the font, respectively. */ /* */ /* TrueType embedded bitmaps: */ /* `size', `width', and `height' values are not contained in the */ @@ -422,9 +421,9 @@ FT_BEGIN_HEADER /* FT_Module */ /* */ /* <Description> */ - /* A handle to a given FreeType module object. Each module can be a */ + /* A handle to a given FreeType module object. A module can be a */ /* font driver, a renderer, or anything else that provides services */ - /* to the formers. */ + /* to the former. */ /* */ typedef struct FT_ModuleRec_* FT_Module; @@ -435,8 +434,8 @@ FT_BEGIN_HEADER /* FT_Driver */ /* */ /* <Description> */ - /* A handle to a given FreeType font driver object. Each font driver */ - /* is a special module capable of creating faces from font files. */ + /* A handle to a given FreeType font driver object. A font driver */ + /* is a module capable of creating faces from font files. */ /* */ typedef struct FT_DriverRec_* FT_Driver; @@ -447,10 +446,10 @@ FT_BEGIN_HEADER /* FT_Renderer */ /* */ /* <Description> */ - /* A handle to a given FreeType renderer. A renderer is a special */ - /* module in charge of converting a glyph image to a bitmap, when */ - /* necessary. Each renderer supports a given glyph image format, and */ - /* one or more target surface depths. */ + /* A handle to a given FreeType renderer. A renderer is a module in */ + /* charge of converting a glyph's outline image to a bitmap. It */ + /* supports a single glyph image format, and one or more target */ + /* surface depths. */ /* */ typedef struct FT_RendererRec_* FT_Renderer; @@ -468,15 +467,15 @@ FT_BEGIN_HEADER /* FT_Face */ /* */ /* <Description> */ - /* A handle to a given typographic face object. A face object models */ - /* a given typeface, in a given style. */ + /* A handle to a typographic face object. A face object models a */ + /* given typeface, in a given style. */ /* */ /* <Note> */ - /* Each face object also owns a single @FT_GlyphSlot object, as well */ + /* A face object also owns a single @FT_GlyphSlot object, as well */ /* as one or more @FT_Size objects. */ /* */ /* Use @FT_New_Face or @FT_Open_Face to create a new face object from */ - /* a given filepathname or a custom input stream. */ + /* a given filepath or a custom input stream. */ /* */ /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */ /* */ @@ -501,11 +500,11 @@ FT_BEGIN_HEADER /* FT_Size */ /* */ /* <Description> */ - /* A handle to an object used to model a face scaled to a given */ + /* A handle to an object that models a face scaled to a given */ /* character size. */ /* */ /* <Note> */ - /* Each @FT_Face has an _active_ @FT_Size object that is used by */ + /* An @FT_Face has one _active_ @FT_Size object that is used by */ /* functions like @FT_Load_Glyph to determine the scaling */ /* transformation that in turn is used to load and hint glyphs and */ /* metrics. */ @@ -532,9 +531,8 @@ FT_BEGIN_HEADER /* FT_GlyphSlot */ /* */ /* <Description> */ - /* A handle to a given `glyph slot'. A slot is a container where it */ - /* is possible to load any of the glyphs contained in its parent */ - /* face. */ + /* A handle to a given `glyph slot'. A slot is a container that can */ + /* hold any of the glyphs contained in its parent face. */ /* */ /* In other words, each time you call @FT_Load_Glyph or */ /* @FT_Load_Char, the slot's content is erased by the new glyph data, */ @@ -553,13 +551,14 @@ FT_BEGIN_HEADER /* FT_CharMap */ /* */ /* <Description> */ - /* A handle to a given character map. A charmap is used to translate */ - /* character codes in a given encoding into glyph indexes for its */ - /* parent's face. Some font formats may provide several charmaps per */ - /* font. */ + /* A handle to a character map (usually abbreviated to `charmap'). A */ + /* charmap is used to translate character codes in a given encoding */ + /* into glyph indexes for its parent's face. Some font formats may */ + /* provide several charmaps per font. */ /* */ /* Each face object owns zero or more charmaps, but only one of them */ - /* can be `active' and used by @FT_Get_Char_Index or @FT_Load_Char. */ + /* can be `active', providing the data used by @FT_Get_Char_Index or */ + /* @FT_Load_Char. */ /* */ /* The list of available charmaps in a face is available through the */ /* `face->num_charmaps' and `face->charmaps' fields of @FT_FaceRec. */ @@ -616,8 +615,8 @@ FT_BEGIN_HEADER /* FT_Encoding */ /* */ /* <Description> */ - /* An enumeration used to specify character sets supported by */ - /* charmaps. Used in the @FT_Select_Charmap API function. */ + /* An enumeration to specify character sets supported by charmaps. */ + /* Used in the @FT_Select_Charmap API function. */ /* */ /* <Note> */ /* Despite the name, this enumeration lists specific character */ @@ -631,18 +630,17 @@ FT_BEGIN_HEADER /* The encoding value~0 is reserved. */ /* */ /* FT_ENCODING_UNICODE :: */ - /* Corresponds to the Unicode character set. This value covers */ - /* all versions of the Unicode repertoire, including ASCII and */ - /* Latin-1. Most fonts include a Unicode charmap, but not all */ - /* of them. */ + /* The Unicode character set. This value covers all versions of */ + /* the Unicode repertoire, including ASCII and Latin-1. Most fonts */ + /* include a Unicode charmap, but not all of them. */ /* */ /* For example, if you want to access Unicode value U+1F028 (and */ /* the font contains it), use value 0x1F028 as the input value for */ /* @FT_Get_Char_Index. */ /* */ /* FT_ENCODING_MS_SYMBOL :: */ - /* Corresponds to the Microsoft Symbol encoding, used to encode */ - /* mathematical symbols and wingdings. For more information, see */ + /* Microsoft Symbol encoding, used to encode mathematical symbols */ + /* and wingdings. For more information, see */ /* `http://www.microsoft.com/typography/otspec/recom.htm', */ /* `http://www.kostis.net/charsets/symbol.htm', and */ /* `http://www.kostis.net/charsets/wingding.htm'. */ @@ -651,12 +649,12 @@ FT_BEGIN_HEADER /* Area) in the range U+F020-U+F0FF. */ /* */ /* FT_ENCODING_SJIS :: */ - /* Corresponds to Japanese SJIS encoding. More info at */ - /* at `http://en.wikipedia.org/wiki/Shift_JIS'. */ - /* See note on multi-byte encodings below. */ + /* Shift JIS encoding for Japanese. More info at */ + /* `http://en.wikipedia.org/wiki/Shift_JIS'. See note on */ + /* multi-byte encodings below. */ /* */ /* FT_ENCODING_GB2312 :: */ - /* Corresponds to an encoding system for Simplified Chinese as used */ + /* Corresponds to an encoding system for Simplified Chinese as */ /* used in mainland China. */ /* */ /* FT_ENCODING_BIG5 :: */ @@ -664,9 +662,10 @@ FT_BEGIN_HEADER /* used in Taiwan and Hong Kong. */ /* */ /* FT_ENCODING_WANSUNG :: */ - /* Corresponds to the Korean encoding system known as Wansung. */ + /* Corresponds to the Korean encoding system known as Extended */ + /* Wansung (MS Windows code page 949). */ /* For more information see */ - /* `https://msdn.microsoft.com/en-US/goglobal/cc305154'. */ + /* `http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/bestfit949.txt'. */ /* */ /* FT_ENCODING_JOHAB :: */ /* The Korean standard character set (KS~C 5601-1992), which */ @@ -678,26 +677,24 @@ FT_BEGIN_HEADER /* PostScript font. It is limited to 256 character codes. */ /* */ /* FT_ENCODING_ADOBE_STANDARD :: */ - /* Corresponds to the Adobe Standard encoding, as found in Type~1, */ - /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ - /* codes. */ + /* Adobe Standard encoding, as found in Type~1, CFF, and */ + /* OpenType/CFF fonts. It is limited to 256 character codes. */ /* */ /* FT_ENCODING_ADOBE_EXPERT :: */ - /* Corresponds to the Adobe Expert encoding, as found in Type~1, */ - /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ - /* codes. */ + /* Adobe Expert encoding, as found in Type~1, CFF, and OpenType/CFF */ + /* fonts. It is limited to 256 character codes. */ /* */ /* FT_ENCODING_ADOBE_CUSTOM :: */ /* Corresponds to a custom encoding, as found in Type~1, CFF, and */ /* OpenType/CFF fonts. It is limited to 256 character codes. */ /* */ /* FT_ENCODING_APPLE_ROMAN :: */ - /* Corresponds to the 8-bit Apple roman encoding. Many TrueType */ - /* and OpenType fonts contain a charmap for this encoding, since */ - /* older versions of Mac OS are able to use it. */ + /* Apple roman encoding. Many TrueType and OpenType fonts contain */ + /* a charmap for this 8-bit encoding, since older versions of Mac */ + /* OS are able to use it. */ /* */ /* FT_ENCODING_OLD_LATIN_2 :: */ - /* This value is deprecated and was never used nor reported by */ + /* This value is deprecated and was neither used nor reported by */ /* FreeType. Don't use or test for it. */ /* */ /* FT_ENCODING_MS_SJIS :: */ @@ -717,7 +714,7 @@ FT_BEGIN_HEADER /* */ /* <Note> */ /* By default, FreeType automatically synthesizes a Unicode charmap */ - /* for PostScript fonts, using their glyph names dictionaries. */ + /* for PostScript fonts, using their glyph name dictionaries. */ /* However, it also reports the encodings defined explicitly in the */ /* font file, for the cases when they are needed, with the Adobe */ /* values as well. */ @@ -821,11 +818,11 @@ FT_BEGIN_HEADER /* */ /* platform_id :: An ID number describing the platform for the */ /* following encoding ID. This comes directly from */ - /* the TrueType specification and should be emulated */ + /* the TrueType specification gets emulated */ /* for other formats. */ /* */ /* encoding_id :: A platform specific encoding number. This also */ - /* comes from the TrueType specification and should be */ + /* comes from the TrueType specification and gets */ /* emulated similarly. */ /* */ typedef struct FT_CharMapRec_ @@ -853,8 +850,8 @@ FT_BEGIN_HEADER /* FT_Face_Internal */ /* */ /* <Description> */ - /* An opaque handle to an `FT_Face_InternalRec' structure, used to */ - /* model private data of a given @FT_Face object. */ + /* An opaque handle to an `FT_Face_InternalRec' structure that models */ + /* the private data of a given @FT_Face object. */ /* */ /* This structure might change between releases of FreeType~2 and is */ /* not generally available to client applications. */ @@ -874,7 +871,7 @@ FT_BEGIN_HEADER /* <Fields> */ /* num_faces :: The number of faces in the font file. Some */ /* font formats can have multiple faces in */ - /* a font file. */ + /* a single font file. */ /* */ /* face_index :: This field holds two different values. */ /* Bits 0-15 are the index of the face in the */ @@ -882,14 +879,15 @@ FT_BEGIN_HEADER /* are set to~0 if there is only one face in */ /* the font file. */ /* */ - /* Bits 16-30 are relevant to GX variation */ - /* fonts only, holding the named instance */ - /* index for the current face index (starting */ - /* with value~1; value~0 indicates font access */ - /* without GX variation data). For non-GX */ - /* fonts, bits 16-30 are ignored. If we have */ - /* the third named instance of face~4, say, */ - /* `face_index' is set to 0x00030004. */ + /* Bits 16-30 are relevant to GX and OpenType */ + /* variation fonts only, holding the named */ + /* instance index for the current face index */ + /* (starting with value~1; value~0 indicates */ + /* font access without variation data). For */ + /* non-variation fonts, bits 16-30 are */ + /* ignored. If we have the third named */ + /* instance of face~4, say, `face_index' is */ + /* set to 0x00030004. */ /* */ /* Bit 31 is always zero (this is, */ /* `face_index' is always a positive value). */ @@ -903,17 +901,18 @@ FT_BEGIN_HEADER /* @FT_STYLE_FLAG_XXX for the details. Bits */ /* 16-30 hold the number of named instances */ /* available for the current face if we have a */ - /* GX variation (sub)font. Bit 31 is always */ - /* zero (this is, `style_flags' is always a */ - /* positive value). */ + /* GX or OpenType variation (sub)font. Bit 31 */ + /* is always zero (this is, `style_flags' is */ + /* always a positive value). */ /* */ /* num_glyphs :: The number of glyphs in the face. If the */ /* face is scalable and has sbits (see */ /* `num_fixed_sizes'), it is set to the number */ /* of outline glyphs. */ /* */ - /* For CID-keyed fonts, this value gives the */ - /* highest CID used in the font. */ + /* For CID-keyed fonts (not in an SFNT */ + /* wrapper) this value gives the highest CID */ + /* used in the font. */ /* */ /* family_name :: The face's family name. This is an ASCII */ /* string, usually in English, that describes */ @@ -952,6 +951,10 @@ FT_BEGIN_HEADER /* strikes in the face. It is set to NULL if */ /* there is no bitmap strike. */ /* */ + /* Note that FreeType tries to sanitize the */ + /* strike data since they are sometimes sloppy */ + /* or incorrect, but this can easily fail. */ + /* */ /* num_charmaps :: The number of charmaps in the face. */ /* */ /* charmaps :: An array of the charmaps of the face. */ @@ -987,8 +990,8 @@ FT_BEGIN_HEADER /* expressed in font units. For font formats */ /* not having this information, it is set to */ /* `bbox.yMin'. Note that this field is */ - /* usually negative. Only relevant for */ - /* scalable formats. */ + /* negative for values below the baseline. */ + /* Only relevant for scalable formats. */ /* */ /* height :: This value is the vertical distance */ /* between two consecutive baselines, */ @@ -1031,6 +1034,12 @@ FT_BEGIN_HEADER /* Fields may be changed after a call to @FT_Attach_File or */ /* @FT_Attach_Stream. */ /* */ + /* For an OpenType variation font, the values of the following fields */ + /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ + /* friends) if the font contains an `MVAR' table: `ascender', */ + /* `descender', `height', `underline_position', and */ + /* `underline_thickness'. */ + /* */ typedef struct FT_FaceRec_ { FT_Long num_faces; @@ -1102,49 +1111,51 @@ FT_BEGIN_HEADER /* */ /* <Values> */ /* FT_FACE_FLAG_SCALABLE :: */ - /* Indicates that the face contains outline glyphs. This doesn't */ - /* prevent bitmap strikes, i.e., a face can have both this and */ - /* and @FT_FACE_FLAG_FIXED_SIZES set. */ + /* The face contains outline glyphs. Note that a face can contain */ + /* bitmap strikes also, i.e., a face can have both this flag and */ + /* @FT_FACE_FLAG_FIXED_SIZES set. */ /* */ /* FT_FACE_FLAG_FIXED_SIZES :: */ - /* Indicates that the face contains bitmap strikes. See also the */ + /* The face contains bitmap strikes. See also the */ /* `num_fixed_sizes' and `available_sizes' fields of @FT_FaceRec. */ /* */ /* FT_FACE_FLAG_FIXED_WIDTH :: */ - /* Indicates that the face contains fixed-width characters (like */ - /* Courier, Lucido, MonoType, etc.). */ + /* The face contains fixed-width characters (like Courier, Lucido, */ + /* MonoType, etc.). */ /* */ /* FT_FACE_FLAG_SFNT :: */ - /* Indicates that the face uses the `sfnt' storage scheme. For */ - /* now, this means TrueType and OpenType. */ + /* The face uses the SFNT storage scheme. For now, this means */ + /* TrueType and OpenType. */ /* */ /* FT_FACE_FLAG_HORIZONTAL :: */ - /* Indicates that the face contains horizontal glyph metrics. This */ - /* should be set for all common formats. */ + /* The face contains horizontal glyph metrics. This should be set */ + /* for all common formats. */ /* */ /* FT_FACE_FLAG_VERTICAL :: */ - /* Indicates that the face contains vertical glyph metrics. This */ - /* is only available in some formats, not all of them. */ + /* The face contains vertical glyph metrics. This is only */ + /* available in some formats, not all of them. */ /* */ /* FT_FACE_FLAG_KERNING :: */ - /* Indicates that the face contains kerning information. If set, */ - /* the kerning distance can be retrieved through the function */ - /* @FT_Get_Kerning. Otherwise the function always return the */ - /* vector (0,0). Note that FreeType doesn't handle kerning data */ - /* from the `GPOS' table (as present in some OpenType fonts). */ + /* The face contains kerning information. If set, the kerning */ + /* distance can be retrieved using the function @FT_Get_Kerning. */ + /* Otherwise the function always return the vector (0,0). Note */ + /* that FreeType doesn't handle kerning data from the SFNT `GPOS' */ + /* table (as present in many OpenType fonts). */ /* */ /* FT_FACE_FLAG_FAST_GLYPHS :: */ /* THIS FLAG IS DEPRECATED. DO NOT USE OR TEST IT. */ /* */ /* FT_FACE_FLAG_MULTIPLE_MASTERS :: */ - /* Indicates that the font contains multiple masters and is capable */ - /* of interpolating between them. See the multiple-masters */ - /* specific API for details. */ + /* The face contains multiple masters and is capable of */ + /* interpolating between them. Supported formats are Adobe MM, */ + /* TrueType GX, and OpenType variation fonts. */ + /* */ + /* See the multiple-masters specific API for details. */ /* */ /* FT_FACE_FLAG_GLYPH_NAMES :: */ - /* Indicates that the font contains glyph names that can be */ - /* retrieved through @FT_Get_Glyph_Name. Note that some TrueType */ - /* fonts contain broken glyph name tables. Use the function */ + /* The face contains glyph names, which can be retrieved using */ + /* @FT_Get_Glyph_Name. Note that some TrueType fonts contain */ + /* broken glyph name tables. Use the function */ /* @FT_Has_PS_Glyph_Names when needed. */ /* */ /* FT_FACE_FLAG_EXTERNAL_STREAM :: */ @@ -1153,31 +1164,31 @@ FT_BEGIN_HEADER /* when @FT_Done_Face is called. Don't read or test this flag. */ /* */ /* FT_FACE_FLAG_HINTER :: */ - /* Set if the font driver has a hinting machine of its own. For */ - /* example, with TrueType fonts, it makes sense to use data from */ - /* the SFNT `gasp' table only if the native TrueType hinting engine */ - /* (with the bytecode interpreter) is available and active. */ + /* The font driver has a hinting machine of its own. For example, */ + /* with TrueType fonts, it makes sense to use data from the SFNT */ + /* `gasp' table only if the native TrueType hinting engine (with */ + /* the bytecode interpreter) is available and active. */ /* */ /* FT_FACE_FLAG_CID_KEYED :: */ - /* Set if the font is CID-keyed. In that case, the font is not */ - /* accessed by glyph indices but by CID values. For subsetted */ - /* CID-keyed fonts this has the consequence that not all index */ - /* values are a valid argument to FT_Load_Glyph. Only the CID */ - /* values for which corresponding glyphs in the subsetted font */ - /* exist make FT_Load_Glyph return successfully; in all other cases */ - /* you get an `FT_Err_Invalid_Argument' error. */ - /* */ - /* Note that CID-keyed fonts that are in an SFNT wrapper don't */ - /* have this flag set since the glyphs are accessed in the normal */ - /* way (using contiguous indices); the `CID-ness' isn't visible to */ - /* the application. */ + /* The face is CID-keyed. In that case, the face is not accessed */ + /* by glyph indices but by CID values. For subsetted CID-keyed */ + /* fonts this has the consequence that not all index values are a */ + /* valid argument to @FT_Load_Glyph. Only the CID values for which */ + /* corresponding glyphs in the subsetted font exist make */ + /* `FT_Load_Glyph' return successfully; in all other cases you get */ + /* an `FT_Err_Invalid_Argument' error. */ + /* */ + /* Note that CID-keyed fonts that are in an SFNT wrapper (this is, */ + /* all OpenType/CFF fonts) don't have this flag set since the */ + /* glyphs are accessed in the normal way (using contiguous */ + /* indices); the `CID-ness' isn't visible to the application. */ /* */ /* FT_FACE_FLAG_TRICKY :: */ - /* Set if the font is `tricky', this is, it always needs the */ - /* font format's native hinting engine to get a reasonable result. */ - /* A typical example is the Chinese font `mingli.ttf' that uses */ - /* TrueType bytecode instructions to move and scale all of its */ - /* subglyphs. */ + /* The face is `tricky', this is, it always needs the font format's */ + /* native hinting engine to get a reasonable result. A typical */ + /* example is the old Chinese font `mingli.ttf' (but not */ + /* `mingliu.ttc') that uses TrueType bytecode instructions to move */ + /* and scale all of its subglyphs. */ /* */ /* It is not possible to auto-hint such fonts using */ /* @FT_LOAD_FORCE_AUTOHINT; it will also ignore */ @@ -1189,8 +1200,8 @@ FT_BEGIN_HEADER /* tricky fonts; they are hard-coded in file `ttobjs.c'. */ /* */ /* FT_FACE_FLAG_COLOR :: */ - /* Set if the font has color glyph tables. To access color glyphs */ - /* use @FT_LOAD_COLOR. */ + /* The face has color glyph tables. To access color glyphs use */ + /* @FT_LOAD_COLOR. */ /* */ #define FT_FACE_FLAG_SCALABLE ( 1L << 0 ) #define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 ) @@ -1223,7 +1234,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_HORIZONTAL( face ) \ - ( face->face_flags & FT_FACE_FLAG_HORIZONTAL ) + ( (face)->face_flags & FT_FACE_FLAG_HORIZONTAL ) /************************************************************************* @@ -1237,7 +1248,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_VERTICAL( face ) \ - ( face->face_flags & FT_FACE_FLAG_VERTICAL ) + ( (face)->face_flags & FT_FACE_FLAG_VERTICAL ) /************************************************************************* @@ -1251,7 +1262,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_KERNING( face ) \ - ( face->face_flags & FT_FACE_FLAG_KERNING ) + ( (face)->face_flags & FT_FACE_FLAG_KERNING ) /************************************************************************* @@ -1262,11 +1273,11 @@ FT_BEGIN_HEADER * @description: * A macro that returns true whenever a face object contains a scalable * font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF, - * and PFR font formats. + * and PFR font formats). * */ #define FT_IS_SCALABLE( face ) \ - ( face->face_flags & FT_FACE_FLAG_SCALABLE ) + ( (face)->face_flags & FT_FACE_FLAG_SCALABLE ) /************************************************************************* @@ -1285,7 +1296,7 @@ FT_BEGIN_HEADER * */ #define FT_IS_SFNT( face ) \ - ( face->face_flags & FT_FACE_FLAG_SFNT ) + ( (face)->face_flags & FT_FACE_FLAG_SFNT ) /************************************************************************* @@ -1300,7 +1311,7 @@ FT_BEGIN_HEADER * */ #define FT_IS_FIXED_WIDTH( face ) \ - ( face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) + ( (face)->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) /************************************************************************* @@ -1315,7 +1326,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_FIXED_SIZES( face ) \ - ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) + ( (face)->face_flags & FT_FACE_FLAG_FIXED_SIZES ) /************************************************************************* @@ -1341,7 +1352,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_GLYPH_NAMES( face ) \ - ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) + ( (face)->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) /************************************************************************* @@ -1356,7 +1367,21 @@ FT_BEGIN_HEADER * */ #define FT_HAS_MULTIPLE_MASTERS( face ) \ - ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) + ( (face)->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) + + + /************************************************************************* + * + * @macro: + * FT_IS_NAMED_INSTANCE( face ) + * + * @description: + * A macro that returns true whenever a face object is a named instance + * of a GX or OpenType variation font. + * + */ +#define FT_IS_NAMED_INSTANCE( face ) \ + ( (face)->face_index & 0x7FFF0000L ) /************************************************************************* @@ -1374,7 +1399,7 @@ FT_BEGIN_HEADER * */ #define FT_IS_CID_KEYED( face ) \ - ( face->face_flags & FT_FACE_FLAG_CID_KEYED ) + ( (face)->face_flags & FT_FACE_FLAG_CID_KEYED ) /************************************************************************* @@ -1388,7 +1413,7 @@ FT_BEGIN_HEADER * */ #define FT_IS_TRICKY( face ) \ - ( face->face_flags & FT_FACE_FLAG_TRICKY ) + ( (face)->face_flags & FT_FACE_FLAG_TRICKY ) /************************************************************************* @@ -1402,7 +1427,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_COLOR( face ) \ - ( face->face_flags & FT_FACE_FLAG_COLOR ) + ( (face)->face_flags & FT_FACE_FLAG_COLOR ) /*************************************************************************/ @@ -1411,15 +1436,15 @@ FT_BEGIN_HEADER /* FT_STYLE_FLAG_XXX */ /* */ /* <Description> */ - /* A list of bit flags used to indicate the style of a given face. */ - /* These are used in the `style_flags' field of @FT_FaceRec. */ + /* A list of bit flags to indicate the style of a given face. These */ + /* are used in the `style_flags' field of @FT_FaceRec. */ /* */ /* <Values> */ /* FT_STYLE_FLAG_ITALIC :: */ - /* Indicates that a given face style is italic or oblique. */ + /* The face style is italic or oblique. */ /* */ /* FT_STYLE_FLAG_BOLD :: */ - /* Indicates that a given face is bold. */ + /* The face is bold. */ /* */ /* <Note> */ /* The style information as provided by FreeType is very basic. More */ @@ -1460,12 +1485,12 @@ FT_BEGIN_HEADER /* hence the term `ppem' (pixels per EM). It is also */ /* referred to as `nominal height'. */ /* */ - /* x_scale :: A 16.16 fractional scaling value used to convert */ + /* x_scale :: A 16.16 fractional scaling value to convert */ /* horizontal metrics from font units to 26.6 */ /* fractional pixels. Only relevant for scalable */ /* font formats. */ /* */ - /* y_scale :: A 16.16 fractional scaling value used to convert */ + /* y_scale :: A 16.16 fractional scaling value to convert */ /* vertical metrics from font units to 26.6 */ /* fractional pixels. Only relevant for scalable */ /* font formats. */ @@ -1496,7 +1521,7 @@ 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. */ + /* The `FT_Size_Metrics' structure is valid for bitmap fonts also. */ /* */ typedef struct FT_Size_Metrics_ { @@ -1636,8 +1661,8 @@ FT_BEGIN_HEADER /* contained in the glyph slot. Typically */ /* @FT_GLYPH_FORMAT_BITMAP, */ /* @FT_GLYPH_FORMAT_OUTLINE, or */ - /* @FT_GLYPH_FORMAT_COMPOSITE, but others are */ - /* possible. */ + /* @FT_GLYPH_FORMAT_COMPOSITE, but other values */ + /* are possible. */ /* */ /* bitmap :: This field is used as a bitmap descriptor */ /* when the slot format is */ @@ -1652,10 +1677,9 @@ FT_BEGIN_HEADER /* glyph slot contains a bitmap. */ /* */ /* bitmap_top :: The bitmap's top bearing expressed in integer */ - /* pixels. Remember that this is the distance */ - /* from the baseline to the top-most glyph */ - /* scanline, upwards y~coordinates being */ - /* *positive*. */ + /* pixels. This is the distance from the */ + /* baseline to the top-most glyph scanline, */ + /* upwards y~coordinates being *positive*. */ /* */ /* outline :: The outline descriptor for the current glyph */ /* image if its format is */ @@ -1677,15 +1701,13 @@ FT_BEGIN_HEADER /* control_data :: Certain font drivers can also return the */ /* control data for a given glyph image (e.g. */ /* TrueType bytecode, Type~1 charstrings, etc.). */ - /* This field is a pointer to such data. */ + /* This field is a pointer to such data; it is */ + /* currently internal to FreeType. */ /* */ /* control_len :: This is the length in bytes of the control */ - /* data. */ + /* data. Currently internal to FreeType. */ /* */ - /* other :: Really wicked formats can use this pointer to */ - /* present their own glyph image to client */ - /* applications. Note that the application */ - /* needs to know about the image format. */ + /* other :: Reserved. */ /* */ /* lsb_delta :: The difference between hinted and unhinted */ /* left side bearing while auto-hinting is */ @@ -1702,7 +1724,7 @@ FT_BEGIN_HEADER /* formats). */ /* */ /* This image can later be converted into a bitmap by calling */ - /* @FT_Render_Glyph. This function finds the current renderer for */ + /* @FT_Render_Glyph. This function searches the current renderer for */ /* the native image's format, then invokes it. */ /* */ /* The renderer is in charge of transforming the native image through */ @@ -1714,7 +1736,6 @@ FT_BEGIN_HEADER /* position (e.g., coordinates (0,0) on the baseline). Of course, */ /* `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP. */ /* */ - /* <Note> */ /* Here is a small pseudo code fragment that shows how to use */ /* `lsb_delta' and `rsb_delta': */ /* */ @@ -1724,8 +1745,8 @@ FT_BEGIN_HEADER /* */ /* */ /* for all glyphs do */ - /* <compute kern between current and previous glyph and add it to */ - /* `origin_x'> */ + /* <compute kern between current and previous glyph */ + /* and add it to `origin_x'> */ /* */ /* <load glyph with `FT_Load_Glyph'> */ /* */ @@ -1742,6 +1763,12 @@ FT_BEGIN_HEADER /* endfor */ /* } */ /* */ + /* If you use strong auto-hinting, you *must* apply these delta */ + /* values! Otherwise you will experience far too large inter-glyph */ + /* spacing at small rendering sizes in most cases. Note that it */ + /* doesn't harm to use the above code for other hinting modes also, */ + /* since the delta values are zero then. */ + /* */ typedef struct FT_GlyphSlotRec_ { FT_Library library; @@ -1884,7 +1911,7 @@ FT_BEGIN_HEADER /* FT_Parameter */ /* */ /* <Description> */ - /* A simple structure used to pass more or less generic parameters to */ + /* A simple structure to pass more or less generic parameters to */ /* @FT_Open_Face. */ /* */ /* <Fields> */ @@ -1910,9 +1937,9 @@ FT_BEGIN_HEADER /* FT_Open_Args */ /* */ /* <Description> */ - /* A structure used to indicate how to open a new font file or */ - /* stream. A pointer to such a structure can be used as a parameter */ - /* for the functions @FT_Open_Face and @FT_Attach_Stream. */ + /* A structure to indicate how to open a new font file or stream. A */ + /* pointer to such a structure can be used as a parameter for the */ + /* functions @FT_Open_Face and @FT_Attach_Stream. */ /* */ /* <Fields> */ /* flags :: A set of bit flags indicating how to use the */ @@ -1927,9 +1954,10 @@ FT_BEGIN_HEADER /* stream :: A handle to a source stream object. */ /* */ /* driver :: This field is exclusively used by @FT_Open_Face; */ - /* it simply specifies the font driver to use to open */ - /* the face. If set to~0, FreeType tries to load the */ - /* face with each one of the drivers in its list. */ + /* it simply specifies the font driver to use for */ + /* opening the face. If set to NULL, FreeType tries */ + /* to load the face with each one of the drivers in */ + /* its list. */ /* */ /* num_params :: The number of extra parameters. */ /* */ @@ -1942,7 +1970,7 @@ FT_BEGIN_HEADER /* */ /* If the @FT_OPEN_MEMORY bit is set, assume that this is a */ /* memory file of `memory_size' bytes, located at `memory_address'. */ - /* The data are are not copied, and the client is responsible for */ + /* The data are not copied, and the client is responsible for */ /* releasing and destroying them _after_ the corresponding call to */ /* @FT_Done_Face. */ /* */ @@ -1982,7 +2010,7 @@ FT_BEGIN_HEADER /* FT_New_Face */ /* */ /* <Description> */ - /* This function calls @FT_Open_Face to open a font by its pathname. */ + /* Call @FT_Open_Face to open a font by its pathname. */ /* */ /* <InOut> */ /* library :: A handle to the library resource. */ @@ -2017,8 +2045,8 @@ FT_BEGIN_HEADER /* FT_New_Memory_Face */ /* */ /* <Description> */ - /* This function calls @FT_Open_Face to open a font that has been */ - /* loaded into memory. */ + /* Call @FT_Open_Face to open a font that has been loaded into */ + /* memory. */ /* */ /* <InOut> */ /* library :: A handle to the library resource. */ @@ -2070,20 +2098,21 @@ FT_BEGIN_HEADER /* with value~0). Set it to~0 if there is only one */ /* face in the font file. */ /* */ - /* Bits 16-30 are relevant to GX variation fonts only, */ - /* specifying the named instance index for the current */ - /* face index (starting with value~1; value~0 makes */ - /* FreeType ignore named instances). For non-GX fonts, */ - /* bits 16-30 are ignored. Assuming that you want to */ - /* access the third named instance in face~4, */ - /* `face_index' should be set to 0x00030004. If you */ - /* want to access face~4 without GX variation handling, */ - /* simply set `face_index' to value~4. */ - /* */ - /* FT_Open_Face and its siblings can be used to quickly */ - /* check whether the font format of a given font */ - /* resource is supported by FreeType. In general, if */ - /* the `face_index' argument is negative, the */ + /* Bits 16-30 are relevant to GX and OpenType variation */ + /* fonts only, specifying the named instance index for */ + /* the current face index (starting with value~1; */ + /* value~0 makes FreeType ignore named instances). For */ + /* non-variation fonts, bits 16-30 are ignored. */ + /* Assuming that you want to access the third named */ + /* instance in face~4, `face_index' should be set to */ + /* 0x00030004. If you want to access face~4 without */ + /* variation handling, simply set `face_index' to */ + /* value~4. */ + /* */ + /* `FT_Open_Face' and its siblings can be used to */ + /* quickly check whether the font format of a given */ + /* font resource is supported by FreeType. In general, */ + /* if the `face_index' argument is negative, the */ /* function's return value is~0 if the font format is */ /* recognized, or non-zero otherwise. The function */ /* allocates a more or less empty face handle in */ @@ -2092,10 +2121,10 @@ FT_BEGIN_HEADER /* `face->num_faces' and `face->style_flags'. For any */ /* negative value of `face_index', `face->num_faces' */ /* gives the number of faces within the font file. For */ - /* the negative value `-(N+1)' (with `N' a 16-bit */ - /* value), bits 16-30 in `face->style_flags' give the */ - /* number of named instances in face `N' if we have a */ - /* GX variation font (or zero otherwise). After */ + /* the negative value `-(N+1)' (with `N' a non-negative */ + /* 16-bit value), bits 16-30 in `face->style_flags' */ + /* give the number of named instances in face `N' if we */ + /* have a variation font (or zero otherwise). After */ /* examination, the returned @FT_Face structure should */ /* be deallocated with a call to @FT_Done_Face. */ /* */ @@ -2202,7 +2231,7 @@ FT_BEGIN_HEADER /* FT_Attach_File */ /* */ /* <Description> */ - /* This function calls @FT_Attach_Stream to attach a file. */ + /* Call @FT_Attach_Stream to attach a file. */ /* */ /* <InOut> */ /* face :: The target face object. */ @@ -2246,7 +2275,7 @@ FT_BEGIN_HEADER /* */ /* Client applications are expected to know what they are doing */ /* when invoking this function. Most drivers simply do not implement */ - /* file attachments. */ + /* file or stream attachments. */ /* */ FT_EXPORT( FT_Error ) FT_Attach_Stream( FT_Face face, @@ -2309,7 +2338,10 @@ FT_BEGIN_HEADER /* FT_Select_Size */ /* */ /* <Description> */ - /* Select a bitmap strike. */ + /* Select a bitmap strike. To be more precise, this function sets */ + /* the scaling factors of the active @FT_Size object in a face so */ + /* that bitmaps from this particular strike are taken by */ + /* @FT_Load_Glyph and friends. */ /* */ /* <InOut> */ /* face :: A handle to a target face object. */ @@ -2321,6 +2353,20 @@ FT_BEGIN_HEADER /* <Return> */ /* FreeType error code. 0~means success. */ /* */ + /* <Note> */ + /* For bitmaps embedded in outline fonts it is common that only a */ + /* subset of the available glyphs at a given ppem value is available. */ + /* FreeType silently uses outlines if there is no bitmap for a given */ + /* glyph index. */ + /* */ + /* For GX and OpenType variation fonts, a bitmap strike makes sense */ + /* only if the default instance is active (this is, no glyph */ + /* variation takes place); otherwise, FreeType simply ignores bitmap */ + /* strikes. The same is true for all named instances that are */ + /* different from the default instance. */ + /* */ + /* Don't use this function if you are using the FreeType cache API. */ + /* */ FT_EXPORT( FT_Error ) FT_Select_Size( FT_Face face, FT_Int strike_index ); @@ -2332,17 +2378,26 @@ FT_BEGIN_HEADER /* FT_Size_Request_Type */ /* */ /* <Description> */ - /* An enumeration type that lists the supported size request types. */ + /* An enumeration type that lists the supported size request types, */ + /* i.e., what input size (in font units) maps to the requested output */ + /* size (in pixels, as computed from the arguments of */ + /* @FT_Size_Request). */ /* */ /* <Values> */ /* FT_SIZE_REQUEST_TYPE_NOMINAL :: */ /* The nominal size. The `units_per_EM' field of @FT_FaceRec is */ /* used to determine both scaling values. */ /* */ + /* This is the standard scaling found in most applications. In */ + /* particular, use this size request type for TrueType fonts if */ + /* they provide optical scaling or something similar. Note, */ + /* however, that `units_per_EM' is a rather abstract value which */ + /* bears no relation to the actual size of the glyphs in a font. */ + /* */ /* FT_SIZE_REQUEST_TYPE_REAL_DIM :: */ - /* The real dimension. The sum of the the `ascender' and (minus */ - /* of) the `descender' fields of @FT_FaceRec are used to determine */ - /* both scaling values. */ + /* The real dimension. The sum of the `ascender' and (minus of) */ + /* the `descender' fields of @FT_FaceRec is used to determine both */ + /* scaling values. */ /* */ /* FT_SIZE_REQUEST_TYPE_BBOX :: */ /* The font bounding box. The width and height of the `bbox' field */ @@ -2387,27 +2442,36 @@ FT_BEGIN_HEADER /* FT_Size_RequestRec */ /* */ /* <Description> */ - /* A structure used to model a size request. */ + /* A structure to model a size request. */ /* */ /* <Fields> */ /* type :: See @FT_Size_Request_Type. */ /* */ - /* width :: The desired width. */ + /* width :: The desired width, given as a 26.6 fractional */ + /* point value (with 72pt = 1in). */ /* */ - /* height :: The desired height. */ + /* height :: The desired height, given as a 26.6 fractional */ + /* point value (with 72pt = 1in). */ /* */ - /* horiResolution :: The horizontal resolution. If set to zero, */ - /* `width' is treated as a 26.6 fractional pixel */ - /* value. */ + /* horiResolution :: The horizontal resolution (dpi, i.e., pixels per */ + /* inch). If set to zero, `width' is treated as a */ + /* 26.6 fractional *pixel* value, which gets */ + /* internally rounded to an integer. */ /* */ - /* vertResolution :: The vertical resolution. If set to zero, */ - /* `height' is treated as a 26.6 fractional pixel */ - /* value. */ + /* vertResolution :: The vertical resolution (dpi, i.e., pixels per */ + /* inch). If set to zero, `height' is treated as a */ + /* 26.6 fractional *pixel* value, which gets */ + /* internally rounded to an integer. */ /* */ /* <Note> */ - /* If `width' is zero, then the horizontal scaling value is set equal */ + /* If `width' is zero, the horizontal scaling value is set equal */ /* to the vertical scaling value, and vice versa. */ /* */ + /* If `type' is FT_SIZE_REQUEST_TYPE_SCALES, `width' and `height' are */ + /* interpreted directly as 16.16 fractional scaling values, without */ + /* any further modification, and both `horiResolution' and */ + /* `vertResolution' are ignored. */ + /* */ typedef struct FT_Size_RequestRec_ { FT_Size_Request_Type type; @@ -2457,7 +2521,7 @@ FT_BEGIN_HEADER /* size is dependent entirely on how the size is defined in the */ /* source face. The font designer chooses the final size of each */ /* glyph relative to this size. For more information refer to */ - /* `http://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html' */ + /* `https://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html'. */ /* */ /* Don't use this function if you are using the FreeType cache API. */ /* */ @@ -2472,8 +2536,7 @@ FT_BEGIN_HEADER /* FT_Set_Char_Size */ /* */ /* <Description> */ - /* This function calls @FT_Request_Size to request the nominal size */ - /* (in points). */ + /* Call @FT_Request_Size to request the nominal size (in points). */ /* */ /* <InOut> */ /* face :: A handle to a target face object. */ @@ -2491,6 +2554,10 @@ FT_BEGIN_HEADER /* FreeType error code. 0~means success. */ /* */ /* <Note> */ + /* While this function allows fractional points as input values, the */ + /* resulting ppem value for the given resolution is always rounded to */ + /* the nearest integer. */ + /* */ /* If either the character width or height is zero, it is set equal */ /* to the other value. */ /* */ @@ -2516,8 +2583,7 @@ FT_BEGIN_HEADER /* FT_Set_Pixel_Sizes */ /* */ /* <Description> */ - /* This function calls @FT_Request_Size to request the nominal size */ - /* (in pixels). */ + /* Call @FT_Request_Size to request the nominal size (in pixels). */ /* */ /* <InOut> */ /* face :: A handle to the target face object. */ @@ -2531,8 +2597,8 @@ FT_BEGIN_HEADER /* FreeType error code. 0~means success. */ /* */ /* <Note> */ - /* You should not rely on the resulting glyphs matching, or being */ - /* constrained, to this pixel size. Refer to @FT_Request_Size to */ + /* You should not rely on the resulting glyphs matching or being */ + /* constrained to this pixel size. Refer to @FT_Request_Size to */ /* understand how requested sizes relate to actual sizes. */ /* */ /* Don't use this function if you are using the FreeType cache API. */ @@ -2549,8 +2615,7 @@ FT_BEGIN_HEADER /* FT_Load_Glyph */ /* */ /* <Description> */ - /* A function used to load a single glyph into the glyph slot of a */ - /* face object. */ + /* Load a glyph into the glyph slot of a face object. */ /* */ /* <InOut> */ /* face :: A handle to the target face object where the glyph */ @@ -2579,6 +2644,10 @@ FT_BEGIN_HEADER /* don't have a corresponding glyph in the font). See the discussion */ /* of the @FT_FACE_FLAG_CID_KEYED flag for more details. */ /* */ + /* If you receive `FT_Err_Glyph_Too_Big', try getting the glyph */ + /* outline at EM size, then scale it manually and fill it as a */ + /* graphics operation. */ + /* */ FT_EXPORT( FT_Error ) FT_Load_Glyph( FT_Face face, FT_UInt glyph_index, @@ -2591,8 +2660,8 @@ FT_BEGIN_HEADER /* FT_Load_Char */ /* */ /* <Description> */ - /* A function used to load a single glyph into the glyph slot of a */ - /* face object, according to its character code. */ + /* Load a glyph into the glyph slot of a face object, accessed by its */ + /* character code. */ /* */ /* <InOut> */ /* face :: A handle to a target face object where the glyph */ @@ -2614,6 +2683,10 @@ FT_BEGIN_HEADER /* <Note> */ /* This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph. */ /* */ + /* Many fonts contain glyphs that can't be loaded by this function */ + /* since its glyph indices are not listed in any of the font's */ + /* charmaps. */ + /* */ FT_EXPORT( FT_Error ) FT_Load_Char( FT_Face face, FT_ULong char_code, @@ -2626,8 +2699,8 @@ FT_BEGIN_HEADER * FT_LOAD_XXX * * @description: - * A list of bit field constants used with @FT_Load_Glyph to indicate - * what kind of operations to perform during glyph loading. + * A list of bit field constants for @FT_Load_Glyph to indicate what + * kind of operations to perform during glyph loading. * * @values: * FT_LOAD_DEFAULT :: @@ -2639,13 +2712,13 @@ FT_BEGIN_HEADER * The bitmap data can be accessed from the glyph slot (see note * below). * - * 2. If no embedded bitmap is searched or found, FreeType looks for a - * scalable outline. If one is found, it is loaded from the font - * file, scaled to device pixels, then `hinted' to the pixel grid - * in order to optimize it. The outline data can be accessed from - * the glyph slot (see note below). + * 2. If no embedded bitmap is searched for or found, FreeType looks + * for a scalable outline. If one is found, it is loaded from + * the font file, scaled to device pixels, then `hinted' to the + * pixel grid in order to optimize it. The outline data can be + * accessed from the glyph slot (see note below). * - * Note that by default, the glyph loader doesn't render outlines into + * Note that by default the glyph loader doesn't render outlines into * bitmaps. The following flags are used to modify this default * behaviour to more specific and useful cases. * @@ -2692,13 +2765,13 @@ FT_BEGIN_HEADER * various font formats. * * FT_LOAD_FORCE_AUTOHINT :: - * Indicates that the auto-hinter is preferred over the font's native - * hinter. See also the note below. + * Prefer the auto-hinter over the font's native hinter. See also + * the note below. * * FT_LOAD_PEDANTIC :: - * Indicates that the font driver should perform pedantic verifications - * during glyph loading. This is mostly used to detect broken glyphs - * in fonts. By default, FreeType tries to handle broken fonts also. + * Make the font driver perform pedantic verifications during glyph + * loading. This is mostly used to detect broken glyphs in fonts. + * By default, FreeType tries to handle broken fonts also. * * In particular, errors from the TrueType bytecode engine are not * passed to the application if this flag is not set; this might @@ -2706,17 +2779,16 @@ FT_BEGIN_HEADER * bytecode is buggy. * * FT_LOAD_NO_RECURSE :: - * Indicate that the font driver should not load composite glyphs - * recursively. Instead, it should set the `num_subglyph' and - * `subglyphs' values of the glyph slot accordingly, and set - * `glyph->format' to @FT_GLYPH_FORMAT_COMPOSITE. The description of - * subglyphs can then be accessed with @FT_Get_SubGlyph_Info. + * Don't load composite glyphs recursively. Instead, the font + * driver should set the `num_subglyph' and `subglyphs' values of + * the glyph slot accordingly, and set `glyph->format' to + * @FT_GLYPH_FORMAT_COMPOSITE. The description of subglyphs can + * then be accessed with @FT_Get_SubGlyph_Info. * * This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM. * * FT_LOAD_IGNORE_TRANSFORM :: - * Indicates that the transform matrix set by @FT_Set_Transform should - * be ignored. + * Ignore the transform matrix set by @FT_Set_Transform. * * FT_LOAD_MONOCHROME :: * This flag is used with @FT_LOAD_RENDER to indicate that you want to @@ -2728,31 +2800,37 @@ FT_BEGIN_HEADER * monochrome-optimized hinting algorithm is used. * * FT_LOAD_LINEAR_DESIGN :: - * Indicates that the `linearHoriAdvance' and `linearVertAdvance' - * fields of @FT_GlyphSlotRec should be kept in font units. See - * @FT_GlyphSlotRec for details. + * Keep `linearHoriAdvance' and `linearVertAdvance' fields of + * @FT_GlyphSlotRec in font units. See @FT_GlyphSlotRec for + * details. * * FT_LOAD_NO_AUTOHINT :: - * Disable auto-hinter. See also the note below. + * Disable the auto-hinter. See also the note below. * * FT_LOAD_COLOR :: - * This flag is used to request loading of color embedded-bitmap - * images. The resulting color bitmaps, if available, will have the - * @FT_PIXEL_MODE_BGRA format. When the flag is not used and color - * bitmaps are found, they will be converted to 256-level gray - * bitmaps transparently. Those bitmaps will be in the + * Load embedded color bitmap images. The resulting color bitmaps, + * if available, will have the @FT_PIXEL_MODE_BGRA format. If the + * flag is not set and color bitmaps are found, they are converted + * to 256-level gray bitmaps transparently, using the * @FT_PIXEL_MODE_GRAY format. * * FT_LOAD_COMPUTE_METRICS :: - * This flag sets computing glyph metrics without the use of bundled - * metrics tables (for example, the `hdmx' table in TrueType fonts). - * Well-behaving fonts have optimized bundled metrics and these should - * be used. This flag is mainly used by font validating or font + * Compute glyph metrics from the glyph data, without the use of + * bundled metrics tables (for example, the `hdmx' table in TrueType + * fonts). This flag is mainly used by font validating or font * editing applications, which need to ignore, verify, or edit those * tables. * * Currently, this flag is only implemented for TrueType fonts. * + * FT_LOAD_BITMAP_METRICS_ONLY :: + * Request loading of the metrics and bitmap image information of a + * (possibly embedded) bitmap glyph without allocating or copying + * the bitmap image data itself. No effect if the target glyph is + * not a bitmap image. + * + * This flag unsets @FT_LOAD_RENDER. + * * FT_LOAD_CROP_BITMAP :: * Ignored. Deprecated. * @@ -2796,13 +2874,14 @@ FT_BEGIN_HEADER #define FT_LOAD_MONOCHROME ( 1L << 12 ) #define FT_LOAD_LINEAR_DESIGN ( 1L << 13 ) #define FT_LOAD_NO_AUTOHINT ( 1L << 15 ) - /* Bits 16..19 are used by `FT_LOAD_TARGET_' */ + /* Bits 16-19 are used by `FT_LOAD_TARGET_' */ #define FT_LOAD_COLOR ( 1L << 20 ) #define FT_LOAD_COMPUTE_METRICS ( 1L << 21 ) +#define FT_LOAD_BITMAP_METRICS_ONLY ( 1L << 22 ) /* */ - /* used internally only by certain font drivers! */ + /* used internally only by certain font drivers */ #define FT_LOAD_ADVANCE_ONLY ( 1L << 8 ) #define FT_LOAD_SBITS_ONLY ( 1L << 14 ) @@ -2813,29 +2892,30 @@ FT_BEGIN_HEADER * FT_LOAD_TARGET_XXX * * @description: - * A list of values that are used to select a specific hinting algorithm - * to use by the hinter. You should OR one of these values to your - * `load_flags' when calling @FT_Load_Glyph. + * A list of values to select a specific hinting algorithm for the + * hinter. You should OR one of these values to your `load_flags' + * when calling @FT_Load_Glyph. * - * Note that font's native hinters may ignore the hinting algorithm you - * have specified (e.g., the TrueType bytecode interpreter). You can set - * @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used. - * - * Also note that @FT_LOAD_TARGET_LIGHT is an exception, in that it - * always implies @FT_LOAD_FORCE_AUTOHINT. + * Note that a font's native hinters may ignore the hinting algorithm + * you have specified (e.g., the TrueType bytecode interpreter). You + * can set @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is + * used. * * @values: * FT_LOAD_TARGET_NORMAL :: - * This corresponds to the default hinting algorithm, optimized for - * standard gray-level rendering. For monochrome output, use - * @FT_LOAD_TARGET_MONO instead. + * The default hinting algorithm, optimized for standard gray-level + * rendering. For monochrome output, use @FT_LOAD_TARGET_MONO + * instead. * * FT_LOAD_TARGET_LIGHT :: - * A lighter hinting algorithm for non-monochrome modes. Many - * generated glyphs are more fuzzy but better resemble its original - * shape. A bit like rendering on Mac OS~X. - * - * As a special exception, this target implies @FT_LOAD_FORCE_AUTOHINT. + * A lighter hinting algorithm for gray-level modes. Many generated + * glyphs are fuzzier but better resemble their original shape. This + * is achieved by snapping glyphs to the pixel grid only vertically + * (Y-axis), as is done by Microsoft's ClearType and Adobe's + * proprietary font renderer. This preserves inter-glyph spacing in + * horizontal text. The snapping is done either by the native font + * driver, if the driver itself and the font support it, or by the + * auto-hinter. * * FT_LOAD_TARGET_MONO :: * Strong hinting algorithm that should only be used for monochrome @@ -2856,7 +2936,7 @@ FT_BEGIN_HEADER * * If @FT_LOAD_RENDER is also set, the glyph is rendered in the * corresponding mode (i.e., the mode that matches the used algorithm - * best). An exeption is FT_LOAD_TARGET_MONO since it implies + * best). An exception is FT_LOAD_TARGET_MONO since it implies * @FT_LOAD_MONOCHROME. * * You can use a hinting algorithm that doesn't correspond to the same @@ -2900,18 +2980,17 @@ FT_BEGIN_HEADER /* FT_Set_Transform */ /* */ /* <Description> */ - /* A function used to set the transformation that is applied to glyph */ - /* images when they are loaded into a glyph slot through */ - /* @FT_Load_Glyph. */ + /* Set the transformation that is applied to glyph images when they */ + /* are loaded into a glyph slot through @FT_Load_Glyph. */ /* */ /* <InOut> */ /* face :: A handle to the source face object. */ /* */ /* <Input> */ - /* matrix :: A pointer to the transformation's 2x2 matrix. Use~0 for */ - /* the identity matrix. */ - /* delta :: A pointer to the translation vector. Use~0 for the null */ - /* vector. */ + /* matrix :: A pointer to the transformation's 2x2 matrix. Use NULL */ + /* for the identity matrix. */ + /* delta :: A pointer to the translation vector. Use NULL for the */ + /* null vector. */ /* */ /* <Note> */ /* The transformation is only applied to scalable image formats after */ @@ -2934,20 +3013,22 @@ FT_BEGIN_HEADER /* FT_Render_Mode */ /* */ /* <Description> */ - /* An enumeration type that lists the render modes supported by */ - /* FreeType~2. Each mode corresponds to a specific type of scanline */ - /* conversion performed on the outline. */ + /* Render modes supported by FreeType~2. Each mode corresponds to a */ + /* specific type of scanline conversion performed on the outline. */ /* */ /* For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode' */ /* field in the @FT_GlyphSlotRec structure gives the format of the */ /* returned bitmap. */ /* */ - /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity. */ + /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity, */ + /* indicating pixel coverage. Use linear alpha blending and gamma */ + /* correction to correctly render non-monochrome glyph bitmaps onto a */ + /* surface; see @FT_Render_Glyph. */ /* */ /* <Values> */ /* FT_RENDER_MODE_NORMAL :: */ - /* This is the default render mode; it corresponds to 8-bit */ - /* anti-aliased bitmaps. */ + /* Default render mode; it corresponds to 8-bit anti-aliased */ + /* bitmaps. */ /* */ /* FT_RENDER_MODE_LIGHT :: */ /* This is equivalent to @FT_RENDER_MODE_NORMAL. It is only */ @@ -2972,11 +3053,11 @@ FT_BEGIN_HEADER /* glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode. */ /* */ /* <Note> */ - /* The LCD-optimized glyph bitmaps produced by FT_Render_Glyph can be */ - /* filtered to reduce color-fringes by using @FT_Library_SetLcdFilter */ - /* (not active in the default builds). It is up to the caller to */ - /* either call @FT_Library_SetLcdFilter (if available) or do the */ - /* filtering itself. */ + /* The LCD-optimized glyph bitmaps produced by `FT_Render_Glyph' can */ + /* be filtered to reduce color-fringes by using */ + /* @FT_Library_SetLcdFilter (not active in the default builds). It */ + /* is up to the caller to either call `FT_Library_SetLcdFilter' (if */ + /* available) or do the filtering itself. */ /* */ /* The selected render mode only affects vector glyphs of a font. */ /* Embedded bitmaps often have a different pixel mode like */ @@ -3017,16 +3098,93 @@ FT_BEGIN_HEADER /* convert. */ /* */ /* <Input> */ - /* render_mode :: This is the render mode used to render the glyph */ - /* image into a bitmap. See @FT_Render_Mode for a */ - /* list of possible values. */ + /* render_mode :: The render mode used to render the glyph image into */ + /* a bitmap. See @FT_Render_Mode for a list of */ + /* possible values. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* To get meaningful results, font scaling values must be set with */ - /* functions like @FT_Set_Char_Size before calling FT_Render_Glyph. */ + /* functions like @FT_Set_Char_Size before calling `FT_Render_Glyph'. */ + /* */ + /* When FreeType outputs a bitmap of a glyph, it really outputs an */ + /* alpha coverage map. If a pixel is completely covered by a */ + /* filled-in outline, the bitmap contains 0xFF at that pixel, meaning */ + /* that 0xFF/0xFF fraction of that pixel is covered, meaning the */ + /* pixel is 100% black (or 0% bright). If a pixel is only 50% */ + /* covered (value 0x80), the pixel is made 50% black (50% bright or a */ + /* middle shade of grey). 0% covered means 0% black (100% bright or */ + /* white). */ + /* */ + /* On high-DPI screens like on smartphones and tablets, the pixels */ + /* are so small that their chance of being completely covered and */ + /* therefore completely black are fairly good. On the low-DPI */ + /* screens, however, the situation is different. The pixels are too */ + /* large for most of the details of a glyph and shades of gray are */ + /* the norm rather than the exception. */ + /* */ + /* This is relevant because all our screens have a second problem: */ + /* they are not linear. 1~+~1 is not~2. Twice the value does not */ + /* result in twice the brightness. When a pixel is only 50% covered, */ + /* the coverage map says 50% black, and this translates to a pixel */ + /* value of 128 when you use 8~bits per channel (0-255). However, */ + /* this does not translate to 50% brightness for that pixel on our */ + /* sRGB and gamma~2.2 screens. Due to their non-linearity, they */ + /* dwell longer in the darks and only a pixel value of about 186 */ + /* results in 50% brightness – 128 ends up too dark on both bright */ + /* and dark backgrounds. The net result is that dark text looks */ + /* burnt-out, pixely and blotchy on bright background, bright text */ + /* too frail on dark backgrounds, and colored text on colored */ + /* background (for example, red on green) seems to have dark halos or */ + /* `dirt' around it. The situation is especially ugly for diagonal */ + /* stems like in `w' glyph shapes where the quality of FreeType's */ + /* anti-aliasing depends on the correct display of grays. On */ + /* high-DPI screens where smaller, fully black pixels reign supreme, */ + /* this doesn't matter, but on our low-DPI screens with all the gray */ + /* shades, it does. 0% and 100% brightness are the same things in */ + /* linear and non-linear space, just all the shades in-between */ + /* aren't. */ + /* */ + /* The blending function for placing text over a background is */ + /* */ + /* { */ + /* dst = alpha * src + (1 - alpha) * dst , */ + /* } */ + /* */ + /* which is known as the OVER operator. */ + /* */ + /* To correctly composite an antialiased pixel of a glyph onto a */ + /* surface, */ + /* */ + /* 1. take the foreground and background colors (e.g., in sRGB space) */ + /* and apply gamma to get them in a linear space, */ + /* */ + /* 2. use OVER to blend the two linear colors using the glyph pixel */ + /* as the alpha value (remember, the glyph bitmap is an alpha */ + /* coverage bitmap), and */ + /* */ + /* 3. apply inverse gamma to the blended pixel and write it back to */ + /* the image. */ + /* */ + /* Internal testing at Adobe found that a target inverse gamma of~1.8 */ + /* for step~3 gives good results across a wide range of displays with */ + /* an sRGB gamma curve or a similar one. */ + /* */ + /* This process can cost performance. There is an approximation that */ + /* does not need to know about the background color; see */ + /* https://bel.fi/alankila/lcd/ and */ + /* https://bel.fi/alankila/lcd/alpcor.html for details. */ + /* */ + /* *ATTENTION*: Linear blending is even more important when dealing */ + /* with subpixel-rendered glyphs to prevent color-fringing! A */ + /* subpixel-rendered glyph must first be filtered with a filter that */ + /* gives equal weight to the three color primaries and does not */ + /* exceed a sum of 0x100, see section @lcd_filtering. Then the */ + /* only difference to gray linear blending is that subpixel-rendered */ + /* linear blending is done 3~times per pixel: red foreground subpixel */ + /* to red background subpixel and so on for green and blue. */ /* */ FT_EXPORT( FT_Error ) FT_Render_Glyph( FT_GlyphSlot slot, @@ -3039,17 +3197,15 @@ FT_BEGIN_HEADER /* FT_Kerning_Mode */ /* */ /* <Description> */ - /* An enumeration used to specify which kerning values to return in */ + /* An enumeration to specify the format of kerning values returned by */ /* @FT_Get_Kerning. */ /* */ /* <Values> */ /* FT_KERNING_DEFAULT :: Return grid-fitted kerning distances in */ - /* pixels (value is~0). Whether they are */ - /* scaled depends on @FT_LOAD_NO_SCALE. */ + /* 26.6 fractional pixels. */ /* */ /* FT_KERNING_UNFITTED :: Return un-grid-fitted kerning distances in */ - /* 26.6 fractional pixels. Whether they are */ - /* scaled depends on @FT_LOAD_NO_SCALE. */ + /* 26.6 fractional pixels. */ /* */ /* FT_KERNING_UNSCALED :: Return the kerning vector in original font */ /* units. */ @@ -3059,9 +3215,13 @@ FT_BEGIN_HEADER /* FreeType heuristically scale down kerning distances at small ppem */ /* values so that they don't become too big. */ /* */ + /* Both FT_KERNING_DEFAULT and FT_KERNING_UNFITTED use the current */ + /* horizontal scaling factor (as set e.g. with @FT_Set_Char_Size) to */ + /* convert font units to pixels. */ + /* */ typedef enum FT_Kerning_Mode_ { - FT_KERNING_DEFAULT = 0, + FT_KERNING_DEFAULT = 0, FT_KERNING_UNFITTED, FT_KERNING_UNSCALED @@ -3081,7 +3241,7 @@ FT_BEGIN_HEADER /* FT_Get_Kerning */ /* */ /* <Description> */ - /* Return the kerning vector between two glyphs of a same face. */ + /* Return the kerning vector between two glyphs of the same face. */ /* */ /* <Input> */ /* face :: A handle to a source face object. */ @@ -3109,6 +3269,10 @@ FT_BEGIN_HEADER /* kernings, are out of the scope of this API function -- they can be */ /* implemented through format-specific interfaces. */ /* */ + /* Kerning for OpenType fonts implemented in a `GPOS' table is not */ + /* supported; use @FT_HAS_KERNING to find out whether a font has data */ + /* that can be extracted with `FT_Get_Kerning'. */ + /* */ FT_EXPORT( FT_Error ) FT_Get_Kerning( FT_Face face, FT_UInt left_glyph, @@ -3148,7 +3312,7 @@ FT_BEGIN_HEADER /* @FT_Attach_Stream). */ /* */ /* Only very few AFM files come with track kerning data; please refer */ - /* to the Adobe's AFM specification for more details. */ + /* to Adobe's AFM specification for more details. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Track_Kerning( FT_Face face, @@ -3194,7 +3358,7 @@ FT_BEGIN_HEADER /* `.notdef'). */ /* */ /* This function always returns an error if the config macro */ - /* `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoptions.h'. */ + /* `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoption.h'. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Glyph_Name( FT_Face face, @@ -3210,7 +3374,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Retrieve the ASCII PostScript name of a given face, if available. */ - /* This only works with PostScript and TrueType fonts. */ + /* This only works with PostScript, TrueType, and OpenType fonts. */ /* */ /* <Input> */ /* face :: A handle to the source face object. */ @@ -3281,7 +3445,8 @@ FT_BEGIN_HEADER /* the face (i.e., if it is not listed in the `face->charmaps' */ /* table). */ /* */ - /* It also fails if a type~14 charmap is selected. */ + /* It also fails if an OpenType type~14 charmap is selected (which */ + /* doesn't map character codes to glyph indices at all). */ /* */ FT_EXPORT( FT_Error ) FT_Set_Charmap( FT_Face face, @@ -3316,7 +3481,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Return the glyph index of a given character code. This function */ - /* uses a charmap object to do the mapping. */ + /* uses the currently selected charmap to do the mapping. */ /* */ /* <Input> */ /* face :: A handle to the source face object. */ @@ -3350,9 +3515,8 @@ FT_BEGIN_HEADER /* FT_Get_First_Char */ /* */ /* <Description> */ - /* This function is used to return the first character code in the */ - /* current charmap of a given face. It also returns the */ - /* corresponding glyph index. */ + /* Return the first character code in the current charmap of a given */ + /* face, together with its corresponding glyph index. */ /* */ /* <Input> */ /* face :: A handle to the source face object. */ @@ -3365,7 +3529,7 @@ FT_BEGIN_HEADER /* The charmap's first character code. */ /* */ /* <Note> */ - /* You should use this function with @FT_Get_Next_Char to be able to */ + /* You should use this function together with @FT_Get_Next_Char to */ /* parse all character codes available in a given charmap. The code */ /* should look like this: */ /* */ @@ -3405,12 +3569,13 @@ FT_BEGIN_HEADER /* FT_Get_Next_Char */ /* */ /* <Description> */ - /* This function is used to return the next character code in the */ - /* current charmap of a given face following the value `char_code', */ - /* as well as the corresponding glyph index. */ + /* Return the next character code in the current charmap of a given */ + /* face following the value `char_code', as well as the corresponding */ + /* glyph index. */ /* */ /* <Input> */ /* face :: A handle to the source face object. */ + /* */ /* char_code :: The starting character code. */ /* */ /* <Output> */ @@ -3423,7 +3588,7 @@ FT_BEGIN_HEADER /* <Note> */ /* You should use this function with @FT_Get_First_Char to walk */ /* over all character codes available in a given charmap. See the */ - /* note for this function for a simple code example. */ + /* note for that function for a simple code example. */ /* */ /* Note that `*agindex' is set to~0 when there are no more codes in */ /* the charmap. */ @@ -3440,8 +3605,7 @@ FT_BEGIN_HEADER /* FT_Get_Name_Index */ /* */ /* <Description> */ - /* Return the glyph index of a given glyph name. This function uses */ - /* driver specific objects to do the translation. */ + /* Return the glyph index of a given glyph name. */ /* */ /* <Input> */ /* face :: A handle to the source face object. */ @@ -3462,8 +3626,10 @@ FT_BEGIN_HEADER * FT_SUBGLYPH_FLAG_XXX * * @description: - * A list of constants used to describe subglyphs. Please refer to the - * TrueType specification for the meaning of the various flags. + * A list of constants describing subglyphs. Please refer to the + * `glyf' table description in the OpenType specification for the + * meaning of the various flags (which get synthesized for + * non-OpenType subglyphs). * * @values: * FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS :: @@ -3524,7 +3690,7 @@ FT_BEGIN_HEADER * @note: * The values of `*p_arg1', `*p_arg2', and `*p_transform' must be * interpreted depending on the flags returned in `*p_flags'. See the - * TrueType specification for details. + * OpenType specification for details. * */ FT_EXPORT( FT_Error ) @@ -3564,33 +3730,31 @@ FT_BEGIN_HEADER /* the font software copyright owner. */ /* */ /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING :: */ - /* If this bit is set, the font may be embedded and temporarily */ - /* loaded on the remote system. Documents containing Preview & */ - /* Print fonts must be opened `read-only'; no edits can be applied */ - /* to the document. */ + /* The font may be embedded and temporarily loaded on the remote */ + /* system. Documents containing Preview & Print fonts must be */ + /* opened `read-only'; no edits can be applied to the document. */ /* */ /* FT_FSTYPE_EDITABLE_EMBEDDING :: */ - /* If this bit is set, the font may be embedded but must only be */ - /* installed temporarily on other systems. In contrast to Preview */ - /* & Print fonts, documents containing editable fonts may be opened */ - /* for reading, editing is permitted, and changes may be saved. */ + /* The font may be embedded but must only be installed temporarily */ + /* on other systems. In contrast to Preview & Print fonts, */ + /* documents containing editable fonts may be opened for reading, */ + /* editing is permitted, and changes may be saved. */ /* */ /* FT_FSTYPE_NO_SUBSETTING :: */ - /* If this bit is set, the font may not be subsetted prior to */ - /* embedding. */ + /* The font may not be subsetted prior to embedding. */ /* */ /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY :: */ - /* If this bit is set, only bitmaps contained in the font may be */ - /* embedded; no outline data may be embedded. If there are no */ - /* bitmaps available in the font, then the font is unembeddable. */ + /* Only bitmaps contained in the font may be embedded; no outline */ + /* data may be embedded. If there are no bitmaps available in the */ + /* font, then the font is unembeddable. */ /* */ /* <Note> */ /* The flags are ORed together, thus more than a single value can be */ /* returned. */ /* */ - /* While the fsType flags can indicate that a font may be embedded, a */ - /* license with the font vendor may be separately required to use the */ - /* font in this way. */ + /* While the `fsType' flags can indicate that a font may be embedded, */ + /* a license with the font vendor may be separately required to use */ + /* the font in this way. */ /* */ #define FT_FSTYPE_INSTALLABLE_EMBEDDING 0x0000 #define FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING 0x0002 @@ -3606,13 +3770,13 @@ FT_BEGIN_HEADER /* FT_Get_FSType_Flags */ /* */ /* <Description> */ - /* Return the fsType flags for a font. */ + /* Return the `fsType' flags for a font. */ /* */ /* <Input> */ /* face :: A handle to the source face object. */ /* */ /* <Return> */ - /* The fsType flags, @FT_FSTYPE_XXX. */ + /* The `fsType' flags, see @FT_FSTYPE_XXX. */ /* */ /* <Note> */ /* Use this function rather than directly reading the `fs_type' field */ @@ -3652,8 +3816,9 @@ FT_BEGIN_HEADER /* Database: */ /* */ /* http://www.unicode.org/reports/tr37/ */ + /* http://www.unicode.org/ivd/ */ /* */ - /* To date (November 2014), the character with the most variants is */ + /* To date (January 2017), the character with the most variants is */ /* U+9089, having 32 such IVS. */ /* */ /* Adobe and MS decided to support IVS with a new cmap subtable */ @@ -3882,16 +4047,17 @@ FT_BEGIN_HEADER /* FT_MulDiv */ /* */ /* <Description> */ - /* A very simple function used to perform the computation `(a*b)/c' */ - /* with maximum accuracy (it uses a 64-bit intermediate integer */ - /* whenever necessary). */ + /* Compute `(a*b)/c' with maximum accuracy, using a 64-bit */ + /* intermediate integer whenever necessary. */ /* */ /* This function isn't necessarily as fast as some processor specific */ /* operations, but is at least completely portable. */ /* */ /* <Input> */ /* a :: The first multiplier. */ + /* */ /* b :: The second multiplier. */ + /* */ /* c :: The divisor. */ /* */ /* <Return> */ @@ -3911,12 +4077,12 @@ FT_BEGIN_HEADER /* FT_MulFix */ /* */ /* <Description> */ - /* A very simple function used to perform the computation */ - /* `(a*b)/0x10000' with maximum accuracy. Most of the time this is */ - /* used to multiply a given value by a 16.16 fixed-point factor. */ + /* Compute `(a*b)/0x10000' with maximum accuracy. Its main use is to */ + /* multiply a given value by a 16.16 fixed-point factor. */ /* */ /* <Input> */ /* a :: The first multiplier. */ + /* */ /* b :: The second multiplier. Use a 16.16 factor here whenever */ /* possible (see note below). */ /* */ @@ -3945,12 +4111,12 @@ FT_BEGIN_HEADER /* FT_DivFix */ /* */ /* <Description> */ - /* A very simple function used to perform the computation */ - /* `(a*0x10000)/b' with maximum accuracy. Most of the time, this is */ - /* used to divide a given value by a 16.16 fixed-point factor. */ + /* Compute `(a*0x10000)/b' with maximum accuracy. Its main use is to */ + /* divide a given value by a 16.16 fixed-point factor. */ /* */ /* <Input> */ /* a :: The numerator. */ + /* */ /* b :: The denominator. Use a 16.16 factor here. */ /* */ /* <Return> */ @@ -3967,13 +4133,13 @@ FT_BEGIN_HEADER /* FT_RoundFix */ /* */ /* <Description> */ - /* A very simple function used to round a 16.16 fixed number. */ + /* Round a 16.16 fixed number. */ /* */ /* <Input> */ /* a :: The number to be rounded. */ /* */ /* <Return> */ - /* `a' rounded to nearest 16.16 fixed integer, halfway cases away */ + /* `a' rounded to the nearest 16.16 fixed integer, halfway cases away */ /* from zero. */ /* */ FT_EXPORT( FT_Fixed ) @@ -3986,8 +4152,7 @@ FT_BEGIN_HEADER /* FT_CeilFix */ /* */ /* <Description> */ - /* A very simple function used to compute the ceiling function of a */ - /* 16.16 fixed number. */ + /* Compute the smallest following integer of a 16.16 fixed number. */ /* */ /* <Input> */ /* a :: The number for which the ceiling function is to be computed. */ @@ -4005,8 +4170,7 @@ FT_BEGIN_HEADER /* FT_FloorFix */ /* */ /* <Description> */ - /* A very simple function used to compute the floor function of a */ - /* 16.16 fixed number. */ + /* Compute the largest previous integer of a 16.16 fixed number. */ /* */ /* <Input> */ /* a :: The number for which the floor function is to be computed. */ @@ -4092,7 +4256,7 @@ FT_BEGIN_HEADER * */ #define FREETYPE_MAJOR 2 -#define FREETYPE_MINOR 6 +#define FREETYPE_MINOR 7 #define FREETYPE_PATCH 1 @@ -4138,20 +4302,13 @@ FT_BEGIN_HEADER /* FT_Face_CheckTrueTypePatents */ /* */ /* <Description> */ - /* Parse all bytecode instructions of a TrueType font file to check */ - /* whether any of the patented opcodes are used. This is only useful */ - /* if you want to be able to use the unpatented hinter with */ - /* fonts that do *not* use these opcodes. */ - /* */ - /* Note that this function parses *all* glyph instructions in the */ - /* font file, which may be slow. */ + /* Deprecated, does nothing. */ /* */ /* <Input> */ /* face :: A face handle. */ /* */ /* <Return> */ - /* 1~if this is a TrueType font that uses one of the patented */ - /* opcodes, 0~otherwise. */ + /* Always returns false. */ /* */ /* <Note> */ /* Since May 2010, TrueType hinting is no longer patented. */ @@ -4169,9 +4326,7 @@ FT_BEGIN_HEADER /* FT_Face_SetUnpatentedHinting */ /* */ /* <Description> */ - /* Enable or disable the unpatented hinter for a given face. */ - /* Only enable it if you have determined that the face doesn't */ - /* use any patented opcodes (see @FT_Face_CheckTrueTypePatents). */ + /* Deprecated, does nothing. */ /* */ /* <Input> */ /* face :: A face handle. */ @@ -4179,9 +4334,7 @@ FT_BEGIN_HEADER /* value :: New boolean setting. */ /* */ /* <Return> */ - /* The old setting value. This will always be false if this is not */ - /* an SFNT font, or if the unpatented hinter is not compiled in this */ - /* instance of the library. */ + /* Always returns false. */ /* */ /* <Note> */ /* Since May 2010, TrueType hinting is no longer patented. */ @@ -4198,7 +4351,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FREETYPE_H__ */ +#endif /* FREETYPE_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftadvanc.h b/third_party/freetype/include/freetype/ftadvanc.h index b4d2aed567..dea96e0db4 100644 --- a/third_party/freetype/include/freetype/ftadvanc.h +++ b/third_party/freetype/include/freetype/ftadvanc.h @@ -4,7 +4,7 @@ /* */ /* Quick computation of advance widths (specification only). */ /* */ -/* Copyright 2008-2015 by */ +/* Copyright 2008-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTADVANC_H__ -#define __FTADVANC_H__ +#ifndef FTADVANC_H_ +#define FTADVANC_H_ #include <ft2build.h> @@ -181,7 +181,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTADVANC_H__ */ +#endif /* FTADVANC_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftbitmap.h b/third_party/freetype/include/freetype/ftbitmap.h index 46cc47b7d1..04b2402ad0 100644 --- a/third_party/freetype/include/freetype/ftbitmap.h +++ b/third_party/freetype/include/freetype/ftbitmap.h @@ -4,7 +4,7 @@ /* */ /* FreeType utility functions for bitmaps (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTBITMAP_H__ -#define __FTBITMAP_H__ +#ifndef FTBITMAP_H_ +#define FTBITMAP_H_ #include <ft2build.h> @@ -234,7 +234,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTBITMAP_H__ */ +#endif /* FTBITMAP_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftcffdrv.h b/third_party/freetype/include/freetype/ftcffdrv.h index 6c8e416cee..35758f8fb1 100644 --- a/third_party/freetype/include/freetype/ftcffdrv.h +++ b/third_party/freetype/include/freetype/ftcffdrv.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for controlling the CFF driver (specification only). */ /* */ -/* Copyright 2013-2015 by */ +/* Copyright 2013-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTCFFDRV_H__ -#define __FTCFFDRV_H__ +#ifndef FTCFFDRV_H_ +#define FTCFFDRV_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -89,7 +89,7 @@ FT_BEGIN_HEADER * features preserve the design's weight and spacing much better than * aliased type would. * - * 2) Aligment in the vertical direction: Weights and spacing along the + * 2) Alignment in the vertical direction: Weights and spacing along the * y~axis are less critical; what is much more important is the visual * alignment of related features (like cap-height and x-height). The * sense of alignment for these is enhanced by the sharpness of grid-fit @@ -110,9 +110,9 @@ FT_BEGIN_HEADER * to minimize distortion. * * @order: - * hinting-engine - * no-stem-darkening - * darkening-parameters + * hinting-engine[cff] + * no-stem-darkening[cff] + * darkening-parameters[cff] * */ @@ -120,7 +120,7 @@ FT_BEGIN_HEADER /************************************************************************** * * @property: - * hinting-engine + * hinting-engine[cff] * * @description: * Thanks to Adobe, which contributed a new hinting (and parsing) @@ -148,6 +148,8 @@ FT_BEGIN_HEADER * @note: * This property can be used with @FT_Property_Get also. * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable (using values `adobe' or `freetype'). */ @@ -157,8 +159,8 @@ FT_BEGIN_HEADER * FT_CFF_HINTING_XXX * * @description: - * A list of constants used for the @hinting-engine property to select - * the hinting engine for CFF fonts. + * A list of constants used for the @hinting-engine[cff] property to + * select the hinting engine for CFF fonts. * * @values: * FT_CFF_HINTING_FREETYPE :: @@ -175,7 +177,7 @@ FT_BEGIN_HEADER /************************************************************************** * * @property: - * no-stem-darkening + * no-stem-darkening[cff] * * @description: * By default, the Adobe CFF engine darkens stems at smaller sizes, @@ -199,13 +201,16 @@ FT_BEGIN_HEADER * @note: * This property can be used with @FT_Property_Get also. * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable (using values 1 and 0 for `on' and `off', respectively). + * */ /************************************************************************** * * @property: - * darkening-parameters + * darkening-parameters[cff] * * @description: * By default, the Adobe CFF engine darkens stems as follows (if the @@ -248,6 +253,14 @@ FT_BEGIN_HEADER * @note: * This property can be used with @FT_Property_Get also. * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable, using eight comma-separated integers without spaces. Here + * the above example, using `\' to break the line for readability. + * + * { + * FREETYPE_PROPERTIES=\ + * cff:darkening-parameters=500,300,1000,200,1500,100,2000,0 + * } */ /* */ @@ -256,7 +269,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCFFDRV_H__ */ +#endif /* FTCFFDRV_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/fterrdef.h b/third_party/freetype/include/freetype/fterrdef.h index d865da7127..232dccdc6a 100644 --- a/third_party/freetype/include/freetype/fterrdef.h +++ b/third_party/freetype/include/freetype/fterrdef.h @@ -4,7 +4,7 @@ /* */ /* FreeType error codes (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -243,7 +243,7 @@ FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, "no Unicode glyph name found" ) FT_ERRORDEF_( Glyph_Too_Big, 0xA4, - "glyph to big for hinting" ) + "glyph too big for hinting" ) /* BDF errors */ diff --git a/third_party/freetype/include/freetype/fterrors.h b/third_party/freetype/include/freetype/fterrors.h index 0507b9ad7d..021989d0dd 100644 --- a/third_party/freetype/include/freetype/fterrors.h +++ b/third_party/freetype/include/freetype/fterrors.h @@ -4,7 +4,7 @@ /* */ /* FreeType error code handling (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -72,13 +72,13 @@ /* */ /* This macro ends the list. */ /* */ - /* Additionally, you have to undefine `__FTERRORS_H__' before */ - /* #including this file. */ + /* Additionally, you have to undefine `FTERRORS_H_' before #including */ + /* this file. */ /* */ /* Here is a simple example. */ /* */ /* { */ - /* #undef __FTERRORS_H__ */ + /* #undef FTERRORS_H_ */ /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ /* #define FT_ERROR_START_LIST { */ /* #define FT_ERROR_END_LIST { 0, NULL } }; */ @@ -99,7 +99,17 @@ /* */ -#ifndef __FTERRORS_H__ + /* In previous FreeType versions we used `__FTERRORS_H__'. However, */ + /* using two successive underscores in a non-system symbol name */ + /* violates the C (and C++) standard, so it was changed to the */ + /* current form. In spite of this, we have to make */ + /* */ + /* #undefine __FTERRORS_H__ */ + /* */ + /* work for backwards compatibility. */ + /* */ +#if !( defined( FTERRORS_H_ ) && defined ( __FTERRORS_H__ ) ) +#define FTERRORS_H_ #define __FTERRORS_H__ @@ -210,7 +220,7 @@ #undef FT_ERR_PREFIX #endif -#endif /* __FTERRORS_H__ */ +#endif /* !(FTERRORS_H_ && __FTERRORS_H__) */ /* END */ diff --git a/third_party/freetype/include/freetype/ftfntfmt.h b/third_party/freetype/include/freetype/ftfntfmt.h index 1f8ff28f10..337758328a 100644 --- a/third_party/freetype/include/freetype/ftfntfmt.h +++ b/third_party/freetype/include/freetype/ftfntfmt.h @@ -4,7 +4,7 @@ /* */ /* Support functions for font formats. */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTFNTFMT_H__ -#define __FTFNTFMT_H__ +#ifndef FTFNTFMT_H_ +#define FTFNTFMT_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -89,4 +89,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTFNTFMT_H__ */ +#endif /* FTFNTFMT_H_ */ + + +/* END */ diff --git a/third_party/freetype/include/freetype/ftglyph.h b/third_party/freetype/include/freetype/ftglyph.h index 803ad39621..6b51792514 100644 --- a/third_party/freetype/include/freetype/ftglyph.h +++ b/third_party/freetype/include/freetype/ftglyph.h @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,8 +29,8 @@ /*************************************************************************/ -#ifndef __FTGLYPH_H__ -#define __FTGLYPH_H__ +#ifndef FTGLYPH_H_ +#define FTGLYPH_H_ #include <ft2build.h> @@ -594,7 +594,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTGLYPH_H__ */ +#endif /* FTGLYPH_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftgzip.h b/third_party/freetype/include/freetype/ftgzip.h index b3a532d5e1..bd5ceaab9f 100644 --- a/third_party/freetype/include/freetype/ftgzip.h +++ b/third_party/freetype/include/freetype/ftgzip.h @@ -4,7 +4,7 @@ /* */ /* Gzip-compressed stream support. */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTGZIP_H__ -#define __FTGZIP_H__ +#ifndef FTGZIP_H_ +#define FTGZIP_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -117,11 +117,11 @@ FT_BEGIN_HEADER * * @inout: * output_len :: - * Before calling the function, this is the the total size of the - * output buffer, which must be large enough to hold the entire - * uncompressed data (so the size of the uncompressed data must be - * known in advance). After calling the function, `output_len' is the - * size of the used data in `output'. + * Before calling the function, this is the total size of the output + * buffer, which must be large enough to hold the entire uncompressed + * data (so the size of the uncompressed data must be known in + * advance). After calling the function, `output_len' is the size of + * the used data in `output'. * * @return: * FreeType error code. 0~means success. @@ -142,7 +142,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTGZIP_H__ */ +#endif /* FTGZIP_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftimage.h b/third_party/freetype/include/freetype/ftimage.h index 82f284c4f9..e21a2203b4 100644 --- a/third_party/freetype/include/freetype/ftimage.h +++ b/third_party/freetype/include/freetype/ftimage.h @@ -5,7 +5,7 @@ /* FreeType glyph image formats and default raster interface */ /* (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,12 +24,12 @@ /*************************************************************************/ -#ifndef __FTIMAGE_H__ -#define __FTIMAGE_H__ +#ifndef FTIMAGE_H_ +#define FTIMAGE_H_ - /* _STANDALONE_ is from ftgrays.c */ -#ifndef _STANDALONE_ + /* STANDALONE_ is from ftgrays.c */ +#ifndef STANDALONE_ #include <ft2build.h> #endif @@ -747,7 +747,7 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* A raster is a scan converter, in charge of rendering an outline into */ - /* a a bitmap. This section contains the public API for rasters. */ + /* a bitmap. This section contains the public API for rasters. */ /* */ /* Note that in FreeType 2, all rasters are now encapsulated within */ /* specific modules called `renderers'. See `ftrender.h' for more */ @@ -860,16 +860,6 @@ FT_BEGIN_HEADER /* This can be used to write anti-aliased outlines directly to a */ /* given background bitmap, and even perform translucency. */ /* */ - /* Note that the `count' field cannot be greater than a fixed value */ - /* defined by the `FT_MAX_GRAY_SPANS' configuration macro in */ - /* `ftoption.h'. By default, this value is set to~32, which means */ - /* that if there are more than 32~spans on a given scanline, the */ - /* callback is called several times with the same `y' parameter in */ - /* order to draw all callbacks. */ - /* */ - /* Otherwise, the callback is only called once per scan-line, and */ - /* only for those scanlines that do have `gray' pixels on them. */ - /* */ typedef void (*FT_SpanFunc)( int y, int count, @@ -1190,6 +1180,7 @@ FT_BEGIN_HEADER typedef struct FT_Raster_Funcs_ { FT_Glyph_Format glyph_format; + FT_Raster_NewFunc raster_new; FT_Raster_ResetFunc raster_reset; FT_Raster_SetModeFunc raster_set_mode; @@ -1203,7 +1194,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTIMAGE_H__ */ +#endif /* FTIMAGE_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftincrem.h b/third_party/freetype/include/freetype/ftincrem.h index 840af25b05..f6ae2baed6 100644 --- a/third_party/freetype/include/freetype/ftincrem.h +++ b/third_party/freetype/include/freetype/ftincrem.h @@ -4,7 +4,7 @@ /* */ /* FreeType incremental loading (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTINCREM_H__ -#define __FTINCREM_H__ +#ifndef FTINCREM_H_ +#define FTINCREM_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -348,7 +348,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTINCREM_H__ */ +#endif /* FTINCREM_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftlcdfil.h b/third_party/freetype/include/freetype/ftlcdfil.h index 4cd999a4b3..928bb0f3ea 100644 --- a/third_party/freetype/include/freetype/ftlcdfil.h +++ b/third_party/freetype/include/freetype/ftlcdfil.h @@ -5,7 +5,7 @@ /* FreeType API for color filtering of subpixel bitmap glyphs */ /* (specification). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __FT_LCD_FILTER_H__ -#define __FT_LCD_FILTER_H__ +#ifndef FTLCDFIL_H_ +#define FTLCDFIL_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -41,56 +41,91 @@ FT_BEGIN_HEADER * LCD Filtering * * @abstract: - * Reduce color fringes of LCD-optimized bitmaps. + * Reduce color fringes of subpixel-rendered 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 - * that would occur with unfiltered rendering. + * Subpixel rendering exploits the color-striped structure of LCD + * pixels, increasing the available resolution in the direction of the + * stripe (usually horizontal RGB) by a factor of~3. Since these + * subpixels are color pixels, using them unfiltered creates severe + * color fringes. Use the @FT_Library_SetLcdFilter API to specify a + * low-pass filter, which is then applied to subpixel-rendered bitmaps + * generated through @FT_Render_Glyph. The filter sacrifices some of + * the higher resolution to reduce color fringes, making the glyph image + * slightly blurrier. Positional improvements will remain. * * 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. - * - * FreeType generates alpha coverage maps, which are linear by nature. - * For instance, the value 0x80 in bitmap representation means that - * (within numerical precision) 0x80/0xFF fraction of that pixel is - * covered by the glyph's outline. The blending function for placing - * text over a background is - * - * { - * dst = alpha * src + (1 - alpha) * dst , - * } - * - * which is known as OVER. However, when calculating the output of the - * OVER operator, the source colors should first be transformed to a - * linear color space, then alpha blended in that space, and transformed - * back to the output color space. - * - * When linear light blending is used, the default FIR5 filtering - * weights (as given by FT_LCD_FILTER_DEFAULT) are no longer optimal, as - * they have been designed for black on white rendering while lacking - * gamma correction. To preserve color neutrality, weights for a FIR5 - * filter should be chosen according to two free parameters `a' and `c', - * and the FIR weights should be - * - * { - * [a - c, a + c, 2 * a, a + c, a - c] . - * } - * - * This formula generates equal weights for all the color primaries - * across the filter kernel, which makes it colorless. One suggested - * set of weights is - * - * { - * [0x10, 0x50, 0x60, 0x50, 0x10] , - * } - * - * where `a' has value 0x30 and `b' value 0x20. The weights in filter - * may have a sum larger than 0x100, which increases coloration slightly - * but also improves contrast. + * in order to activate it and explicitly call @FT_Library_SetLcdFilter + * to enable it. + * + * A filter should have two properties: + * + * 1) It should be normalized, meaning the sum of the 5~components + * should be 256 (0x100). It is possible to go above or under this + * target sum, however: going under means tossing out contrast, going + * over means invoking clamping and thereby non-linearities that + * increase contrast somewhat at the expense of greater distortion + * and color-fringing. Contrast is better enhanced through stem + * darkening. + * + * 2) It should be color-balanced, meaning a filter `{~a, b, c, b, a~}' + * where a~+ b~=~c. It distributes the computed coverage for one + * subpixel to all subpixels equally, sacrificing some won resolution + * but drastically reducing color-fringing. Positioning improvements + * remain! Note that color-fringing can only really be minimized + * when using a color-balanced filter and alpha-blending the glyph + * onto a surface in linear space; see @FT_Render_Glyph. + * + * Regarding the form, a filter can be a `boxy' filter or a `beveled' + * filter. Boxy filters are sharper but are less forgiving of non-ideal + * gamma curves of a screen (viewing angles!), beveled filters are + * fuzzier but more tolerant. + * + * Examples: + * + * - [0x10 0x40 0x70 0x40 0x10] is beveled and neither balanced nor + * normalized. + * + * - [0x1A 0x33 0x4D 0x33 0x1A] is beveled and balanced but not + * normalized. + * + * - [0x19 0x33 0x66 0x4c 0x19] is beveled and normalized but not + * balanced. + * + * - [0x00 0x4c 0x66 0x4c 0x00] is boxily beveled and normalized but not + * balanced. + * + * - [0x00 0x55 0x56 0x55 0x00] is boxy, normalized, and almost + * balanced. + * + * - [0x08 0x4D 0x56 0x4D 0x08] is beveled, normalized and, almost + * balanced. + * + * The filter affects glyph bitmaps rendered through @FT_Render_Glyph, + * @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 wider or taller than the dimensions of the corresponding + * outline with regard to the pixel grid. For example, for + * @FT_RENDER_MODE_LCD, the filter adds 3~subpixels to the left, and + * 3~subpixels to the right. The bitmap offset values are adjusted + * accordingly, so clients shouldn't need to modify their layout and + * glyph positioning code when enabling the filter. + * + * It is important to understand that linear alpha blending and gamma + * correction is critical for correctly rendering glyphs onto surfaces + * without artifacts and even more critical when subpixel rendering is + * involved. + * + * Each of the 3~alpha values (subpixels) is independently used to blend + * one color channel. That is, red alpha blends the red channel of the + * text color with the red channel of the background pixel. The + * distribution of density values by the color-balanced filter assumes + * alpha blending is done in linear space; only then color artifacts + * cancel out. */ @@ -111,10 +146,23 @@ FT_BEGIN_HEADER * The default filter reduces color fringes considerably, at the cost * of a slight blurriness in the output. * + * It is a beveled, normalized, and color-balanced five-tap filter + * that is more forgiving to screens with non-ideal gamma curves and + * viewing angles. Note that while color-fringing is reduced, it can + * only be minimized by using linear alpha blending and gamma + * correction to render glyphs onto surfaces. The default filter + * weights are [0x08 0x4D 0x56 0x4D 0x08]. + * * 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. + * The light filter is a variant that is sharper at the cost of + * slightly more color fringes than the default one. + * + * It is a boxy, normalized, and color-balanced three-tap filter that + * is less forgiving to screens with non-ideal gamma curves and + * viewing angles. This filter works best when the rendering system + * uses linear alpha blending and gamma correction to render glyphs + * onto surfaces. The light filter weights are + * [0x00 0x55 0x56 0x55 0x00]. * * FT_LCD_FILTER_LEGACY :: * This filter corresponds to the original libXft color filter. It @@ -126,14 +174,23 @@ FT_BEGIN_HEADER * This filter is only provided for comparison purposes, and might be * disabled or stay unsupported in the future. * + * FT_LCD_FILTER_LEGACY1 :: + * For historical reasons, the FontConfig library returns a different + * enumeration value for legacy LCD filtering. To make code work that + * (incorrectly) forwards FontConfig's enumeration value to + * @FT_Library_SetLcdFilter without proper mapping, it is thus easiest + * to have another enumeration value, which is completely equal to + * `FT_LCD_FILTER_LEGACY'. + * * @since: - * 2.3.0 + * 2.3.0 (`FT_LCD_FILTER_LEGACY1' since 2.6.2) */ typedef enum FT_LcdFilter_ { FT_LCD_FILTER_NONE = 0, FT_LCD_FILTER_DEFAULT = 1, FT_LCD_FILTER_LIGHT = 2, + FT_LCD_FILTER_LEGACY1 = 3, FT_LCD_FILTER_LEGACY = 16, FT_LCD_FILTER_MAX /* do not remove */ @@ -176,22 +233,6 @@ FT_BEGIN_HEADER * 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 */ @@ -206,11 +247,8 @@ FT_BEGIN_HEADER * FT_Library_SetLcdFilterWeights * * @description: - * Use this function to override the filter weights selected by - * @FT_Library_SetLcdFilter. By default, FreeType uses the quintuple - * (0x00, 0x55, 0x56, 0x55, 0x00) for FT_LCD_FILTER_LIGHT, and (0x10, - * 0x40, 0x70, 0x40, 0x10) for FT_LCD_FILTER_DEFAULT and - * FT_LCD_FILTER_LEGACY. + * This function can be used to enable LCD filter with custom weights, + * instead of using presets in @FT_Library_SetLcdFilter. * * @input: * library :: @@ -230,9 +268,6 @@ FT_BEGIN_HEADER * defined in your build of the library, which should correspond to all * default builds of FreeType. * - * This function must be called after @FT_Library_SetLcdFilter to have - * any effect. - * * @since: * 2.4.0 */ @@ -245,7 +280,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FT_LCD_FILTER_H__ */ +#endif /* FTLCDFIL_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftlist.h b/third_party/freetype/include/freetype/ftlist.h index 12b48c78f7..5309cb18ba 100644 --- a/third_party/freetype/include/freetype/ftlist.h +++ b/third_party/freetype/include/freetype/ftlist.h @@ -4,7 +4,7 @@ /* */ /* Generic list support for FreeType (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,8 +24,8 @@ /*************************************************************************/ -#ifndef __FTLIST_H__ -#define __FTLIST_H__ +#ifndef FTLIST_H_ +#define FTLIST_H_ #include <ft2build.h> @@ -270,7 +270,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTLIST_H__ */ +#endif /* FTLIST_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftmm.h b/third_party/freetype/include/freetype/ftmm.h index 6ef47987e6..96dd62523c 100644 --- a/third_party/freetype/include/freetype/ftmm.h +++ b/third_party/freetype/include/freetype/ftmm.h @@ -4,7 +4,7 @@ /* */ /* FreeType Multiple Master font interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTMM_H__ -#define __FTMM_H__ +#ifndef FTMM_H_ +#define FTMM_H_ #include <ft2build.h> @@ -43,11 +43,10 @@ FT_BEGIN_HEADER /* Master fonts, i.e., the selection of specific design instances by */ /* setting design axis coordinates. */ /* */ - /* George Williams has extended this interface to make it work with */ - /* both Type~1 Multiple Masters fonts and GX distortable (var) */ - /* fonts. Some of these routines only work with MM fonts, others */ - /* will work with both types. They are similar enough that a */ - /* consistent interface makes sense. */ + /* Besides Adobe MM fonts, the interface supports Apple's TrueType GX */ + /* and OpenType variation fonts. Some of the routines only work with */ + /* Adobe MM fonts, others will work with all three types. They are */ + /* similar enough that a consistent interface makes sense. */ /* */ /*************************************************************************/ @@ -58,10 +57,11 @@ FT_BEGIN_HEADER /* FT_MM_Axis */ /* */ /* <Description> */ - /* A simple structure used to model a given axis in design space for */ - /* Multiple Masters fonts. */ + /* A structure to model a given axis in design space for Multiple */ + /* Masters fonts. */ /* */ - /* This structure can't be used for GX var fonts. */ + /* This structure can't be used for TrueType GX or OpenType variation */ + /* fonts. */ /* */ /* <Fields> */ /* name :: The axis's name. */ @@ -85,10 +85,11 @@ FT_BEGIN_HEADER /* FT_Multi_Master */ /* */ /* <Description> */ - /* A structure used to model the axes and space of a Multiple Masters */ + /* A structure to model the axes and space of a Multiple Masters */ /* font. */ /* */ - /* This structure can't be used for GX var fonts. */ + /* This structure can't be used for TrueType GX or OpenType variation */ + /* fonts. */ /* */ /* <Fields> */ /* num_axis :: Number of axes. Cannot exceed~4. */ @@ -115,27 +116,35 @@ FT_BEGIN_HEADER /* FT_Var_Axis */ /* */ /* <Description> */ - /* A simple structure used to model a given axis in design space for */ - /* Multiple Masters and GX var fonts. */ + /* A structure to model a given axis in design space for Multiple */ + /* Masters, TrueType GX, and OpenType variation fonts. */ /* */ /* <Fields> */ /* name :: The axis's name. */ - /* Not always meaningful for GX. */ + /* Not always meaningful for TrueType GX or OpenType */ + /* variation fonts. */ /* */ /* minimum :: The axis's minimum design coordinate. */ /* */ /* def :: The axis's default design coordinate. */ - /* FreeType computes meaningful default values for MM; it */ - /* is then an integer value, not in 16.16 format. */ + /* FreeType computes meaningful default values for Adobe */ + /* MM fonts. */ /* */ /* maximum :: The axis's maximum design coordinate. */ /* */ - /* tag :: The axis's tag (the GX equivalent to `name'). */ - /* FreeType provides default values for MM if possible. */ + /* tag :: The axis's tag (the equivalent to `name' for TrueType */ + /* GX and OpenType variation fonts). FreeType provides */ + /* default values for Adobe MM fonts if possible. */ /* */ - /* strid :: The entry in `name' table (another GX version of */ - /* `name'). */ - /* Not meaningful for MM. */ + /* strid :: The axis name entry in the font's `name' table. This */ + /* is another (and often better) version of the `name' */ + /* field for TrueType GX or OpenType variation fonts. Not */ + /* meaningful for Adobe MM fonts. */ + /* */ + /* <Note> */ + /* The fields `minimum', `def', and `maximum' are 16.16 fractional */ + /* values for TrueType GX and OpenType variation fonts. For Adobe MM */ + /* fonts, the values are integers. */ /* */ typedef struct FT_Var_Axis_ { @@ -157,9 +166,10 @@ FT_BEGIN_HEADER /* FT_Var_Named_Style */ /* */ /* <Description> */ - /* A simple structure used to model a named style in a GX var font. */ + /* A structure to model a named style in a TrueType GX or OpenType */ + /* variation font. */ /* */ - /* This structure can't be used for MM fonts. */ + /* This structure can't be used for Adobe MM fonts. */ /* */ /* <Fields> */ /* coords :: The design coordinates for this style. */ @@ -167,10 +177,14 @@ FT_BEGIN_HEADER /* */ /* strid :: The entry in `name' table identifying this style. */ /* */ + /* psid :: The entry in `name' table identifying a PostScript name */ + /* for this style. */ + /* */ typedef struct FT_Var_Named_Style_ { FT_Fixed* coords; FT_UInt strid; + FT_UInt psid; /* since 2.7.1 */ } FT_Var_Named_Style; @@ -181,31 +195,42 @@ FT_BEGIN_HEADER /* FT_MM_Var */ /* */ /* <Description> */ - /* A structure used to model the axes and space of a Multiple Masters */ - /* or GX var distortable font. */ + /* A structure to model the axes and space of a Adobe MM, TrueType */ + /* GX, or OpenType variation font. */ /* */ - /* Some fields are specific to one format and not to the other. */ + /* Some fields are specific to one format and not to the others. */ /* */ /* <Fields> */ /* num_axis :: The number of axes. The maximum value is~4 for */ - /* MM; no limit in GX. */ + /* Adobe MM fonts; no limit in TrueType GX or */ + /* OpenType variation fonts. */ /* */ /* num_designs :: The number of designs; should be normally */ - /* 2^num_axis for MM fonts. Not meaningful for GX */ + /* 2^num_axis for Adobe MM fonts. Not meaningful */ + /* for TrueType GX or OpenType variation fonts */ /* (where every glyph could have a different */ /* number of designs). */ /* */ - /* num_namedstyles :: The number of named styles; only meaningful for */ - /* GX that allows certain design coordinates to */ - /* have a string ID (in the `name' table) */ - /* associated with them. The font can tell the */ - /* user that, for example, Weight=1.5 is `Bold'. */ + /* num_namedstyles :: The number of named styles; a `named style' is */ + /* a tuple of design coordinates that has a string */ + /* ID (in the `name' table) associated with it. */ + /* The font can tell the user that, for example, */ + /* [Weight=1.5,Width=1.1] is `Bold'. */ + /* */ + /* For Adobe Multiple Masters fonts, this value is */ + /* always zero because the format does not support */ + /* named styles. */ /* */ /* axis :: An axis descriptor table. */ - /* GX fonts contain slightly more data than MM. */ + /* TrueType GX and OpenType variation fonts */ + /* contain slightly more data than Adobe MM fonts. */ + /* Memory management of this pointer is done */ + /* internally by FreeType. */ /* */ /* namedstyle :: A named style table. */ - /* Only meaningful with GX. */ + /* Only meaningful for TrueType GX and OpenType */ + /* variation fonts. Memory management of this */ + /* pointer is done internally by FreeType. */ /* */ typedef struct FT_MM_Var_ { @@ -224,9 +249,10 @@ FT_BEGIN_HEADER /* FT_Get_Multi_Master */ /* */ /* <Description> */ - /* Retrieve the Multiple Master descriptor of a given font. */ + /* Retrieve a variation descriptor of a given Adobe MM font. */ /* */ - /* This function can't be used with GX fonts. */ + /* This function can't be used with TrueType GX or OpenType variation */ + /* fonts. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ @@ -248,14 +274,17 @@ FT_BEGIN_HEADER /* FT_Get_MM_Var */ /* */ /* <Description> */ - /* Retrieve the Multiple Master/GX var descriptor of a given font. */ + /* Retrieve a variation descriptor for a given font. */ + /* */ + /* This function works with all supported variation formats. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ /* */ /* <Output> */ - /* amaster :: The Multiple Masters/GX var descriptor. */ - /* Allocates a data structure, which the user must free. */ + /* amaster :: The variation descriptor. */ + /* Allocates a data structure, which the user must */ + /* deallocate with `free' after use. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ @@ -271,10 +300,11 @@ FT_BEGIN_HEADER /* FT_Set_MM_Design_Coordinates */ /* */ /* <Description> */ - /* For Multiple Masters fonts, choose an interpolated font design */ - /* through design coordinates. */ + /* For Adobe MM fonts, choose an interpolated font design through */ + /* design coordinates. */ /* */ - /* This function can't be used with GX fonts. */ + /* This function can't be used with TrueType GX or OpenType variation */ + /* fonts. */ /* */ /* <InOut> */ /* face :: A handle to the source face. */ @@ -302,8 +332,9 @@ FT_BEGIN_HEADER /* FT_Set_Var_Design_Coordinates */ /* */ /* <Description> */ - /* For Multiple Master or GX Var fonts, choose an interpolated font */ - /* design through design coordinates. */ + /* Choose an interpolated font design through design coordinates. */ + /* */ + /* This function works with all supported variation formats. */ /* */ /* <InOut> */ /* face :: A handle to the source face. */ @@ -328,11 +359,43 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Function> */ + /* FT_Get_Var_Design_Coordinates */ + /* */ + /* <Description> */ + /* Get the design coordinates of the currently selected interpolated */ + /* font. */ + /* */ + /* This function works with all supported variation formats. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* num_coords :: The number of design coordinates to retrieve. If it */ + /* is larger than the number of axes, set the excess */ + /* values to~0. */ + /* */ + /* <Output> */ + /* coords :: The design coordinates array. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Var_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ /* FT_Set_MM_Blend_Coordinates */ /* */ /* <Description> */ - /* For Multiple Masters and GX var fonts, choose an interpolated font */ - /* design through normalized blend coordinates. */ + /* Choose an interpolated font design through normalized blend */ + /* coordinates. */ + /* */ + /* This function works with all supported variation formats. */ /* */ /* <InOut> */ /* face :: A handle to the source face. */ @@ -344,7 +407,9 @@ FT_BEGIN_HEADER /* use default values for the remaining axes. */ /* */ /* coords :: The design coordinates array (each element must be */ - /* between 0 and 1.0). */ + /* between 0 and 1.0 for Adobe MM fonts, and between */ + /* -1.0 and 1.0 for TrueType GX and OpenType variation */ + /* fonts). */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ @@ -358,6 +423,37 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Function> */ + /* FT_Get_MM_Blend_Coordinates */ + /* */ + /* <Description> */ + /* Get the normalized blend coordinates of the currently selected */ + /* interpolated font. */ + /* */ + /* This function works with all supported variation formats. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* num_coords :: The number of normalized blend coordinates to */ + /* retrieve. If it is larger than the number of axes, */ + /* set the excess values to~0.5 for Adobe MM fonts, and */ + /* to~0 for TrueType GX and OpenType variation fonts. */ + /* */ + /* <Output> */ + /* coords :: The normalized blend coordinates array. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ /* FT_Set_Var_Blend_Coordinates */ /* */ /* <Description> */ @@ -368,12 +464,26 @@ FT_BEGIN_HEADER FT_UInt num_coords, FT_Fixed* coords ); + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Var_Blend_Coordinates */ + /* */ + /* <Description> */ + /* This is another name of @FT_Get_MM_Blend_Coordinates. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Var_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + /* */ FT_END_HEADER -#endif /* __FTMM_H__ */ +#endif /* FTMM_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftmodapi.h b/third_party/freetype/include/freetype/ftmodapi.h index 544279a68a..d5bf376512 100644 --- a/third_party/freetype/include/freetype/ftmodapi.h +++ b/third_party/freetype/include/freetype/ftmodapi.h @@ -4,7 +4,7 @@ /* */ /* FreeType modules public interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTMODAPI_H__ -#define __FTMODAPI_H__ +#ifndef FTMODAPI_H_ +#define FTMODAPI_H_ #include <ft2build.h> @@ -111,12 +111,14 @@ FT_BEGIN_HEADER #define FT_MODULE_HINTER 4 /* this module is a glyph hinter */ #define FT_MODULE_STYLER 8 /* this module is a styler */ -#define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ +#define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ /* scalable fonts */ -#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ +#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ /* support vector outlines */ -#define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ +#define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ /* own hinter */ +#define FT_MODULE_DRIVER_HINTS_LIGHTLY 0x800 /* the driver's hinter */ + /* produces LIGHT hints */ /* deprecated values */ @@ -125,9 +127,10 @@ FT_BEGIN_HEADER #define ft_module_hinter FT_MODULE_HINTER #define ft_module_styler FT_MODULE_STYLER -#define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE -#define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES -#define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER +#define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE +#define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES +#define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER +#define ft_module_driver_hints_lightly FT_MODULE_DRIVER_HINTS_LIGHTLY typedef FT_Pointer FT_Module_Interface; @@ -610,12 +613,7 @@ FT_BEGIN_HEADER * The library doesn't implement any kind of bytecode interpreter. * * FT_TRUETYPE_ENGINE_TYPE_UNPATENTED :: - * The library implements a bytecode interpreter that doesn't - * support the patented operations of the TrueType virtual machine. - * - * Its main use is to load certain Asian fonts that position and - * scale glyph components with bytecode instructions. It produces - * bad output for most other fonts. + * Deprecated and removed. * * FT_TRUETYPE_ENGINE_TYPE_PATENTED :: * The library implements a bytecode interpreter that covers @@ -663,7 +661,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTMODAPI_H__ */ +#endif /* FTMODAPI_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftmoderr.h b/third_party/freetype/include/freetype/ftmoderr.h index 9d7f981409..7f608375e8 100644 --- a/third_party/freetype/include/freetype/ftmoderr.h +++ b/third_party/freetype/include/freetype/ftmoderr.h @@ -4,7 +4,7 @@ /* */ /* FreeType module error offsets (specification). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -74,7 +74,7 @@ /* with something like */ /* */ /* { */ - /* #undef __FTMODERR_H__ */ + /* #undef FTMODERR_H_ */ /* #define FT_MODERRDEF( e, v, s ) { FT_Mod_Err_ ## e, s }, */ /* #define FT_MODERR_START_LIST { */ /* #define FT_MODERR_END_LIST { 0, 0 } }; */ @@ -91,8 +91,8 @@ /*************************************************************************/ -#ifndef __FTMODERR_H__ -#define __FTMODERR_H__ +#ifndef FTMODERR_H_ +#define FTMODERR_H_ /*******************************************************************/ @@ -188,7 +188,7 @@ #undef FT_NEED_EXTERN_C -#endif /* __FTMODERR_H__ */ +#endif /* FTMODERR_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftotval.h b/third_party/freetype/include/freetype/ftotval.h index e744b713fb..b5d27cfe74 100644 --- a/third_party/freetype/include/freetype/ftotval.h +++ b/third_party/freetype/include/freetype/ftotval.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating OpenType tables (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,8 +27,8 @@ /***************************************************************************/ -#ifndef __FTOTVAL_H__ -#define __FTOTVAL_H__ +#ifndef FTOTVAL_H_ +#define FTOTVAL_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -106,12 +106,12 @@ FT_BEGIN_HEADER #define FT_VALIDATE_JSTF 0x1000 #define FT_VALIDATE_MATH 0x2000 -#define FT_VALIDATE_OT FT_VALIDATE_BASE | \ - FT_VALIDATE_GDEF | \ - FT_VALIDATE_GPOS | \ - FT_VALIDATE_GSUB | \ - FT_VALIDATE_JSTF | \ - FT_VALIDATE_MATH +#define FT_VALIDATE_OT ( FT_VALIDATE_BASE | \ + FT_VALIDATE_GDEF | \ + FT_VALIDATE_GPOS | \ + FT_VALIDATE_GSUB | \ + FT_VALIDATE_JSTF | \ + FT_VALIDATE_MATH ) /********************************************************************** * @@ -198,7 +198,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTOTVAL_H__ */ +#endif /* FTOTVAL_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftoutln.h b/third_party/freetype/include/freetype/ftoutln.h index b6ec70de8c..07f73ebb1b 100644 --- a/third_party/freetype/include/freetype/ftoutln.h +++ b/third_party/freetype/include/freetype/ftoutln.h @@ -5,7 +5,7 @@ /* Support for the FT_Outline type used to store glyph shapes of */ /* most scalable font formats (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __FTOUTLN_H__ -#define __FTOUTLN_H__ +#ifndef FTOUTLN_H_ +#define FTOUTLN_H_ #include <ft2build.h> @@ -115,6 +115,10 @@ FT_BEGIN_HEADER /* outline for stroking purposes (otherwise it would result in a */ /* visible dot when round caps are used). */ /* */ + /* Similarly, the function returns success for an empty outline also */ + /* (doing nothing, this is, not calling any emitter); if necessary, */ + /* you should filter this out, too. */ + /* */ FT_EXPORT( FT_Error ) FT_Outline_Decompose( FT_Outline* outline, const FT_Outline_Funcs* func_interface, @@ -213,6 +217,10 @@ FT_BEGIN_HEADER /* <Return> */ /* FreeType error code. 0~means success. */ /* */ + /* <Note> */ + /* An empty outline, or an outline with a single point only is also */ + /* valid. */ + /* */ FT_EXPORT( FT_Error ) FT_Outline_Check( FT_Outline* outline ); @@ -563,7 +571,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTOUTLN_H__ */ +#endif /* FTOUTLN_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftrender.h b/third_party/freetype/include/freetype/ftrender.h index ec8da700b1..960837580a 100644 --- a/third_party/freetype/include/freetype/ftrender.h +++ b/third_party/freetype/include/freetype/ftrender.h @@ -4,7 +4,7 @@ /* */ /* FreeType renderer modules public interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTRENDER_H__ -#define __FTRENDER_H__ +#ifndef FTRENDER_H_ +#define FTRENDER_H_ #include <ft2build.h> @@ -75,6 +75,7 @@ FT_BEGIN_HEADER { FT_Long glyph_size; FT_Glyph_Format glyph_format; + FT_Glyph_InitFunc glyph_init; FT_Glyph_DoneFunc glyph_done; FT_Glyph_CopyFunc glyph_copy; @@ -226,7 +227,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTRENDER_H__ */ +#endif /* FTRENDER_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftsizes.h b/third_party/freetype/include/freetype/ftsizes.h index bef8424715..2f3958a857 100644 --- a/third_party/freetype/include/freetype/ftsizes.h +++ b/third_party/freetype/include/freetype/ftsizes.h @@ -4,7 +4,7 @@ /* */ /* FreeType size objects management (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,8 +25,8 @@ /*************************************************************************/ -#ifndef __FTSIZES_H__ -#define __FTSIZES_H__ +#ifndef FTSIZES_H_ +#define FTSIZES_H_ #include <ft2build.h> @@ -153,7 +153,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSIZES_H__ */ +#endif /* FTSIZES_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftsnames.h b/third_party/freetype/include/freetype/ftsnames.h index 0f7fbe1744..f6daf8c7da 100644 --- a/third_party/freetype/include/freetype/ftsnames.h +++ b/third_party/freetype/include/freetype/ftsnames.h @@ -7,7 +7,7 @@ /* */ /* This is _not_ used to retrieve glyph names! */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,8 +19,8 @@ /***************************************************************************/ -#ifndef __FT_SFNT_NAMES_H__ -#define __FT_SFNT_NAMES_H__ +#ifndef FTSNAMES_H_ +#define FTSNAMES_H_ #include <ft2build.h> @@ -147,8 +147,8 @@ FT_BEGIN_HEADER /* */ /* <Note> */ /* The `string' array returned in the `aname' structure is not */ - /* null-terminated. The application should deallocate it if it is no */ - /* longer in use. */ + /* null-terminated. Note that you don't have to deallocate `string' */ + /* by yourself; FreeType takes care of it if you call @FT_Done_Face. */ /* */ /* Use @FT_Get_Sfnt_Name_Count to get the total number of available */ /* `name' table entries, then do a loop until you get the right */ @@ -194,7 +194,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FT_SFNT_NAMES_H__ */ +#endif /* FTSNAMES_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftsynth.h b/third_party/freetype/include/freetype/ftsynth.h index fbcbad871a..1863fa2383 100644 --- a/third_party/freetype/include/freetype/ftsynth.h +++ b/third_party/freetype/include/freetype/ftsynth.h @@ -5,7 +5,7 @@ /* FreeType synthesizing code for emboldening and slanting */ /* (specification). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,8 +41,8 @@ /* adapted to the particular needs. */ -#ifndef __FTSYNTH_H__ -#define __FTSYNTH_H__ +#ifndef FTSYNTH_H_ +#define FTSYNTH_H_ #include <ft2build.h> @@ -78,7 +78,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSYNTH_H__ */ +#endif /* FTSYNTH_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftsystem.h b/third_party/freetype/include/freetype/ftsystem.h index 2bc999910b..1aa4762ad6 100644 --- a/third_party/freetype/include/freetype/ftsystem.h +++ b/third_party/freetype/include/freetype/ftsystem.h @@ -4,7 +4,7 @@ /* */ /* FreeType low-level system interface definition (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTSYSTEM_H__ -#define __FTSYSTEM_H__ +#ifndef FTSYSTEM_H_ +#define FTSYSTEM_H_ #include <ft2build.h> @@ -290,7 +290,7 @@ FT_BEGIN_HEADER * The stream size in bytes. * * In case of compressed streams where the size is unknown before - * actually doing the decompression, the value is set to 0x7FFFFFFF. + * actually doing the decompression, the value is set to 0x7FFFFFFF. * (Note that this size value can occur for normal streams also; it is * thus just a hint.) * @@ -349,7 +349,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSYSTEM_H__ */ +#endif /* FTSYSTEM_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/fttrigon.h b/third_party/freetype/include/freetype/fttrigon.h index 485ec51587..89f0350675 100644 --- a/third_party/freetype/include/freetype/fttrigon.h +++ b/third_party/freetype/include/freetype/fttrigon.h @@ -4,7 +4,7 @@ /* */ /* FreeType trigonometric functions (specification). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTTRIGON_H__ -#define __FTTRIGON_H__ +#ifndef FTTRIGON_H_ +#define FTTRIGON_H_ #include FT_FREETYPE_H @@ -344,7 +344,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTTRIGON_H__ */ +#endif /* FTTRIGON_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ftttdrv.h b/third_party/freetype/include/freetype/ftttdrv.h index dc0081a0b9..a7b937fa53 100644 --- a/third_party/freetype/include/freetype/ftttdrv.h +++ b/third_party/freetype/include/freetype/ftttdrv.h @@ -5,7 +5,7 @@ /* FreeType API for controlling the TrueType driver */ /* (specification only). */ /* */ -/* Copyright 2013-2015 by */ +/* Copyright 2013-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __FTTTDRV_H__ -#define __FTTTDRV_H__ +#ifndef FTTTDRV_H_ +#define FTTTDRV_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -138,31 +138,37 @@ FT_BEGIN_HEADER * interpreter-version * * @description: - * Currently, two versions are available, representing the bytecode - * interpreter with and without subpixel hinting support, - * respectively. The default is subpixel support if - * TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel - * support otherwise (since it isn't available then). + + * Currently, three versions are available, two representing the + * bytecode interpreter with subpixel hinting support (old `Infinality' + * code and new stripped-down and higher performance `minimal' code) and + * one without, respectively. The default is subpixel support if + * TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel support + * otherwise (since it isn't available then). * * If subpixel hinting is on, many TrueType bytecode instructions behave * differently compared to B/W or grayscale rendering (except if `native - * ClearType' is selected by the font). The main idea is to render at a - * much increased horizontal resolution, then sampling down the created - * output to subpixel precision. However, many older fonts are not - * suited to this and must be specially taken care of by applying - * (hardcoded) font-specific tweaks. + * ClearType' is selected by the font). Microsoft's main idea is to + * render at a much increased horizontal resolution, then sampling down + * the created output to subpixel precision. However, many older fonts + * are not suited to this and must be specially taken care of by + * applying (hardcoded) tweaks in Microsoft's interpreter. * * Details on subpixel hinting and some of the necessary tweaks can be * found in Greg Hitchcock's whitepaper at - * `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'. + * `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'. + * Note that FreeType currently doesn't really `subpixel hint' (6x1, 6x2, + * or 6x5 supersampling) like discussed in the paper. Depending on the + * chosen interpreter, it simply ignores instructions on vertical stems + * to arrive at very similar results. * - * The following example code demonstrates how to activate subpixel + * The following example code demonstrates how to deactivate subpixel * hinting (omitting the error handling). * * { * FT_Library library; * FT_Face face; - * FT_UInt interpreter_version = TT_INTERPRETER_VERSION_38; + * FT_UInt interpreter_version = TT_INTERPRETER_VERSION_35; * * * FT_Init_FreeType( &library ); @@ -175,6 +181,8 @@ FT_BEGIN_HEADER * @note: * This property can be used with @FT_Property_Get also. * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable (using values `35', `38', or `40'). */ @@ -197,9 +205,19 @@ FT_BEGIN_HEADER * * TT_INTERPRETER_VERSION_38 :: * Version~38 corresponds to MS rasterizer v.1.9; it is roughly - * equivalent to the hinting provided by DirectWrite ClearType (as - * can be found, for example, in the Internet Explorer~9 running on - * Windows~7). + * equivalent to the hinting provided by DirectWrite ClearType (as can + * be found, for example, in the Internet Explorer~9 running on + * Windows~7). It is used in FreeType to select the `Infinality' + * subpixel hinting code. The code may be removed in a future + * version. + * + * TT_INTERPRETER_VERSION_40 :: + * Version~40 corresponds to MS rasterizer v.2.1; it is roughly + * equivalent to the hinting provided by DirectWrite ClearType (as can + * be found, for example, in Microsoft's Edge Browser on Windows~10). + * It is used in FreeType to select the `minimal' subpixel hinting + * code, a stripped-down and higher performance version of the + * `Infinality' code. * * @note: * This property controls the behaviour of the bytecode interpreter @@ -207,9 +225,9 @@ FT_BEGIN_HEADER * get rasterized! In particular, it does not control subpixel color * filtering. * - * If FreeType has not been compiled with configuration option - * FT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 causes an - * `FT_Err_Unimplemented_Feature' error. + * If FreeType has not been compiled with the configuration option + * FT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 or~40 causes + * an `FT_Err_Unimplemented_Feature' error. * * Depending on the graphics framework, Microsoft uses different * bytecode and rendering engines. As a consequence, the version @@ -290,13 +308,14 @@ FT_BEGIN_HEADER * the version~1 gasp table exclusively (like Color ClearType), while * v1.6 only respects the values of version~0 (bits 0 and~1). * - * FreeType doesn't provide all capabilities of the most recent - * ClearType incarnation, thus we identify our subpixel support as - * version~38. + * Keep in mind that the features of the above interpreter versions + * might not map exactly to FreeType features or behavior because it is + * a fundamentally different library with different internals. * */ #define TT_INTERPRETER_VERSION_35 35 #define TT_INTERPRETER_VERSION_38 38 +#define TT_INTERPRETER_VERSION_40 40 /* */ @@ -304,7 +323,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTTTDRV_H__ */ +#endif /* FTTTDRV_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/fttypes.h b/third_party/freetype/include/freetype/fttypes.h index 706a1be4ef..eab8adaad4 100644 --- a/third_party/freetype/include/freetype/fttypes.h +++ b/third_party/freetype/include/freetype/fttypes.h @@ -4,7 +4,7 @@ /* */ /* FreeType simple types definitions (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTTYPES_H__ -#define __FTTYPES_H__ +#ifndef FTTYPES_H_ +#define FTTYPES_H_ #include <ft2build.h> @@ -596,7 +596,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTTYPES_H__ */ +#endif /* FTTYPES_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/autohint.h b/third_party/freetype/include/freetype/internal/autohint.h index 8d5a9773cb..bae83e7384 100644 --- a/third_party/freetype/include/freetype/internal/autohint.h +++ b/third_party/freetype/include/freetype/internal/autohint.h @@ -4,7 +4,7 @@ /* */ /* High-level `autohint' module-specific interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,8 +24,8 @@ /*************************************************************************/ -#ifndef __AUTOHINT_H__ -#define __AUTOHINT_H__ +#ifndef AUTOHINT_H_ +#define AUTOHINT_H_ /*************************************************************************/ @@ -238,7 +238,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AUTOHINT_H__ */ +#endif /* AUTOHINT_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/ftcalc.h b/third_party/freetype/include/freetype/internal/ftcalc.h index 67ade7e5f9..c9ac9d8246 100644 --- a/third_party/freetype/include/freetype/internal/ftcalc.h +++ b/third_party/freetype/include/freetype/internal/ftcalc.h @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTCALC_H__ -#define __FTCALC_H__ +#ifndef FTCALC_H_ +#define FTCALC_H_ #include <ft2build.h> @@ -47,7 +47,7 @@ FT_BEGIN_HEADER FT_MulFix_arm( FT_Int32 a, FT_Int32 b ) { - register FT_Int32 t, t2; + FT_Int32 t, t2; __asm @@ -80,7 +80,7 @@ FT_BEGIN_HEADER FT_MulFix_arm( FT_Int32 a, FT_Int32 b ) { - register FT_Int32 t, t2; + FT_Int32 t, t2; __asm__ __volatile__ ( @@ -116,7 +116,7 @@ FT_BEGIN_HEADER FT_MulFix_i386( FT_Int32 a, FT_Int32 b ) { - register FT_Int32 result; + FT_Int32 result; __asm__ __volatile__ ( @@ -152,7 +152,7 @@ FT_BEGIN_HEADER FT_MulFix_i386( FT_Int32 a, FT_Int32 b ) { - register FT_Int32 result; + FT_Int32 result; __asm { @@ -412,7 +412,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCALC_H__ */ +#endif /* FTCALC_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/ftdebug.h b/third_party/freetype/include/freetype/internal/ftdebug.h index 216c73031e..5dcd2b1740 100644 --- a/third_party/freetype/include/freetype/internal/ftdebug.h +++ b/third_party/freetype/include/freetype/internal/ftdebug.h @@ -4,7 +4,7 @@ /* */ /* Debugging and logging component (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,8 +21,8 @@ /***************************************************************************/ -#ifndef __FTDEBUG_H__ -#define __FTDEBUG_H__ +#ifndef FTDEBUG_H_ +#define FTDEBUG_H_ #include <ft2build.h> @@ -249,7 +249,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTDEBUG_H__ */ +#endif /* FTDEBUG_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/ftdriver.h b/third_party/freetype/include/freetype/internal/ftdriver.h index 16856d3df8..e82fa8d41f 100644 --- a/third_party/freetype/include/freetype/internal/ftdriver.h +++ b/third_party/freetype/include/freetype/internal/ftdriver.h @@ -4,7 +4,7 @@ /* */ /* FreeType font driver interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTDRIVER_H__ -#define __FTDRIVER_H__ +#ifndef FTDRIVER_H_ +#define FTDRIVER_H_ #include <ft2build.h> @@ -67,15 +67,6 @@ FT_BEGIN_HEADER FT_Int32 load_flags ); - typedef FT_UInt - (*FT_CharMap_CharIndexFunc)( FT_CharMap charmap, - FT_Long charcode ); - - typedef FT_Long - (*FT_CharMap_CharNextFunc)( FT_CharMap charmap, - FT_Long charcode ); - - typedef FT_Error (*FT_Face_GetKerningFunc)( FT_Face face, FT_UInt left_glyph, @@ -213,7 +204,7 @@ FT_BEGIN_HEADER /* And when it is no longer needed a `destroy' function needs to be */ /* called to release that allocation. */ /* */ - /* `fcinit.c' (ft_create_default_module_classes) already contains a */ + /* `ftinit.c' (ft_create_default_module_classes) already contains a */ /* mechanism to call these functions for the default modules */ /* described in `ftmodule.h'. */ /* */ @@ -403,7 +394,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTDRIVER_H__ */ +#endif /* FTDRIVER_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/ftgloadr.h b/third_party/freetype/include/freetype/internal/ftgloadr.h index 970dd70cc3..f41c3df554 100644 --- a/third_party/freetype/include/freetype/internal/ftgloadr.h +++ b/third_party/freetype/include/freetype/internal/ftgloadr.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph loader (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTGLOADR_H__ -#define __FTGLOADR_H__ +#ifndef FTGLOADR_H_ +#define FTGLOADR_H_ #include <ft2build.h> @@ -36,24 +36,6 @@ FT_BEGIN_HEADER /* The glyph loader is an internal object used to load several glyphs */ /* together (for example, in the case of composites). */ /* */ - /* <Note> */ - /* The glyph loader implementation is not part of the high-level API, */ - /* hence the forward structure declaration. */ - /* */ - typedef struct FT_GlyphLoaderRec_* FT_GlyphLoader ; - - -#if 0 /* moved to freetype.h in version 2.2 */ -#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 -#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 -#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 -#define FT_SUBGLYPH_FLAG_SCALE 8 -#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 -#define FT_SUBGLYPH_FLAG_2X2 0x80 -#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 -#endif - - typedef struct FT_SubGlyphRec_ { FT_Int index; @@ -89,7 +71,7 @@ FT_BEGIN_HEADER void* other; /* for possible future extension? */ - } FT_GlyphLoaderRec; + } FT_GlyphLoaderRec, *FT_GlyphLoader; /* create new empty glyph loader */ @@ -166,7 +148,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTGLOADR_H__ */ +#endif /* FTGLOADR_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/fthash.h b/third_party/freetype/include/freetype/internal/fthash.h new file mode 100644 index 0000000000..f22f9d5d39 --- /dev/null +++ b/third_party/freetype/include/freetype/internal/fthash.h @@ -0,0 +1,136 @@ +/***************************************************************************/ +/* */ +/* fthash.h */ +/* */ +/* Hashing functions (specification). */ +/* */ +/***************************************************************************/ + +/* + * Copyright 2000 Computing Research Labs, New Mexico State University + * Copyright 2001-2015 + * 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 to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + /*************************************************************************/ + /* */ + /* This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50 */ + /* */ + /* taken from Mark Leisher's xmbdfed package */ + /* */ + /*************************************************************************/ + + +#ifndef FTHASH_H_ +#define FTHASH_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + typedef union FT_Hashkey_ + { + FT_Int num; + const char* str; + + } FT_Hashkey; + + + typedef struct FT_HashnodeRec_ + { + FT_Hashkey key; + size_t data; + + } FT_HashnodeRec; + + typedef struct FT_HashnodeRec_ *FT_Hashnode; + + + typedef FT_ULong + (*FT_Hash_LookupFunc)( FT_Hashkey* key ); + + typedef FT_Bool + (*FT_Hash_CompareFunc)( FT_Hashkey* a, + FT_Hashkey* b ); + + + typedef struct FT_HashRec_ + { + FT_UInt limit; + FT_UInt size; + FT_UInt used; + + FT_Hash_LookupFunc lookup; + FT_Hash_CompareFunc compare; + + FT_Hashnode* table; + + } FT_HashRec; + + typedef struct FT_HashRec_ *FT_Hash; + + + FT_Error + ft_hash_str_init( FT_Hash hash, + FT_Memory memory ); + + FT_Error + ft_hash_num_init( FT_Hash hash, + FT_Memory memory ); + + void + ft_hash_str_free( FT_Hash hash, + FT_Memory memory ); + +#define ft_hash_num_free ft_hash_str_free + + FT_Error + ft_hash_str_insert( const char* key, + size_t data, + FT_Hash hash, + FT_Memory memory ); + + FT_Error + ft_hash_num_insert( FT_Int num, + size_t data, + FT_Hash hash, + FT_Memory memory ); + + size_t* + ft_hash_str_lookup( const char* key, + FT_Hash hash ); + + size_t* + ft_hash_num_lookup( FT_Int num, + FT_Hash hash ); + + +FT_END_HEADER + + +#endif /* FTHASH_H_ */ + + +/* END */ diff --git a/third_party/freetype/include/freetype/internal/ftmemory.h b/third_party/freetype/include/freetype/internal/ftmemory.h index c0c553b4fc..59e5b58a57 100644 --- a/third_party/freetype/include/freetype/internal/ftmemory.h +++ b/third_party/freetype/include/freetype/internal/ftmemory.h @@ -4,7 +4,7 @@ /* */ /* The FreeType memory management macros (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTMEMORY_H__ -#define __FTMEMORY_H__ +#ifndef FTMEMORY_H_ +#define FTMEMORY_H_ #include <ft2build.h> @@ -65,13 +65,15 @@ FT_BEGIN_HEADER #ifdef __cplusplus - extern "C++" +extern "C++" +{ template <typename T> inline T* cplusplus_typeof( T*, void *v ) { return static_cast <T*> ( v ); } +} #define FT_ASSIGNP( p, val ) (p) = cplusplus_typeof( (p), (val) ) @@ -106,10 +108,12 @@ FT_BEGIN_HEADER /* * The allocation functions return a pointer, and the error code - * is written to through the `p_error' parameter. See below for - * for documentation. + * is written to through the `p_error' parameter. */ + /* The `q' variants of the functions below (`q' for `quick') don't fill */ + /* the allocated or reallocated memory with zero bytes. */ + FT_BASE( FT_Pointer ) ft_mem_alloc( FT_Memory memory, FT_Long size, @@ -141,6 +145,9 @@ FT_BEGIN_HEADER const void* P ); + /* The `Q' variants of the macros below (`Q' for `quick') don't fill */ + /* the allocated or reallocated memory with zero bytes. */ + #define FT_MEM_ALLOC( ptr, size ) \ FT_ASSIGNP_INNER( ptr, ft_mem_alloc( memory, \ (FT_Long)(size), \ @@ -380,7 +387,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTMEMORY_H__ */ +#endif /* FTMEMORY_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/ftobjs.h b/third_party/freetype/include/freetype/internal/ftobjs.h index da5582dc3f..772d82c315 100644 --- a/third_party/freetype/include/freetype/internal/ftobjs.h +++ b/third_party/freetype/include/freetype/internal/ftobjs.h @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,8 +23,8 @@ /*************************************************************************/ -#ifndef __FTOBJS_H__ -#define __FTOBJS_H__ +#ifndef FTOBJS_H_ +#define FTOBJS_H_ #include <ft2build.h> #include FT_RENDER_H @@ -193,6 +193,7 @@ FT_BEGIN_HEADER typedef struct FT_CMap_ClassRec_ { FT_ULong size; + FT_CMap_InitFunc init; FT_CMap_DoneFunc done; FT_CMap_CharIndexFunc char_index; @@ -341,12 +342,6 @@ 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. */ - /* */ /* refcount :: */ /* A counter initialized to~1 at the time an @FT_Face structure is */ /* created. @FT_Reference_Face increments this counter, and */ @@ -365,7 +360,6 @@ FT_BEGIN_HEADER FT_Incremental_InterfaceRec* incremental_interface; #endif - FT_Bool ignore_unpatented_hinter; FT_Int refcount; } FT_Face_InternalRec; @@ -506,6 +500,9 @@ FT_BEGIN_HEADER #define FT_DRIVER_HAS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ FT_MODULE_DRIVER_HAS_HINTER ) +#define FT_DRIVER_HINTS_LIGHTLY( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_HINTS_LIGHTLY ) + /*************************************************************************/ /* */ @@ -534,7 +531,16 @@ FT_BEGIN_HEADER FT_BASE( FT_Pointer ) ft_module_get_service( FT_Module module, - const char* service_id ); + const char* service_id, + FT_Bool global ); + +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + FT_BASE( FT_Error ) + ft_property_string_set( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + FT_String* value ); +#endif /* */ @@ -772,13 +778,6 @@ FT_BEGIN_HEADER #define FT_DEBUG_HOOK_TRUETYPE 0 - /* Set this debug hook to a non-null pointer to force unpatented hinting */ - /* 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 ); @@ -844,7 +843,7 @@ FT_BEGIN_HEADER /* filtering callback function. */ /* */ /* pic_container :: Contains global structs and tables, instead */ - /* of defining them globallly. */ + /* of defining them globally. */ /* */ /* refcount :: A counter initialized to~1 at the time an */ /* @FT_Library structure is created. */ @@ -877,7 +876,7 @@ FT_BEGIN_HEADER #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_Byte lcd_weights[5]; /* filter weights, if any */ FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */ #endif @@ -982,8 +981,8 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Used to initialize an instance of FT_Outline_Funcs struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ - /* be called with a pre-allocated structure to be filled. */ + /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ + /* to be called with a pre-allocated structure to be filled. */ /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ /* allocated in the global scope (or the scope where the macro */ /* is used). */ @@ -1041,8 +1040,8 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Used to initialize an instance of FT_Raster_Funcs struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ - /* be called with a pre-allocated structure to be filled. */ + /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ + /* to be called with a pre-allocated structure to be filled. */ /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ /* allocated in the global scope (or the scope where the macro */ /* is used). */ @@ -1101,8 +1100,8 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Used to initialize an instance of FT_Glyph_Class struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ - /* be called with a pre-allocated stcture to be filled. */ + /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ + /* to be called with a pre-allocated structure to be filled. */ /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ /* allocated in the global scope (or the scope where the macro */ /* is used). */ @@ -1175,11 +1174,11 @@ FT_BEGIN_HEADER /* <Description> */ /* Used to initialize an instance of FT_Renderer_Class struct. */ /* */ - /* When FT_CONFIG_OPTION_PIC is defined a `create' funtion will need */ - /* to be called with a pointer where the allocated structure is */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' function will */ + /* need to be called with a pointer where the allocated structure is */ /* returned. And when it is no longer needed a `destroy' function */ /* needs to be called to release that allocation. */ - /* `fcinit.c' (ft_create_default_module_classes) already contains */ + /* `ftinit.c' (ft_create_default_module_classes) already contains */ /* a mechanism to call these functions for the default modules */ /* described in `ftmodule.h'. */ /* */ @@ -1379,11 +1378,11 @@ FT_BEGIN_HEADER /* <Description> */ /* Used to initialize an instance of an FT_Module_Class struct. */ /* */ - /* When FT_CONFIG_OPTION_PIC is defined a `create' funtion needs to */ - /* be called with a pointer where the allocated structure is */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' function needs */ + /* to be called with a pointer where the allocated structure is */ /* returned. And when it is no longer needed a `destroy' function */ /* needs to be called to release that allocation. */ - /* `fcinit.c' (ft_create_default_module_classes) already contains */ + /* `ftinit.c' (ft_create_default_module_classes) already contains */ /* a mechanism to call these functions for the default modules */ /* described in `ftmodule.h'. */ /* */ @@ -1565,7 +1564,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTOBJS_H__ */ +#endif /* FTOBJS_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/ftpic.h b/third_party/freetype/include/freetype/internal/ftpic.h index 7f9154f419..0d43ed20f7 100644 --- a/third_party/freetype/include/freetype/internal/ftpic.h +++ b/third_party/freetype/include/freetype/internal/ftpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services (declaration). */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,8 +23,8 @@ /*************************************************************************/ -#ifndef __FTPIC_H__ -#define __FTPIC_H__ +#ifndef FTPIC_H_ +#define FTPIC_H_ FT_BEGIN_HEADER @@ -65,7 +65,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTPIC_H__ */ +#endif /* FTPIC_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/ftrfork.h b/third_party/freetype/include/freetype/internal/ftrfork.h index da61ca75b5..25a44a4487 100644 --- a/third_party/freetype/include/freetype/internal/ftrfork.h +++ b/third_party/freetype/include/freetype/internal/ftrfork.h @@ -4,7 +4,7 @@ /* */ /* Embedded resource forks accessor (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2017 by */ /* Masatake YAMATO and Redhat K.K. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,8 +21,8 @@ /***************************************************************************/ -#ifndef __FTRFORK_H__ -#define __FTRFORK_H__ +#ifndef FTRFORK_H_ +#define FTRFORK_H_ #include <ft2build.h> @@ -43,11 +43,12 @@ FT_BEGIN_HEADER typedef struct FT_RFork_Ref_ { - FT_UShort res_id; - FT_Long offset; + FT_Short res_id; + FT_Long offset; } FT_RFork_Ref; + #ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK typedef FT_Error (*ft_raccess_guess_func)( FT_Library library, @@ -227,7 +228,7 @@ FT_BEGIN_HEADER /* sort_by_res_id :: */ /* A Boolean to sort the fragmented resource by their ids. */ /* The fragmented resources for `POST' resource should be sorted */ - /* to restore Type1 font properly. For `snft' resources, sorting */ + /* to restore Type1 font properly. For `sfnt' resources, sorting */ /* may induce a different order of the faces in comparison to that */ /* by QuickDraw API. */ /* */ @@ -260,7 +261,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTRFORK_H__ */ +#endif /* FTRFORK_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/ftserv.h b/third_party/freetype/include/freetype/internal/ftserv.h index 11a0c7f3de..c84afba4a8 100644 --- a/third_party/freetype/include/freetype/internal/ftserv.h +++ b/third_party/freetype/include/freetype/internal/ftserv.h @@ -4,7 +4,7 @@ /* */ /* The FreeType services (specification only). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -28,8 +28,8 @@ /*************************************************************************/ -#ifndef __FTSERV_H__ -#define __FTSERV_H__ +#ifndef FTSERV_H_ +#define FTSERV_H_ FT_BEGIN_HEADER @@ -109,27 +109,27 @@ FT_BEGIN_HEADER */ #ifdef __cplusplus -#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ - FT_BEGIN_STMNT \ - FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ - FT_Pointer _tmp_; \ - FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ - \ - \ - _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ - *_pptr_ = _tmp_; \ +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_; \ + FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ + \ + \ + _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \ + *_pptr_ = _tmp_; \ FT_END_STMNT #else /* !C++ */ -#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ - FT_BEGIN_STMNT \ - FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ - FT_Pointer _tmp_; \ - \ - \ - _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ - ptr = _tmp_; \ +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_; \ + \ + \ + _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \ + ptr = _tmp_; \ FT_END_STMNT #endif /* !C++ */ @@ -167,6 +167,7 @@ FT_BEGIN_HEADER /* FT_DEFINE_SERVICEDESCREC5 */ /* FT_DEFINE_SERVICEDESCREC6 */ /* FT_DEFINE_SERVICEDESCREC7 */ + /* FT_DEFINE_SERVICEDESCREC8 */ /* */ /* <Description> */ /* Used to initialize an array of FT_ServiceDescRec structures. */ @@ -283,6 +284,28 @@ FT_BEGIN_HEADER { NULL, NULL } \ }; +#define FT_DEFINE_SERVICEDESCREC8( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6, \ + serv_id_7, serv_data_7, \ + serv_id_8, serv_data_8 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { serv_id_3, serv_data_3 }, \ + { serv_id_4, serv_data_4 }, \ + { serv_id_5, serv_data_5 }, \ + { serv_id_6, serv_data_6 }, \ + { serv_id_7, serv_data_7 }, \ + { serv_id_8, serv_data_8 }, \ + { NULL, NULL } \ + }; + #else /* FT_CONFIG_OPTION_PIC */ #define FT_DEFINE_SERVICEDESCREC1( class_, \ @@ -593,6 +616,62 @@ FT_BEGIN_HEADER return FT_Err_Ok; \ } +#define FT_DEFINE_SERVICEDESCREC8( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6, \ + serv_id_7, serv_data_7, \ + serv_id_8, serv_data_8 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 9 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = serv_id_5; \ + clazz[4].serv_data = serv_data_5; \ + clazz[5].serv_id = serv_id_6; \ + clazz[5].serv_data = serv_data_6; \ + clazz[6].serv_id = serv_id_7; \ + clazz[6].serv_data = serv_data_7; \ + clazz[7].serv_id = serv_id_8; \ + clazz[7].serv_data = serv_data_8; \ + clazz[8].serv_id = NULL; \ + clazz[8].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + #endif /* FT_CONFIG_OPTION_PIC */ @@ -635,6 +714,7 @@ FT_BEGIN_HEADER { FT_Pointer service_POSTSCRIPT_FONT_NAME; FT_Pointer service_MULTI_MASTERS; + FT_Pointer service_METRICS_VARIATIONS; FT_Pointer service_GLYPH_DICT; FT_Pointer service_PFR_METRICS; FT_Pointer service_WINFNT; @@ -739,6 +819,7 @@ FT_BEGIN_HEADER #define FT_SERVICE_GLYPH_DICT_H <freetype/internal/services/svgldict.h> #define FT_SERVICE_GX_VALIDATE_H <freetype/internal/services/svgxval.h> #define FT_SERVICE_KERNING_H <freetype/internal/services/svkern.h> +#define FT_SERVICE_METRICS_VARIATIONS_H <freetype/internal/services/svmetric.h> #define FT_SERVICE_MULTIPLE_MASTERS_H <freetype/internal/services/svmm.h> #define FT_SERVICE_OPENTYPE_VALIDATE_H <freetype/internal/services/svotval.h> #define FT_SERVICE_PFR_H <freetype/internal/services/svpfr.h> @@ -757,7 +838,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSERV_H__ */ +#endif /* FTSERV_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/ftstream.h b/third_party/freetype/include/freetype/internal/ftstream.h index 384e5df305..02b2f0bc90 100644 --- a/third_party/freetype/include/freetype/internal/ftstream.h +++ b/third_party/freetype/include/freetype/internal/ftstream.h @@ -4,7 +4,7 @@ /* */ /* Stream handling (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTSTREAM_H__ -#define __FTSTREAM_H__ +#ifndef FTSTREAM_H_ +#define FTSTREAM_H_ #include <ft2build.h> @@ -530,7 +530,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSTREAM_H__ */ +#endif /* FTSTREAM_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/ftvalid.h b/third_party/freetype/include/freetype/internal/ftvalid.h index 9cda6eef5f..df6f7c5778 100644 --- a/third_party/freetype/include/freetype/internal/ftvalid.h +++ b/third_party/freetype/include/freetype/internal/ftvalid.h @@ -4,7 +4,7 @@ /* */ /* FreeType validation support (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTVALID_H__ -#define __FTVALID_H__ +#ifndef FTVALID_H_ +#define FTVALID_H_ #include <ft2build.h> #include FT_CONFIG_STANDARD_LIBRARY_H /* for ft_setjmp and ft_longjmp */ @@ -153,7 +153,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTVALID_H__ */ +#endif /* FTVALID_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/internal.h b/third_party/freetype/include/freetype/internal/internal.h index 809ce59c92..02046813a3 100644 --- a/third_party/freetype/include/freetype/internal/internal.h +++ b/third_party/freetype/include/freetype/internal/internal.h @@ -4,7 +4,7 @@ /* */ /* Internal header files (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,6 +30,7 @@ #define FT_INTERNAL_MEMORY_H <freetype/internal/ftmemory.h> #define FT_INTERNAL_DEBUG_H <freetype/internal/ftdebug.h> #define FT_INTERNAL_CALC_H <freetype/internal/ftcalc.h> +#define FT_INTERNAL_HASH_H <freetype/internal/fthash.h> #define FT_INTERNAL_DRIVER_H <freetype/internal/ftdriver.h> #define FT_INTERNAL_TRACE_H <freetype/internal/fttrace.h> #define FT_INTERNAL_GLYPH_LOADER_H <freetype/internal/ftgloadr.h> @@ -43,7 +44,6 @@ #define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h> #define FT_INTERNAL_POSTSCRIPT_HINTS_H <freetype/internal/pshints.h> -#define FT_INTERNAL_POSTSCRIPT_GLOBALS_H <freetype/internal/psglobal.h> #define FT_INTERNAL_AUTOHINT_H <freetype/internal/autohint.h> diff --git a/third_party/freetype/include/freetype/internal/psaux.h b/third_party/freetype/include/freetype/internal/psaux.h index 1c5f784f52..286d6040cb 100644 --- a/third_party/freetype/include/freetype/internal/psaux.h +++ b/third_party/freetype/include/freetype/internal/psaux.h @@ -5,7 +5,7 @@ /* Auxiliary functions and data structures related to PostScript fonts */ /* (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,13 +17,14 @@ /***************************************************************************/ -#ifndef __PSAUX_H__ -#define __PSAUX_H__ +#ifndef PSAUX_H_ +#define PSAUX_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_HASH_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H @@ -678,6 +679,7 @@ FT_BEGIN_HEADER FT_Int num_subrs; FT_Byte** subrs; FT_UInt* subrs_len; /* array of subrs length (optional) */ + FT_Hash subrs_hash; /* used if `num_subrs' was massaged */ FT_Matrix font_matrix; FT_Vector font_offset; @@ -871,7 +873,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSAUX_H__ */ +#endif /* PSAUX_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/pshints.h b/third_party/freetype/include/freetype/internal/pshints.h index 12aaabacd4..49116eb443 100644 --- a/third_party/freetype/include/freetype/internal/pshints.h +++ b/third_party/freetype/include/freetype/internal/pshints.h @@ -6,7 +6,7 @@ /* recorders (specification only). These are used to support native */ /* T1/T2 hints in the `type1', `cid', and `cff' font drivers. */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,8 +18,8 @@ /***************************************************************************/ -#ifndef __PSHINTS_H__ -#define __PSHINTS_H__ +#ifndef PSHINTS_H_ +#define PSHINTS_H_ #include <ft2build.h> @@ -716,7 +716,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSHINTS_H__ */ +#endif /* PSHINTS_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/services/svcid.h b/third_party/freetype/include/freetype/internal/services/svcid.h index 4a535a6f42..cce94d8df6 100644 --- a/third_party/freetype/include/freetype/internal/services/svcid.h +++ b/third_party/freetype/include/freetype/internal/services/svcid.h @@ -4,7 +4,7 @@ /* */ /* The FreeType CID font services (specification). */ /* */ -/* Copyright 2007-2015 by */ +/* Copyright 2007-2017 by */ /* Derek Clegg and Michael Toftdal. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVCID_H__ -#define __SVCID_H__ +#ifndef SVCID_H_ +#define SVCID_H_ #include FT_INTERNAL_SERVICE_H @@ -84,7 +84,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVCID_H__ */ +#endif /* SVCID_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/services/svfntfmt.h b/third_party/freetype/include/freetype/internal/services/svfntfmt.h index f8b3617364..376d9255bb 100644 --- a/third_party/freetype/include/freetype/internal/services/svfntfmt.h +++ b/third_party/freetype/include/freetype/internal/services/svfntfmt.h @@ -4,7 +4,7 @@ /* */ /* The FreeType font format service (specification only). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVFNTFMT_H__ -#define __SVFNTFMT_H__ +#ifndef SVFNTFMT_H_ +#define SVFNTFMT_H_ #include FT_INTERNAL_SERVICE_H @@ -49,7 +49,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVFNTFMT_H__ */ +#endif /* SVFNTFMT_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/services/svgldict.h b/third_party/freetype/include/freetype/internal/services/svgldict.h index f78bca5d77..0cd13618d8 100644 --- a/third_party/freetype/include/freetype/internal/services/svgldict.h +++ b/third_party/freetype/include/freetype/internal/services/svgldict.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph dictionary services (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVGLDICT_H__ -#define __SVGLDICT_H__ +#ifndef SVGLDICT_H_ +#define SVGLDICT_H_ #include FT_INTERNAL_SERVICE_H @@ -85,4 +85,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVGLDICT_H__ */ +#endif /* SVGLDICT_H_ */ + + +/* END */ diff --git a/third_party/freetype/include/freetype/internal/services/svkern.h b/third_party/freetype/include/freetype/internal/services/svkern.h index bc26f15941..b8344e96e9 100644 --- a/third_party/freetype/include/freetype/internal/services/svkern.h +++ b/third_party/freetype/include/freetype/internal/services/svkern.h @@ -4,7 +4,7 @@ /* */ /* The FreeType Kerning service (specification). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVKERN_H__ -#define __SVKERN_H__ +#ifndef SVKERN_H_ +#define SVKERN_H_ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -45,7 +45,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVKERN_H__ */ +#endif /* SVKERN_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/services/svmetric.h b/third_party/freetype/include/freetype/internal/services/svmetric.h new file mode 100644 index 0000000000..cac9bf88ba --- /dev/null +++ b/third_party/freetype/include/freetype/internal/services/svmetric.h @@ -0,0 +1,153 @@ +/***************************************************************************/ +/* */ +/* svmetric.h */ +/* */ +/* The FreeType services for metrics variations (specification). */ +/* */ +/* Copyright 2016-2017 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 SVMETRIC_H_ +#define SVMETRIC_H_ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A service to manage the `HVAR, `MVAR', and `VVAR' OpenType tables. + * + */ + +#define FT_SERVICE_ID_METRICS_VARIATIONS "metrics-variations" + + + /* HVAR */ + + typedef FT_Error + (*FT_HAdvance_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + typedef FT_Error + (*FT_LSB_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + typedef FT_Error + (*FT_RSB_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + /* VVAR */ + + typedef FT_Error + (*FT_VAdvance_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + typedef FT_Error + (*FT_TSB_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + typedef FT_Error + (*FT_BSB_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + typedef FT_Error + (*FT_VOrg_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + /* MVAR */ + + typedef void + (*FT_Metrics_Adjust_Func)( FT_Face face ); + + + FT_DEFINE_SERVICE( MetricsVariations ) + { + FT_HAdvance_Adjust_Func hadvance_adjust; + FT_LSB_Adjust_Func lsb_adjust; + FT_RSB_Adjust_Func rsb_adjust; + + FT_VAdvance_Adjust_Func vadvance_adjust; + FT_TSB_Adjust_Func tsb_adjust; + FT_BSB_Adjust_Func bsb_adjust; + FT_VOrg_Adjust_Func vorg_adjust; + + FT_Metrics_Adjust_Func metrics_adjust; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_METRICSVARIATIONSREC( class_, \ + hadvance_adjust_, \ + lsb_adjust_, \ + rsb_adjust_, \ + vadvance_adjust_, \ + tsb_adjust_, \ + bsb_adjust_, \ + vorg_adjust_, \ + metrics_adjust_ ) \ + static const FT_Service_MetricsVariationsRec class_ = \ + { \ + hadvance_adjust_, \ + lsb_adjust_, \ + rsb_adjust_, \ + vadvance_adjust_, \ + tsb_adjust_, \ + bsb_adjust_, \ + vorg_adjust_, \ + metrics_adjust_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_METRICSVARIATIONSREC( class_, \ + hadvance_adjust_, \ + lsb_adjust_, \ + rsb_adjust_, \ + vadvance_adjust_, \ + tsb_adjust_, \ + bsb_adjust_, \ + vorg_adjust_, \ + metrics_adjust_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_MetricsVariationsRec* clazz ) \ + { \ + clazz->hadvance_adjust = hadvance_adjust_; \ + clazz->lsb_adjust = lsb_adjust_; \ + clazz->rsb_adjust = rsb_adjust_; \ + clazz->vadvance_adjust = vadvance_adjust_; \ + clazz->tsb_adjust = tsb_adjust_; \ + clazz->bsb_adjust = bsb_adjust_; \ + clazz->vorg_adjust = vorg_adjust_; \ + clazz->metrics_adjust = metrics_adjust_; \ + }; + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + +#endif /* SVMETRIC_H_ */ + + +/* END */ diff --git a/third_party/freetype/include/freetype/internal/services/svmm.h b/third_party/freetype/include/freetype/internal/services/svmm.h index f2cecfbb3b..97af1ac984 100644 --- a/third_party/freetype/include/freetype/internal/services/svmm.h +++ b/third_party/freetype/include/freetype/internal/services/svmm.h @@ -4,7 +4,7 @@ /* */ /* The FreeType Multiple Masters and GX var services (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVMM_H__ -#define __SVMM_H__ +#ifndef SVMM_H_ +#define SVMM_H_ #include FT_INTERNAL_SERVICE_H @@ -58,46 +58,91 @@ FT_BEGIN_HEADER FT_UInt num_coords, FT_Long* coords ); + typedef FT_Error + (*FT_Get_Var_Design_Func)( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + typedef FT_Error + (*FT_Get_MM_Blend_Func)( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + typedef FT_Error + (*FT_Get_Var_Blend_Func)( FT_Face face, + FT_UInt *num_coords, + FT_Fixed* *coords, + FT_MM_Var* *mm_var ); + + typedef void + (*FT_Done_Blend_Func)( FT_Face ); + FT_DEFINE_SERVICE( MultiMasters ) { FT_Get_MM_Func get_mm; FT_Set_MM_Design_Func set_mm_design; FT_Set_MM_Blend_Func set_mm_blend; + FT_Get_MM_Blend_Func get_mm_blend; FT_Get_MM_Var_Func get_mm_var; FT_Set_Var_Design_Func set_var_design; + FT_Get_Var_Design_Func get_var_design; + + /* for internal use; only needed for code sharing between modules */ + FT_Get_Var_Blend_Func get_var_blend; + FT_Done_Blend_Func done_blend; }; #ifndef FT_CONFIG_OPTION_PIC -#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_var_, \ - set_var_design_ ) \ - static const FT_Service_MultiMastersRec class_ = \ - { \ - get_mm_, set_mm_design_, set_mm_blend_, get_mm_var_, set_var_design_ \ +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + get_var_blend_, \ + done_blend_ ) \ + static const FT_Service_MultiMastersRec class_ = \ + { \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + get_var_blend_, \ + done_blend_ \ }; #else /* FT_CONFIG_OPTION_PIC */ -#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_var_, \ - set_var_design_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Service_MultiMastersRec* clazz ) \ - { \ - clazz->get_mm = get_mm_; \ - clazz->set_mm_design = set_mm_design_; \ - clazz->set_mm_blend = set_mm_blend_; \ - clazz->get_mm_var = get_mm_var_; \ - clazz->set_var_design = set_var_design_; \ +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + get_var_blend_, \ + done_blend_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_MultiMastersRec* clazz ) \ + { \ + clazz->get_mm = get_mm_; \ + clazz->set_mm_design = set_mm_design_; \ + clazz->set_mm_blend = set_mm_blend_; \ + clazz->get_mm_blend = get_mm_blend_; \ + clazz->get_mm_var = get_mm_var_; \ + clazz->set_var_design = set_var_design_; \ + clazz->get_var_design = get_var_design_; \ + clazz->get_var_blend = get_var_blend_; \ + clazz->done_blend = done_blend_; \ } #endif /* FT_CONFIG_OPTION_PIC */ @@ -107,7 +152,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVMM_H__ */ +#endif /* SVMM_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/services/svpostnm.h b/third_party/freetype/include/freetype/internal/services/svpostnm.h index a89f79e479..022cdec195 100644 --- a/third_party/freetype/include/freetype/internal/services/svpostnm.h +++ b/third_party/freetype/include/freetype/internal/services/svpostnm.h @@ -4,7 +4,7 @@ /* */ /* The FreeType PostScript name services (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPOSTNM_H__ -#define __SVPOSTNM_H__ +#ifndef SVPOSTNM_H_ +#define SVPOSTNM_H_ #include FT_INTERNAL_SERVICE_H @@ -75,7 +75,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPOSTNM_H__ */ +#endif /* SVPOSTNM_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/services/svprop.h b/third_party/freetype/include/freetype/internal/services/svprop.h index c9f07ce33a..eb2d4eed15 100644 --- a/third_party/freetype/include/freetype/internal/services/svprop.h +++ b/third_party/freetype/include/freetype/internal/services/svprop.h @@ -4,7 +4,7 @@ /* */ /* The FreeType property service (specification). */ /* */ -/* Copyright 2012-2015 by */ +/* Copyright 2012-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPROP_H__ -#define __SVPROP_H__ +#ifndef SVPROP_H_ +#define SVPROP_H_ FT_BEGIN_HEADER @@ -29,7 +29,8 @@ FT_BEGIN_HEADER typedef FT_Error (*FT_Properties_SetFunc)( FT_Module module, const char* property_name, - const void* value ); + const void* value, + FT_Bool value_is_string ); typedef FT_Error (*FT_Properties_GetFunc)( FT_Module module, @@ -75,7 +76,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPROP_H__ */ +#endif /* SVPROP_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/services/svpscmap.h b/third_party/freetype/include/freetype/internal/services/svpscmap.h index 66da6e1043..b32122e5d6 100644 --- a/third_party/freetype/include/freetype/internal/services/svpscmap.h +++ b/third_party/freetype/include/freetype/internal/services/svpscmap.h @@ -4,7 +4,7 @@ /* */ /* The FreeType PostScript charmap service (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPSCMAP_H__ -#define __SVPSCMAP_H__ +#ifndef SVPSCMAP_H_ +#define SVPSCMAP_H_ #include FT_INTERNAL_OBJECTS_H @@ -171,7 +171,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPSCMAP_H__ */ +#endif /* SVPSCMAP_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/services/svpsinfo.h b/third_party/freetype/include/freetype/internal/services/svpsinfo.h index 752a266025..0220ce529c 100644 --- a/third_party/freetype/include/freetype/internal/services/svpsinfo.h +++ b/third_party/freetype/include/freetype/internal/services/svpsinfo.h @@ -4,7 +4,7 @@ /* */ /* The FreeType PostScript info service (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPSINFO_H__ -#define __SVPSINFO_H__ +#ifndef SVPSINFO_H_ +#define SVPSINFO_H_ #include FT_INTERNAL_SERVICE_H #include FT_INTERNAL_TYPE1_TYPES_H @@ -105,7 +105,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPSINFO_H__ */ +#endif /* SVPSINFO_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/services/svsfnt.h b/third_party/freetype/include/freetype/internal/services/svsfnt.h index 252ae1cf5e..49d18e43e0 100644 --- a/third_party/freetype/include/freetype/internal/services/svsfnt.h +++ b/third_party/freetype/include/freetype/internal/services/svsfnt.h @@ -4,7 +4,7 @@ /* */ /* The FreeType SFNT table loading service (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVSFNT_H__ -#define __SVSFNT_H__ +#ifndef SVSFNT_H_ +#define SVSFNT_H_ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -97,7 +97,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVSFNT_H__ */ +#endif /* SVSFNT_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/services/svttcmap.h b/third_party/freetype/include/freetype/internal/services/svttcmap.h index cd95b9ab81..30f7feec71 100644 --- a/third_party/freetype/include/freetype/internal/services/svttcmap.h +++ b/third_party/freetype/include/freetype/internal/services/svttcmap.h @@ -4,7 +4,7 @@ /* */ /* The FreeType TrueType/sfnt cmap extra information service. */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2017 by */ /* Masatake YAMATO, Redhat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -19,8 +19,8 @@ /* Development of this service is support of Information-technology Promotion Agency, Japan. */ -#ifndef __SVTTCMAP_H__ -#define __SVTTCMAP_H__ +#ifndef SVTTCMAP_H_ +#define SVTTCMAP_H_ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -100,7 +100,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVTTCMAP_H__ */ +#endif /* SVTTCMAP_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/services/svtteng.h b/third_party/freetype/include/freetype/internal/services/svtteng.h index 272ee8c055..e4b368ad40 100644 --- a/third_party/freetype/include/freetype/internal/services/svtteng.h +++ b/third_party/freetype/include/freetype/internal/services/svtteng.h @@ -4,7 +4,7 @@ /* */ /* The FreeType TrueType engine query service (specification). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVTTENG_H__ -#define __SVTTENG_H__ +#ifndef SVTTENG_H_ +#define SVTTENG_H_ #include FT_INTERNAL_SERVICE_H #include FT_MODULE_H @@ -47,7 +47,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVTTENG_H__ */ +#endif /* SVTTENG_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/services/svttglyf.h b/third_party/freetype/include/freetype/internal/services/svttglyf.h index f5cb76a9f8..b7793059fd 100644 --- a/third_party/freetype/include/freetype/internal/services/svttglyf.h +++ b/third_party/freetype/include/freetype/internal/services/svttglyf.h @@ -4,7 +4,7 @@ /* */ /* The FreeType TrueType glyph service. */ /* */ -/* Copyright 2007-2015 by */ +/* Copyright 2007-2017 by */ /* David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -15,8 +15,8 @@ /* */ /***************************************************************************/ -#ifndef __SVTTGLYF_H__ -#define __SVTTGLYF_H__ +#ifndef SVTTGLYF_H_ +#define SVTTGLYF_H_ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -63,7 +63,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVTTGLYF_H__ */ +#endif /* SVTTGLYF_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/sfnt.h b/third_party/freetype/include/freetype/internal/sfnt.h index 30f53bf09c..348b5a9437 100644 --- a/third_party/freetype/include/freetype/internal/sfnt.h +++ b/third_party/freetype/include/freetype/internal/sfnt.h @@ -4,7 +4,7 @@ /* */ /* High-level `sfnt' driver interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SFNT_H__ -#define __SFNT_H__ +#ifndef SFNT_H_ +#define SFNT_H_ #include <ft2build.h> @@ -742,7 +742,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SFNT_H__ */ +#endif /* SFNT_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/t1types.h b/third_party/freetype/include/freetype/internal/t1types.h index 029acc4009..b2e35d42d1 100644 --- a/third_party/freetype/include/freetype/internal/t1types.h +++ b/third_party/freetype/include/freetype/internal/t1types.h @@ -5,7 +5,7 @@ /* Basic Type1/Type2 type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,14 +17,15 @@ /***************************************************************************/ -#ifndef __T1TYPES_H__ -#define __T1TYPES_H__ +#ifndef T1TYPES_H_ +#define T1TYPES_H_ #include <ft2build.h> #include FT_TYPE1_TABLES_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H #include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_HASH_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H @@ -107,6 +108,7 @@ FT_BEGIN_HEADER FT_Int num_subrs; FT_Byte** subrs; FT_UInt* subrs_len; + FT_Hash subrs_hash; FT_Int num_glyphs; FT_String** glyph_names; /* array of glyph names */ @@ -249,7 +251,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1TYPES_H__ */ +#endif /* T1TYPES_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/internal/tttypes.h b/third_party/freetype/include/freetype/internal/tttypes.h index 1507a7c57a..6af73034ce 100644 --- a/third_party/freetype/include/freetype/internal/tttypes.h +++ b/third_party/freetype/include/freetype/internal/tttypes.h @@ -5,7 +5,7 @@ /* Basic SFNT/TrueType type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTTYPES_H__ -#define __TTTYPES_H__ +#ifndef TTTYPES_H_ +#define TTTYPES_H_ #include <ft2build.h> @@ -185,7 +185,7 @@ FT_BEGIN_HEADER /* */ /* CompLength :: Compressed table length (in bytes). */ /* */ - /* OrigLength :: Unompressed table length (in bytes). */ + /* OrigLength :: Uncompressed table length (in bytes). */ /* */ /* CheckSum :: The table checksum. This value can be ignored. */ /* */ @@ -1060,6 +1060,34 @@ FT_BEGIN_HEADER } TT_SbitTableType; + /* OpenType 1.8 brings new tables for variation font support; */ + /* to make the old MM and GX fonts still work we need to check */ + /* the presence (and validity) of the functionality provided */ + /* by those tables. The following flag macros are for the */ + /* field `variation_support'. */ + /* */ + /* Note that `fvar' gets checked immediately at font loading, */ + /* while the other features are only loaded if MM support is */ + /* actually requested. */ + + /* FVAR */ +#define TT_FACE_FLAG_VAR_FVAR ( 1 << 0 ) + + /* HVAR */ +#define TT_FACE_FLAG_VAR_HADVANCE ( 1 << 1 ) +#define TT_FACE_FLAG_VAR_LSB ( 1 << 2 ) +#define TT_FACE_FLAG_VAR_RSB ( 1 << 3 ) + + /* VVAR */ +#define TT_FACE_FLAG_VAR_VADVANCE ( 1 << 4 ) +#define TT_FACE_FLAG_VAR_TSB ( 1 << 5 ) +#define TT_FACE_FLAG_VAR_BSB ( 1 << 6 ) +#define TT_FACE_FLAG_VAR_VORG ( 1 << 7 ) + + /* MVAR */ +#define TT_FACE_FLAG_VAR_MVAR ( 1 << 8 ) + + /*************************************************************************/ /* */ /* TrueType Face Type */ @@ -1161,6 +1189,11 @@ FT_BEGIN_HEADER /* */ /* psnames :: A pointer to the PostScript names service. */ /* */ + /* mm :: A pointer to the Multiple Masters service. */ + /* */ + /* var :: A pointer to the Metrics Variations */ + /* service. */ + /* */ /* hdmx :: The face's horizontal device metrics */ /* (`hdmx' table). This table is optional in */ /* TrueType/OpenType fonts. */ @@ -1182,18 +1215,6 @@ FT_BEGIN_HEADER /* file `ttconfig.h' for comments on the */ /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES option. */ /* */ - /* num_locations :: The number of glyph locations in this */ - /* TrueType file. This should be */ - /* identical to the number of glyphs. */ - /* Ignored for Type 2 fonts. */ - /* */ - /* glyph_locations :: An array of longs. These are offsets to */ - /* glyph data within the `glyf' table. */ - /* Ignored for Type 2 font faces. */ - /* */ - /* glyf_len :: The length of the `glyf' table. Needed */ - /* for malformed `loca' tables. */ - /* */ /* font_program_size :: Size in bytecodes of the face's font */ /* program. 0 if none defined. Ignored for */ /* Type 2 fonts. */ @@ -1219,22 +1240,19 @@ FT_BEGIN_HEADER /* units. Comes from the `cvt ' table. */ /* Ignored for Type 2 fonts. */ /* */ - /* num_kern_pairs :: The number of kerning pairs present in the */ - /* font file. The engine only loads the */ - /* first horizontal format 0 kern table it */ - /* finds in the font file. Ignored for */ - /* Type 2 fonts. */ - /* */ - /* kern_table_index :: The index of the kerning table in the font */ - /* kerning directory. Ignored for Type 2 */ - /* fonts. */ - /* */ /* interpreter :: A pointer to the TrueType bytecode */ /* interpreters field is also used to hook */ /* the debugger in `ttdebug'. */ /* */ - /* unpatented_hinting :: If true, use only unpatented methods in */ - /* the bytecode interpreter. */ + /* extra :: Reserved for third-party font drivers. */ + /* */ + /* postscript_name :: The PS name of the font. Used by the */ + /* postscript name service. */ + /* */ + /* glyf_len :: The length of the `glyf' table. Needed */ + /* for malformed `loca' tables. */ + /* */ + /* glyf_offset :: The file offset of the `glyf' table. */ /* */ /* doblend :: A boolean which is set if the font should */ /* be blended (this is for GX var). */ @@ -1243,10 +1261,89 @@ FT_BEGIN_HEADER /* variation tables (rather like Multiple */ /* Master data). */ /* */ - /* extra :: Reserved for third-party font drivers. */ + /* is_default_instance :: Set if the glyph outlines can be used */ + /* unmodified (i.e., without applying glyph */ + /* variation deltas). */ /* */ - /* postscript_name :: The PS name of the font. Used by the */ - /* postscript name service. */ + /* variation_support :: Flags that indicate which OpenType */ + /* functionality related to font variation */ + /* support is present, valid, and usable. */ + /* For example, TT_FACE_FLAG_VAR_FVAR is only */ + /* set if we have at least one design axis. */ + /* */ + /* horz_metrics_size :: The size of the `hmtx' table. */ + /* */ + /* vert_metrics_size :: The size of the `vmtx' table. */ + /* */ + /* num_locations :: The number of glyph locations in this */ + /* TrueType file. This should be */ + /* identical to the number of glyphs. */ + /* Ignored for Type 2 fonts. */ + /* */ + /* glyph_locations :: An array of longs. These are offsets to */ + /* glyph data within the `glyf' table. */ + /* Ignored for Type 2 font faces. */ + /* */ + /* hdmx_table :: A pointer to the `hdmx' table. */ + /* */ + /* hdmx_table_size :: The size of the `hdmx' table. */ + /* */ + /* hdmx_record_count :: The number of hdmx records. */ + /* */ + /* hdmx_record_size :: The size of a single hdmx record. */ + /* */ + /* hdmx_record_sizes :: An array holding the ppem sizes available */ + /* in the `hdmx' table. */ + /* */ + /* sbit_table :: A pointer to the font's embedded bitmap */ + /* location table. */ + /* */ + /* sbit_table_size :: The size of `sbit_table'. */ + /* */ + /* sbit_table_type :: The sbit table type (CBLC, SBIX, etc.). */ + /* */ + /* sbit_num_strikes :: The number of sbit strikes exposed by */ + /* FreeType's API, omitting invalid strikes. */ + /* */ + /* sbit_strike_map :: A mapping between the strike indices */ + /* exposed by the API and the indices used in */ + /* the font's sbit table. */ + /* */ + /* kern_table :: A pointer to the `kern' table. */ + /* */ + /* kern_table_size :: The size of the `kern' table. */ + /* */ + /* num_kern_tables :: The number of supported kern subtables */ + /* (up to 32; FreeType recognizes only */ + /* horizontal ones with format 0). */ + /* */ + /* kern_avail_bits :: The availability status of kern subtables; */ + /* if bit n is set, table n is available. */ + /* */ + /* kern_order_bits :: The sortedness status of kern subtables; */ + /* if bit n is set, table n is sorted. */ + /* */ + /* bdf :: Data related to an SFNT font's `bdf' */ + /* table; see `tttypes.h'. */ + /* */ + /* horz_metrics_offset :: The file offset of the `hmtx' table. */ + /* */ + /* vert_metrics_offset :: The file offset of the `vmtx' table. */ + /* */ + /* sph_found_func_flags :: Flags identifying special bytecode */ + /* functions (used by the v38 implementation */ + /* of the bytecode interpreter). */ + /* */ + /* sph_compatibility_mode :: */ + /* This flag is set if we are in ClearType */ + /* backwards compatibility mode (used by the */ + /* v38 implementation of the bytecode */ + /* interpreter). */ + /* */ + /* ebdt_start :: The file offset of the sbit data table */ + /* (CBDT, bdat, etc.). */ + /* */ + /* ebdt_size :: The size of the sbit data table. */ /* */ typedef struct TT_FaceRec_ { @@ -1291,6 +1388,16 @@ FT_BEGIN_HEADER /* handle glyph names <-> unicode & Mac values */ void* psnames; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* a typeless pointer to the FT_Service_MultiMasters table used to */ + /* handle variation fonts */ + void* mm; + + /* a typeless pointer to the FT_Service_MetricsVariationsRec table */ + /* used to handle the HVAR, VVAR, and MVAR OpenType tables */ + void* var; +#endif + /***********************************************************************/ /* */ @@ -1334,10 +1441,6 @@ FT_BEGIN_HEADER /* used to hook the debugger for the `ttdebug' utility. */ TT_Interpreter interpreter; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - /* Use unpatented hinting only. */ - FT_Bool unpatented_hinting; -#endif /***********************************************************************/ /* */ @@ -1351,18 +1454,21 @@ FT_BEGIN_HEADER const char* postscript_name; FT_ULong glyf_len; + FT_ULong glyf_offset; /* since 2.7.1 */ + + FT_Bool isCFF2; /* since 2.7.1 */ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_Bool doblend; GX_Blend blend; + + FT_Bool is_default_instance; /* since 2.7.1 */ + FT_UInt32 variation_support; /* since 2.7.1 */ #endif /* since version 2.2 */ - FT_Byte* horz_metrics; FT_ULong horz_metrics_size; - - FT_Byte* vert_metrics; FT_ULong vert_metrics_size; FT_ULong num_locations; /* in broken TTF, gid > 0xFFFF */ @@ -1378,6 +1484,7 @@ FT_BEGIN_HEADER FT_ULong sbit_table_size; TT_SbitTableType sbit_table_type; FT_UInt sbit_num_strikes; + FT_UInt* sbit_strike_map; FT_Byte* kern_table; FT_ULong kern_table_size; @@ -1393,12 +1500,18 @@ FT_BEGIN_HEADER FT_ULong horz_metrics_offset; FT_ULong vert_metrics_offset; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* since 2.4.12 */ FT_ULong sph_found_func_flags; /* special functions found */ /* for this face */ FT_Bool sph_compatibility_mode; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + /* since 2.7 */ + FT_ULong ebdt_start; /* either `CBDT', `EBDT', or `bdat' */ + FT_ULong ebdt_size; +#endif } TT_FaceRec; @@ -1492,8 +1605,6 @@ FT_BEGIN_HEADER FT_Vector pp1; FT_Vector pp2; - FT_ULong glyf_offset; - /* the zone where we load our glyphs */ TT_GlyphZoneRec base; TT_GlyphZoneRec zone; @@ -1515,12 +1626,15 @@ FT_BEGIN_HEADER FT_Byte* cursor; FT_Byte* limit; + /* since version 2.6.2 */ + FT_ListRec composites; + } TT_LoaderRec; FT_END_HEADER -#endif /* __TTTYPES_H__ */ +#endif /* TTTYPES_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/t1tables.h b/third_party/freetype/include/freetype/t1tables.h index a6ea415af5..81c9034533 100644 --- a/third_party/freetype/include/freetype/t1tables.h +++ b/third_party/freetype/include/freetype/t1tables.h @@ -5,7 +5,7 @@ /* Basic Type 1/Type 2 tables definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __T1TABLES_H__ -#define __T1TABLES_H__ +#ifndef T1TABLES_H_ +#define T1TABLES_H_ #include <ft2build.h> @@ -755,7 +755,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1TABLES_H__ */ +#endif /* T1TABLES_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/ttnameid.h b/third_party/freetype/include/freetype/ttnameid.h index c9585f2413..7da5c45072 100644 --- a/third_party/freetype/include/freetype/ttnameid.h +++ b/third_party/freetype/include/freetype/ttnameid.h @@ -4,7 +4,7 @@ /* */ /* TrueType name ID definitions (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTNAMEID_H__ -#define __TTNAMEID_H__ +#ifndef TTNAMEID_H_ +#define TTNAMEID_H_ #include <ft2build.h> @@ -1231,7 +1231,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTNAMEID_H__ */ +#endif /* TTNAMEID_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/tttables.h b/third_party/freetype/include/freetype/tttables.h index 1568f40364..7a278e2b19 100644 --- a/third_party/freetype/include/freetype/tttables.h +++ b/third_party/freetype/include/freetype/tttables.h @@ -5,7 +5,7 @@ /* Basic SFNT/TrueType tables definitions and interface */ /* (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTTABLES_H__ -#define __TTTABLES_H__ +#ifndef TTTABLES_H_ +#define TTTABLES_H_ #include <ft2build.h> @@ -175,6 +175,8 @@ FT_BEGIN_HEADER /* caret_Slope_Run :: The run coefficient of the cursor's */ /* slope. */ /* */ + /* caret_Offset :: The cursor's offset for slanted fonts. */ + /* */ /* Reserved :: 8~reserved bytes. */ /* */ /* metric_Data_Format :: Always~0. */ @@ -188,6 +190,11 @@ FT_BEGIN_HEADER /* short_metrics :: A pointer into the `hmtx' table. */ /* */ /* <Note> */ + /* For an OpenType variation font, the values of the following fields */ + /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ + /* friends) if the font contains an `MVAR' table: `caret_Slope_Rise', */ + /* `caret_Slope_Run', and `caret_Offset'. */ + /* */ /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ /* be identical except for the names of their fields, */ /* which are different. */ @@ -219,7 +226,7 @@ FT_BEGIN_HEADER /* The following fields are not defined by the TrueType specification */ /* but they are used to connect the metrics header to the relevant */ - /* `HMTX' table. */ + /* `hmtx' table. */ void* long_metrics; void* short_metrics; @@ -297,8 +304,6 @@ FT_BEGIN_HEADER /* slope. */ /* */ /* caret_Offset :: The cursor's offset for slanted fonts. */ - /* This value is `reserved' in vmtx */ - /* version 1.0. */ /* */ /* Reserved :: 8~reserved bytes. */ /* */ @@ -309,11 +314,17 @@ FT_BEGIN_HEADER /* smaller than the total number of glyphs */ /* in the font. */ /* */ - /* long_metrics :: A pointer into the `vmtx' table. */ + /* long_metrics :: A pointer into the `vmtx' table. */ /* */ - /* short_metrics :: A pointer into the `vmtx' table. */ + /* short_metrics :: A pointer into the `vmtx' table. */ /* */ /* <Note> */ + /* For an OpenType variation font, the values of the following fields */ + /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ + /* friends) if the font contains an `MVAR' table: `Ascender', */ + /* `Descender', `Line_Gap', `caret_Slope_Rise', `caret_Slope_Run', */ + /* and `caret_Offset'. */ + /* */ /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ /* be identical except for the names of their fields, */ /* which are different. */ @@ -344,8 +355,8 @@ FT_BEGIN_HEADER FT_UShort number_Of_VMetrics; /* The following fields are not defined by the TrueType specification */ - /* but they're used to connect the metrics header to the relevant */ - /* `HMTX' or `VMTX' table. */ + /* but they are used to connect the metrics header to the relevant */ + /* `hmtx' or `vmtx' table. */ void* long_metrics; void* short_metrics; @@ -359,12 +370,22 @@ FT_BEGIN_HEADER /* TT_OS2 */ /* */ /* <Description> */ - /* A structure used to model a TrueType OS/2 table. All fields */ + /* A structure used to model a TrueType `OS/2' table. All fields */ /* comply to the OpenType specification. */ /* */ /* Note that we now support old Mac fonts that do not include an OS/2 */ /* table. In this case, the `version' field is always set to 0xFFFF. */ /* */ + /* For an OpenType variation font, the values of the following fields */ + /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ + /* friends) if the font contains an `MVAR' table: `sCapHeight', */ + /* `sTypoAscender', `sTypoDescender', `sTypoLineGap', `sxHeight', */ + /* `usWinAscent', `usWinDescent', `yStrikeoutPosition', */ + /* `yStrikeoutSize', `ySubscriptXOffset', `ySubScriptXSize', */ + /* `ySubscriptYOffset', `ySubscriptYSize', `ySuperscriptXOffset', */ + /* `ySuperscriptXSize', `ySuperscriptYOffset', and */ + /* `ySuperscriptYSize'. */ + typedef struct TT_OS2_ { FT_UShort version; /* 0x0001 - more or 0xFFFF */ @@ -429,11 +450,17 @@ FT_BEGIN_HEADER /* TT_Postscript */ /* */ /* <Description> */ - /* A structure used to model a TrueType PostScript table. All fields */ + /* A structure used to model a TrueType `post' table. All fields */ /* comply to the TrueType specification. This structure does not */ /* reference the PostScript glyph names, which can be nevertheless */ /* accessed with the `ttpost' module. */ /* */ + /* <Note> */ + /* For an OpenType variation font, the values of the following fields */ + /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ + /* friends) if the font contains an `MVAR' table: `underlinePosition' */ + /* and `underlineThickness'. */ + /* */ typedef struct TT_Postscript_ { FT_Fixed FormatType; @@ -447,7 +474,7 @@ FT_BEGIN_HEADER FT_ULong maxMemType1; /* Glyph names follow in the file, but we don't */ - /* load them by default. See the ttpost.c file. */ + /* load them by default. See file `ttpost.c'. */ } TT_Postscript; @@ -458,7 +485,7 @@ FT_BEGIN_HEADER /* TT_PCLT */ /* */ /* <Description> */ - /* A structure used to model a TrueType PCLT table. All fields */ + /* A structure used to model a TrueType `PCLT' table. All fields */ /* comply to the TrueType specification. */ /* */ typedef struct TT_PCLT_ @@ -488,7 +515,7 @@ FT_BEGIN_HEADER /* TT_MaxProfile */ /* */ /* <Description> */ - /* The maximum profile is a table containing many max values, which */ + /* The maximum profile (`maxp') table contains many max values, which */ /* can be used to pre-allocate arrays. This ensures that no memory */ /* allocation occurs during a glyph load. */ /* */ @@ -587,7 +614,7 @@ FT_BEGIN_HEADER /* */ /* FT_SFNT_HHEA :: To access the font's @TT_HoriHeader structure. */ /* */ - /* FT_SFNT_VHEA :: To access the font's @TT_VertHeader struture. */ + /* FT_SFNT_VHEA :: To access the font's @TT_VertHeader structure. */ /* */ /* FT_SFNT_POST :: To access the font's @TT_Postscript structure. */ /* */ @@ -823,7 +850,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTTABLES_H__ */ +#endif /* TTTABLES_H_ */ /* END */ diff --git a/third_party/freetype/include/freetype/tttags.h b/third_party/freetype/include/freetype/tttags.h index 3836c7bbfd..32eb2fdc26 100644 --- a/third_party/freetype/include/freetype/tttags.h +++ b/third_party/freetype/include/freetype/tttags.h @@ -4,7 +4,7 @@ /* */ /* Tags for TrueType and OpenType tables (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTAGS_H__ -#define __TTAGS_H__ +#ifndef TTAGS_H_ +#define TTAGS_H_ #include <ft2build.h> @@ -43,6 +43,7 @@ FT_BEGIN_HEADER #define TTAG_CBDT FT_MAKE_TAG( 'C', 'B', 'D', 'T' ) #define TTAG_CBLC FT_MAKE_TAG( 'C', 'B', 'L', 'C' ) #define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' ) +#define TTAG_CFF2 FT_MAKE_TAG( 'C', 'F', 'F', '2' ) #define TTAG_CID FT_MAKE_TAG( 'C', 'I', 'D', ' ' ) #define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) #define TTAG_cvar FT_MAKE_TAG( 'c', 'v', 'a', 'r' ) @@ -61,6 +62,7 @@ FT_BEGIN_HEADER #define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' ) #define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' ) #define TTAG_gvar FT_MAKE_TAG( 'g', 'v', 'a', 'r' ) +#define TTAG_HVAR FT_MAKE_TAG( 'H', 'V', 'A', 'R' ) #define TTAG_hdmx FT_MAKE_TAG( 'h', 'd', 'm', 'x' ) #define TTAG_head FT_MAKE_TAG( 'h', 'e', 'a', 'd' ) #define TTAG_hhea FT_MAKE_TAG( 'h', 'h', 'e', 'a' ) @@ -79,6 +81,7 @@ FT_BEGIN_HEADER #define TTAG_MMSD FT_MAKE_TAG( 'M', 'M', 'S', 'D' ) #define TTAG_mort FT_MAKE_TAG( 'm', 'o', 'r', 't' ) #define TTAG_morx FT_MAKE_TAG( 'm', 'o', 'r', 'x' ) +#define TTAG_MVAR FT_MAKE_TAG( 'M', 'V', 'A', 'R' ) #define TTAG_name FT_MAKE_TAG( 'n', 'a', 'm', 'e' ) #define TTAG_opbd FT_MAKE_TAG( 'o', 'p', 'b', 'd' ) #define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' ) @@ -100,12 +103,13 @@ FT_BEGIN_HEADER #define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) #define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) #define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) +#define TTAG_VVAR FT_MAKE_TAG( 'V', 'V', 'A', 'R' ) #define TTAG_wOFF FT_MAKE_TAG( 'w', 'O', 'F', 'F' ) FT_END_HEADER -#endif /* __TTAGS_H__ */ +#endif /* TTAGS_H_ */ /* END */ diff --git a/third_party/freetype/include/ft2build.h b/third_party/freetype/include/ft2build.h index 419b80ae44..e7d808f3f4 100644 --- a/third_party/freetype/include/ft2build.h +++ b/third_party/freetype/include/ft2build.h @@ -4,7 +4,7 @@ /* */ /* FreeType 2 build and setup macros. */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,12 +31,12 @@ /*************************************************************************/ -#ifndef __FT2BUILD_H__ -#define __FT2BUILD_H__ +#ifndef FT2BUILD_H_ +#define FT2BUILD_H_ #include <freetype/config/ftheader.h> -#endif /* __FT2BUILD_H__ */ +#endif /* FT2BUILD_H_ */ /* END */ diff --git a/third_party/freetype/src/base/basepic.c b/third_party/freetype/src/base/basepic.c index 9850ed96a4..57fb8169ad 100644 --- a/third_party/freetype/src/base/basepic.c +++ b/third_party/freetype/src/base/basepic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for base. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/base/basepic.h b/third_party/freetype/src/base/basepic.h index c5d7cbf5ab..258d4ce2ba 100644 --- a/third_party/freetype/src/base/basepic.h +++ b/third_party/freetype/src/base/basepic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for base. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __BASEPIC_H__ -#define __BASEPIC_H__ +#ifndef BASEPIC_H_ +#define BASEPIC_H_ #include FT_INTERNAL_PIC_H @@ -85,7 +85,7 @@ FT_END_HEADER /* */ -#endif /* __BASEPIC_H__ */ +#endif /* BASEPIC_H_ */ /* END */ diff --git a/third_party/freetype/src/base/ftadvanc.c b/third_party/freetype/src/base/ftadvanc.c index f12908f518..1557607fc5 100644 --- a/third_party/freetype/src/base/ftadvanc.c +++ b/third_party/freetype/src/base/ftadvanc.c @@ -4,7 +4,7 @@ /* */ /* Quick computation of advance widths (body). */ /* */ -/* Copyright 2008-2015 by */ +/* Copyright 2008-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -36,7 +36,7 @@ if ( flags & FT_LOAD_NO_SCALE ) return FT_Err_Ok; - if ( face->size == NULL ) + if ( !face->size ) return FT_THROW( Invalid_Size_Handle ); if ( flags & FT_LOAD_VERTICAL_LAYOUT ) @@ -60,8 +60,11 @@ /* - unscaled load */ /* - unhinted load */ /* - light-hinted load */ + /* - if a variations font, it must have an `HVAR' or `VVAR' */ + /* table (thus the old MM or GX fonts don't qualify; this */ + /* gets checked by the driver-specific functions) */ -#define LOAD_ADVANCE_FAST_CHECK( flags ) \ +#define LOAD_ADVANCE_FAST_CHECK( face, flags ) \ ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \ FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) @@ -87,7 +90,7 @@ return FT_THROW( Invalid_Glyph_Index ); func = face->driver->clazz->get_advances; - if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) ) { FT_Error error; @@ -133,7 +136,7 @@ return FT_Err_Ok; func = face->driver->clazz->get_advances; - if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) ) { error = func( face, start, count, flags, padvances ); if ( !error ) @@ -157,8 +160,8 @@ /* scale from 26.6 to 16.16 */ padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) - ? face->glyph->advance.y << 10 - : face->glyph->advance.x << 10; + ? face->glyph->advance.y * 1024 + : face->glyph->advance.x * 1024; } return error; diff --git a/third_party/freetype/src/base/ftbase.c b/third_party/freetype/src/base/ftbase.c index 253dfb7236..993ac72286 100644 --- a/third_party/freetype/src/base/ftbase.c +++ b/third_party/freetype/src/base/ftbase.c @@ -4,7 +4,7 @@ /* */ /* Single object library component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,7 @@ #include "ftcalc.c" #include "ftdbgmem.c" #include "ftgloadr.c" +#include "fthash.c" #include "ftobjs.c" #include "ftoutln.c" #include "ftrfork.c" diff --git a/third_party/freetype/src/base/ftbase.h b/third_party/freetype/src/base/ftbase.h index e37fefa411..2072284f06 100644 --- a/third_party/freetype/src/base/ftbase.h +++ b/third_party/freetype/src/base/ftbase.h @@ -4,7 +4,7 @@ /* */ /* The FreeType private functions used in base module (specification). */ /* */ -/* Copyright 2008-2015 by */ +/* Copyright 2008-2017 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTBASE_H__ -#define __FTBASE_H__ +#ifndef FTBASE_H_ +#define FTBASE_H_ #include <ft2build.h> @@ -68,7 +68,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTBASE_H__ */ +#endif /* FTBASE_H_ */ /* END */ diff --git a/third_party/freetype/src/base/ftbitmap.c b/third_party/freetype/src/base/ftbitmap.c index a54572aaa2..88c88c4c1b 100644 --- a/third_party/freetype/src/base/ftbitmap.c +++ b/third_party/freetype/src/base/ftbitmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility functions for bitmaps (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -76,7 +76,7 @@ source_pitch_sign = source->pitch < 0 ? -1 : 1; target_pitch_sign = target->pitch < 0 ? -1 : 1; - if ( source->buffer == NULL ) + if ( !source->buffer ) { *target = *source; if ( source_pitch_sign != target_pitch_sign ) @@ -351,7 +351,7 @@ } /* for each row */ - for ( y = 0; y < bitmap->rows ; y++ ) + for ( y = 0; y < bitmap->rows; y++ ) { /* * Horizontally: diff --git a/third_party/freetype/src/base/ftcalc.c b/third_party/freetype/src/base/ftcalc.c index 619a08b3a0..f0525502f3 100644 --- a/third_party/freetype/src/base/ftcalc.c +++ b/third_party/freetype/src/base/ftcalc.c @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -233,7 +233,7 @@ { #ifdef FT_MULFIX_ASSEMBLER - return FT_MULFIX_ASSEMBLER( a_, b_ ); + return FT_MULFIX_ASSEMBLER( (FT_Int32)a_, (FT_Int32)b_ ); #else @@ -449,8 +449,8 @@ FT_Add64( &temp, &temp2, &temp ); /* last attempt to ditch long division */ - a = temp.hi == 0 ? temp.lo / c - : ft_div64by32( temp.hi, temp.lo, c ); + a = ( temp.hi == 0 ) ? temp.lo / c + : ft_div64by32( temp.hi, temp.lo, c ); } a_ = (FT_Long)a; @@ -492,8 +492,8 @@ ft_multo64( a, b, &temp ); /* last attempt to ditch long division */ - a = temp.hi == 0 ? temp.lo / c - : ft_div64by32( temp.hi, temp.lo, c ); + a = ( temp.hi == 0 ) ? temp.lo / c + : ft_div64by32( temp.hi, temp.lo, c ); } a_ = (FT_Long)a; diff --git a/third_party/freetype/src/base/ftdbgmem.c b/third_party/freetype/src/base/ftdbgmem.c index 6f20313b34..242246bfd1 100644 --- a/third_party/freetype/src/base/ftdbgmem.c +++ b/third_party/freetype/src/base/ftdbgmem.c @@ -4,7 +4,7 @@ /* */ /* Memory debugger (body). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -268,7 +268,7 @@ ft_mem_table_alloc( table, new_size * (FT_Long)sizeof ( FT_MemNode ) ); - if ( new_buckets == NULL ) + if ( !new_buckets ) return; FT_ARRAY_ZERO( new_buckets, new_size ); @@ -309,7 +309,7 @@ table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) ); - if ( table == NULL ) + if ( !table ) goto Exit; FT_ZERO( table ); @@ -367,7 +367,8 @@ { printf( "leaked memory block at address %p, size %8ld in (%s:%ld)\n", - node->address, node->size, + (void*)node->address, + node->size, FT_FILENAME( node->source->file_name ), node->source->line_no ); @@ -462,10 +463,10 @@ (FT_UInt32)( 5 * _ft_debug_lineno ); pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS]; - for ( ;; ) + for (;;) { node = *pnode; - if ( node == NULL ) + if ( !node ) break; if ( node->file_name == _ft_debug_file && @@ -476,7 +477,7 @@ } node = (FT_MemSource)ft_mem_table_alloc( table, sizeof ( *node ) ); - if ( node == NULL ) + if ( !node ) ft_mem_debug_panic( "not enough memory to perform memory debugging\n" ); @@ -544,7 +545,7 @@ /* we need to create a new node in this table */ node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) ); - if ( node == NULL ) + if ( !node ) ft_mem_debug_panic( "not enough memory to run memory tests" ); node->address = address; @@ -716,7 +717,7 @@ FT_MemTable table = (FT_MemTable)memory->user; - if ( block == NULL ) + if ( !block ) ft_mem_debug_panic( "trying to free NULL in (%s:%ld)", FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); @@ -754,7 +755,7 @@ /* the following is valid according to ANSI C */ #if 0 - if ( block == NULL || cur_size == 0 ) + if ( !block || !cur_size ) ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)", file_name, line_no ); #endif @@ -798,7 +799,7 @@ return NULL; new_block = (FT_Pointer)ft_mem_table_alloc( table, new_size ); - if ( new_block == NULL ) + if ( !new_block ) return NULL; ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta ); @@ -839,9 +840,9 @@ memory->free = ft_mem_debug_free; p = getenv( "FT2_ALLOC_TOTAL_MAX" ); - if ( p != NULL ) + if ( p ) { - FT_Long total_max = ft_atol( p ); + FT_Long total_max = ft_strtol( p, NULL, 10 ); if ( total_max > 0 ) @@ -852,9 +853,9 @@ } p = getenv( "FT2_ALLOC_COUNT_MAX" ); - if ( p != NULL ) + if ( p ) { - FT_Long total_count = ft_atol( p ); + FT_Long total_count = ft_strtol( p, NULL, 10 ); if ( total_count > 0 ) @@ -865,9 +866,9 @@ } p = getenv( "FT2_KEEP_ALIVE" ); - if ( p != NULL ) + if ( p ) { - FT_Long keep_alive = ft_atol( p ); + FT_Long keep_alive = ft_strtol( p, NULL, 10 ); if ( keep_alive > 0 ) diff --git a/third_party/freetype/src/base/ftfntfmt.c b/third_party/freetype/src/base/ftfntfmt.c index 98e7431a2b..dcbeba0053 100644 --- a/third_party/freetype/src/base/ftfntfmt.c +++ b/third_party/freetype/src/base/ftfntfmt.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file for font formats (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/base/ftfstype.c b/third_party/freetype/src/base/ftfstype.c index cd3458f73e..cec4fb3025 100644 --- a/third_party/freetype/src/base/ftfstype.c +++ b/third_party/freetype/src/base/ftfstype.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file to access FSType data (body). */ /* */ -/* Copyright 2008-2015 by */ +/* Copyright 2008-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/base/ftgloadr.c b/third_party/freetype/src/base/ftgloadr.c index 7e28638b27..8134003b4b 100644 --- a/third_party/freetype/src/base/ftgloadr.c +++ b/third_party/freetype/src/base/ftgloadr.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph loader (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/base/ftglyph.c b/third_party/freetype/src/base/ftglyph.c index cb7fc37787..9bfb330508 100644 --- a/third_party/freetype/src/base/ftglyph.c +++ b/third_party/freetype/src/base/ftglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -125,23 +125,25 @@ FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; - cbox->xMin = glyph->left << 6; - cbox->xMax = cbox->xMin + (FT_Pos)( glyph->bitmap.width << 6 ); - cbox->yMax = glyph->top << 6; - cbox->yMin = cbox->yMax - (FT_Pos)( glyph->bitmap.rows << 6 ); + cbox->xMin = glyph->left * 64; + cbox->xMax = cbox->xMin + (FT_Pos)( glyph->bitmap.width * 64 ); + cbox->yMax = glyph->top * 64; + cbox->yMin = cbox->yMax - (FT_Pos)( glyph->bitmap.rows * 64 ); } - FT_DEFINE_GLYPH(ft_bitmap_glyph_class, + FT_DEFINE_GLYPH( + ft_bitmap_glyph_class, + sizeof ( FT_BitmapGlyphRec ), FT_GLYPH_FORMAT_BITMAP, - ft_bitmap_glyph_init, - ft_bitmap_glyph_done, - ft_bitmap_glyph_copy, - 0, /* FT_Glyph_TransformFunc */ - ft_bitmap_glyph_bbox, - 0 /* FT_Glyph_PrepareFunc */ + ft_bitmap_glyph_init, /* FT_Glyph_InitFunc glyph_init */ + ft_bitmap_glyph_done, /* FT_Glyph_DoneFunc glyph_done */ + ft_bitmap_glyph_copy, /* FT_Glyph_CopyFunc glyph_copy */ + NULL, /* FT_Glyph_TransformFunc glyph_transform */ + ft_bitmap_glyph_bbox, /* FT_Glyph_GetBBoxFunc glyph_bbox */ + NULL /* FT_Glyph_PrepareFunc glyph_prepare */ ) @@ -260,16 +262,18 @@ } - FT_DEFINE_GLYPH( ft_outline_glyph_class, + FT_DEFINE_GLYPH( + ft_outline_glyph_class, + sizeof ( FT_OutlineGlyphRec ), FT_GLYPH_FORMAT_OUTLINE, - ft_outline_glyph_init, - ft_outline_glyph_done, - ft_outline_glyph_copy, - ft_outline_glyph_transform, - ft_outline_glyph_bbox, - ft_outline_glyph_prepare + ft_outline_glyph_init, /* FT_Glyph_InitFunc glyph_init */ + ft_outline_glyph_done, /* FT_Glyph_DoneFunc glyph_done */ + ft_outline_glyph_copy, /* FT_Glyph_CopyFunc glyph_copy */ + ft_outline_glyph_transform, /* FT_Glyph_TransformFunc glyph_transform */ + ft_outline_glyph_bbox, /* FT_Glyph_GetBBoxFunc glyph_bbox */ + ft_outline_glyph_prepare /* FT_Glyph_PrepareFunc glyph_prepare */ ) @@ -403,9 +407,9 @@ if ( error ) goto Exit; - /* copy advance while converting it to 16.16 format */ - glyph->advance.x = slot->advance.x << 10; - glyph->advance.y = slot->advance.y << 10; + /* copy advance while converting 26.6 to 16.16 format */ + glyph->advance.x = slot->advance.x * 1024; + glyph->advance.y = slot->advance.y * 1024; /* now import the image from the glyph slot */ error = clazz->glyph_init( glyph, slot ); @@ -542,8 +546,8 @@ /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */ /* then calling FT_Render_Glyph_Internal() */ - FT_MEM_ZERO( &dummy, sizeof ( dummy ) ); - FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) ); + FT_ZERO( &dummy ); + FT_ZERO( &dummy_internal ); dummy.internal = &dummy_internal; dummy.library = library; dummy.format = clazz->glyph_format; diff --git a/third_party/freetype/src/base/fthash.c b/third_party/freetype/src/base/fthash.c new file mode 100644 index 0000000000..21bc8dd5b4 --- /dev/null +++ b/third_party/freetype/src/base/fthash.c @@ -0,0 +1,339 @@ +/***************************************************************************/ +/* */ +/* fthash.c */ +/* */ +/* Hashing functions (body). */ +/* */ +/***************************************************************************/ + +/* + * Copyright 2000 Computing Research Labs, New Mexico State University + * Copyright 2001-2015 + * 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 to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + /*************************************************************************/ + /* */ + /* This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50 */ + /* */ + /* taken from Mark Leisher's xmbdfed package */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_HASH_H +#include FT_INTERNAL_MEMORY_H + + +#define INITIAL_HT_SIZE 241 + + + static FT_ULong + hash_str_lookup( FT_Hashkey* key ) + { + const char* kp = key->str; + FT_ULong res = 0; + + + /* Mocklisp hash function. */ + while ( *kp ) + res = ( res << 5 ) - res + (FT_ULong)*kp++; + + return res; + } + + + static FT_ULong + hash_num_lookup( FT_Hashkey* key ) + { + FT_ULong num = (FT_ULong)key->num; + FT_ULong res; + + + /* Mocklisp hash function. */ + res = num & 0xFF; + res = ( res << 5 ) - res + ( ( num >> 8 ) & 0xFF ); + res = ( res << 5 ) - res + ( ( num >> 16 ) & 0xFF ); + res = ( res << 5 ) - res + ( ( num >> 24 ) & 0xFF ); + + return res; + } + + + static FT_Bool + hash_str_compare( FT_Hashkey* a, + FT_Hashkey* b ) + { + if ( a->str[0] == b->str[0] && + ft_strcmp( a->str, b->str ) == 0 ) + return 1; + + return 0; + } + + + static FT_Bool + hash_num_compare( FT_Hashkey* a, + FT_Hashkey* b ) + { + if ( a->num == b->num ) + return 1; + + return 0; + } + + + static FT_Hashnode* + hash_bucket( FT_Hashkey key, + FT_Hash hash ) + { + FT_ULong res = 0; + FT_Hashnode* bp = hash->table; + FT_Hashnode* ndp; + + + res = (hash->lookup)( &key ); + + ndp = bp + ( res % hash->size ); + while ( *ndp ) + { + if ( (hash->compare)( &(*ndp)->key, &key ) ) + break; + + ndp--; + if ( ndp < bp ) + ndp = bp + ( hash->size - 1 ); + } + + return ndp; + } + + + static FT_Error + hash_rehash( FT_Hash hash, + FT_Memory memory ) + { + FT_Hashnode* obp = hash->table; + FT_Hashnode* bp; + FT_Hashnode* nbp; + + FT_UInt i, sz = hash->size; + FT_Error error = FT_Err_Ok; + + + hash->size <<= 1; + hash->limit = hash->size / 3; + + if ( FT_NEW_ARRAY( hash->table, hash->size ) ) + goto Exit; + + for ( i = 0, bp = obp; i < sz; i++, bp++ ) + { + if ( *bp ) + { + nbp = hash_bucket( (*bp)->key, hash ); + *nbp = *bp; + } + } + + FT_FREE( obp ); + + Exit: + return error; + } + + + static FT_Error + hash_init( FT_Hash hash, + FT_Bool is_num, + FT_Memory memory ) + { + FT_UInt sz = INITIAL_HT_SIZE; + FT_Error error; + + + hash->size = sz; + hash->limit = sz / 3; + hash->used = 0; + + if ( is_num ) + { + hash->lookup = hash_num_lookup; + hash->compare = hash_num_compare; + } + else + { + hash->lookup = hash_str_lookup; + hash->compare = hash_str_compare; + } + + FT_MEM_NEW_ARRAY( hash->table, sz ); + + return error; + } + + + FT_Error + ft_hash_str_init( FT_Hash hash, + FT_Memory memory ) + { + return hash_init( hash, 0, memory ); + } + + + FT_Error + ft_hash_num_init( FT_Hash hash, + FT_Memory memory ) + { + return hash_init( hash, 1, memory ); + } + + + void + ft_hash_str_free( FT_Hash hash, + FT_Memory memory ) + { + if ( hash ) + { + FT_UInt sz = hash->size; + FT_Hashnode* bp = hash->table; + FT_UInt i; + + + for ( i = 0; i < sz; i++, bp++ ) + FT_FREE( *bp ); + + FT_FREE( hash->table ); + } + } + + + /* `ft_hash_num_free' is the same as `ft_hash_str_free' */ + + + static FT_Error + hash_insert( FT_Hashkey key, + size_t data, + FT_Hash hash, + FT_Memory memory ) + { + FT_Hashnode nn; + FT_Hashnode* bp = hash_bucket( key, hash ); + FT_Error error = FT_Err_Ok; + + + nn = *bp; + if ( !nn ) + { + if ( FT_NEW( nn ) ) + goto Exit; + *bp = nn; + + nn->key = key; + nn->data = data; + + if ( hash->used >= hash->limit ) + { + error = hash_rehash( hash, memory ); + if ( error ) + goto Exit; + } + + hash->used++; + } + else + nn->data = data; + + Exit: + return error; + } + + + FT_Error + ft_hash_str_insert( const char* key, + size_t data, + FT_Hash hash, + FT_Memory memory ) + { + FT_Hashkey hk; + + + hk.str = key; + + return hash_insert( hk, data, hash, memory ); + } + + + FT_Error + ft_hash_num_insert( FT_Int num, + size_t data, + FT_Hash hash, + FT_Memory memory ) + { + FT_Hashkey hk; + + + hk.num = num; + + return hash_insert( hk, data, hash, memory ); + } + + + static size_t* + hash_lookup( FT_Hashkey key, + FT_Hash hash ) + { + FT_Hashnode* np = hash_bucket( key, hash ); + + + return (*np) ? &(*np)->data + : NULL; + } + + + size_t* + ft_hash_str_lookup( const char* key, + FT_Hash hash ) + { + FT_Hashkey hk; + + + hk.str = key; + + return hash_lookup( hk, hash ); + } + + + size_t* + ft_hash_num_lookup( FT_Int num, + FT_Hash hash ) + { + FT_Hashkey hk; + + + hk.num = num; + + return hash_lookup( hk, hash ); + } + + +/* END */ diff --git a/third_party/freetype/src/base/ftinit.c b/third_party/freetype/src/base/ftinit.c index b65a91d06c..1c4b76f567 100644 --- a/third_party/freetype/src/base/ftinit.c +++ b/third_party/freetype/src/base/ftinit.c @@ -4,7 +4,7 @@ /* */ /* FreeType initialization layer (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -226,6 +226,115 @@ } +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + +#define MAX_LENGTH 128 + + /* + * Set default properties derived from the `FREETYPE_PROPERTIES' + * environment variable. + * + * `FREETYPE_PROPERTIES' has the following syntax form (broken here into + * multiple lines for better readability) + * + * <optional whitespace> + * <module-name1> ':' + * <property-name1> '=' <property-value1> + * <whitespace> + * <module-name2> ':' + * <property-name2> '=' <property-value2> + * ... + * + * Example: + * + * FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ + * cff:no-stem-darkening=1 \ + * autofitter:warping=1 + * + */ + + static void + ft_set_default_properties( FT_Library library ) + { + const char* env; + const char* p; + const char* q; + + char module_name[MAX_LENGTH + 1]; + char property_name[MAX_LENGTH + 1]; + char property_value[MAX_LENGTH + 1]; + + int i; + + + env = ft_getenv( "FREETYPE_PROPERTIES" ); + if ( !env ) + return; + + for ( p = env; *p; p++ ) + { + /* skip leading whitespace and separators */ + if ( *p == ' ' || *p == '\t' ) + continue; + + /* read module name, followed by `:' */ + q = p; + for ( i = 0; i < MAX_LENGTH; i++ ) + { + if ( !*p || *p == ':' ) + break; + module_name[i] = *p++; + } + module_name[i] = '\0'; + + if ( !*p || *p != ':' || p == q ) + break; + + /* read property name, followed by `=' */ + q = ++p; + for ( i = 0; i < MAX_LENGTH; i++ ) + { + if ( !*p || *p == '=' ) + break; + property_name[i] = *p++; + } + property_name[i] = '\0'; + + if ( !*p || *p != '=' || p == q ) + break; + + /* read property value, followed by whitespace (if any) */ + q = ++p; + for ( i = 0; i < MAX_LENGTH; i++ ) + { + if ( !*p || *p == ' ' || *p == '\t' ) + break; + property_value[i] = *p++; + } + property_value[i] = '\0'; + + if ( !( *p == '\0' || *p == ' ' || *p == '\t' ) || p == q ) + break; + + /* we completely ignore errors */ + ft_property_string_set( library, + module_name, + property_name, + property_value ); + } + } + +#else + + static void + ft_set_default_properties( FT_Library library ) + { + FT_UNUSED( library ); + } + +#endif + + /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Error ) @@ -256,6 +365,8 @@ else FT_Add_Default_Modules( *alibrary ); + ft_set_default_properties( *alibrary ); + return error; } diff --git a/third_party/freetype/src/base/ftlcdfil.c b/third_party/freetype/src/base/ftlcdfil.c index ff6f7e98ce..f8e1709e92 100644 --- a/third_party/freetype/src/base/ftlcdfil.c +++ b/third_party/freetype/src/base/ftlcdfil.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for color filtering of subpixel bitmap glyphs (body). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -296,6 +296,8 @@ return FT_THROW( Invalid_Argument ); ft_memcpy( library->lcd_weights, weights, 5 ); + library->lcd_filter_func = _ft_lcd_filter_fir; + library->lcd_extra = 2; return FT_Err_Ok; } @@ -305,12 +307,10 @@ FT_Library_SetLcdFilter( FT_Library library, FT_LcdFilter filter ) { + static const FT_Byte default_filter[5] = + { 0x08, 0x4d, 0x56, 0x4d, 0x08 }; static const FT_Byte light_filter[5] = { 0x00, 0x55, 0x56, 0x55, 0x00 }; - /* 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 ) @@ -324,25 +324,9 @@ 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 ) - - ft_memcpy( library->lcd_weights, light_filter, 5 ); - library->lcd_filter_func = _ft_lcd_filter_fir; - library->lcd_extra = 2; - -#else - ft_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: @@ -354,6 +338,7 @@ #ifdef USE_LEGACY case FT_LCD_FILTER_LEGACY: + case FT_LCD_FILTER_LEGACY1: library->lcd_filter_func = _ft_lcd_filter_legacy; library->lcd_extra = 0; break; diff --git a/third_party/freetype/src/base/ftmm.c b/third_party/freetype/src/base/ftmm.c index 7c012aa438..b8db3c5662 100644 --- a/third_party/freetype/src/base/ftmm.c +++ b/third_party/freetype/src/base/ftmm.c @@ -4,7 +4,7 @@ /* */ /* Multiple Master font support (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 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_MULTIPLE_MASTERS_H #include FT_INTERNAL_OBJECTS_H #include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_METRICS_VARIATIONS_H /*************************************************************************/ @@ -62,6 +63,34 @@ } + static FT_Error + ft_face_get_mvar_service( FT_Face face, + FT_Service_MetricsVariations *aservice ) + { + FT_Error error; + + + *aservice = NULL; + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + error = FT_ERR( Invalid_Argument ); + + if ( FT_HAS_MULTIPLE_MASTERS( face ) ) + { + FT_FACE_LOOKUP_SERVICE( face, + *aservice, + METRICS_VARIATIONS ); + + if ( *aservice ) + error = FT_Err_Ok; + } + + return error; + } + + /* documentation is in ftmm.h */ FT_EXPORT_DEF( FT_Error ) @@ -140,6 +169,13 @@ error = service->set_mm_design( face, num_coords, coords ); } + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + return error; } @@ -151,6 +187,49 @@ FT_UInt num_coords, FT_Fixed* coords ) { + FT_Error error; + FT_Service_MultiMasters service_mm; + FT_Service_MetricsVariations service_mvar; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service_mm ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service_mm->set_var_design ) + error = service_mm->set_var_design( face, num_coords, coords ); + } + + error = ft_face_get_mvar_service( face, &service_mvar ); + if ( !error ) + { + if ( service_mvar->metrics_adjust ) + service_mvar->metrics_adjust( face ); + } + + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Var_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { FT_Error error; FT_Service_MultiMasters service; @@ -164,8 +243,8 @@ if ( !error ) { error = FT_ERR( Invalid_Argument ); - if ( service->set_var_design ) - error = service->set_var_design( face, num_coords, coords ); + if ( service->get_var_design ) + error = service->get_var_design( face, num_coords, coords ); } return error; @@ -179,6 +258,95 @@ FT_UInt num_coords, FT_Fixed* coords ) { + FT_Error error; + FT_Service_MultiMasters service_mm; + FT_Service_MetricsVariations service_mvar; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service_mm ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service_mm->set_mm_blend ) + error = service_mm->set_mm_blend( face, num_coords, coords ); + } + + error = ft_face_get_mvar_service( face, &service_mvar ); + if ( !error ) + { + if ( service_mvar->metrics_adjust ) + service_mvar->metrics_adjust( face ); + } + + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + + return error; + } + + + /* documentation is in ftmm.h */ + + /* This is exactly the same as the previous function. It exists for */ + /* orthogonality. */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Var_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error; + FT_Service_MultiMasters service_mm; + FT_Service_MetricsVariations service_mvar; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service_mm ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service_mm->set_mm_blend ) + error = service_mm->set_mm_blend( face, num_coords, coords ); + } + + error = ft_face_get_mvar_service( face, &service_mvar ); + if ( !error ) + { + if ( service_mvar->metrics_adjust ) + service_mvar->metrics_adjust( face ); + } + + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { FT_Error error; FT_Service_MultiMasters service; @@ -192,8 +360,8 @@ if ( !error ) { error = FT_ERR( Invalid_Argument ); - if ( service->set_mm_blend ) - error = service->set_mm_blend( face, num_coords, coords ); + if ( service->get_mm_blend ) + error = service->get_mm_blend( face, num_coords, coords ); } return error; @@ -206,7 +374,7 @@ /* orthogonality. */ FT_EXPORT_DEF( FT_Error ) - FT_Set_Var_Blend_Coordinates( FT_Face face, + FT_Get_Var_Blend_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ) { @@ -223,8 +391,8 @@ if ( !error ) { error = FT_ERR( Invalid_Argument ); - if ( service->set_mm_blend ) - error = service->set_mm_blend( face, num_coords, coords ); + if ( service->get_mm_blend ) + error = service->get_mm_blend( face, num_coords, coords ); } return error; diff --git a/third_party/freetype/src/base/ftobjs.c b/third_party/freetype/src/base/ftobjs.c index f0c2e77fcc..59d65e2a69 100644 --- a/third_party/freetype/src/base/ftobjs.c +++ b/third_party/freetype/src/base/ftobjs.c @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -55,7 +55,18 @@ #pragma warning( disable : 4244 ) #endif /* _MSC_VER */ - /* it's easiest to include `md5.c' directly */ + /* It's easiest to include `md5.c' directly. However, since OpenSSL */ + /* also provides the same functions, there might be conflicts if */ + /* both FreeType and OpenSSL are built as static libraries. For */ + /* this reason, we put the MD5 stuff into the `FT_' namespace. */ +#define MD5_u32plus FT_MD5_u32plus +#define MD5_CTX FT_MD5_CTX +#define MD5_Init FT_MD5_Init +#define MD5_Update FT_MD5_Update +#define MD5_Final FT_MD5_Final + +#undef HAVE_OPENSSL + #include "md5.c" #if defined( _MSC_VER ) @@ -68,6 +79,15 @@ #define GRID_FIT_METRICS + /* forward declaration */ + static FT_Error + ft_open_face_internal( FT_Library library, + const FT_Open_Args* args, + FT_Long face_index, + FT_Face *aface, + FT_Bool test_mac_fonts ); + + FT_BASE_DEF( FT_Pointer ) ft_service_list_lookup( FT_ServiceDesc service_descriptors, const char* service_id ) @@ -442,7 +462,8 @@ Exit: - FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error )); + FT_TRACE4(( "FT_New_GlyphSlot: Return 0x%x\n", error )); + return error; } @@ -630,6 +651,9 @@ load_flags &= ~FT_LOAD_RENDER; } + if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) + load_flags &= ~FT_LOAD_RENDER; + /* * Determine whether we need to auto-hint or not. * The general rules are: @@ -675,8 +699,8 @@ /* check the size of the `fpgm' and `prep' tables, too -- */ /* the assumption is that there don't exist real TTFs where */ /* both `fpgm' and `prep' tables are missing */ - if ( mode == FT_RENDER_MODE_LIGHT || - face->internal->ignore_unpatented_hinter || + if ( ( mode == FT_RENDER_MODE_LIGHT && + !FT_DRIVER_HINTS_LIGHTLY( driver ) ) || ( FT_IS_SFNT( face ) && ttface->num_locations && ttface->max_profile.maxSizeOfInstructions == 0 && @@ -1091,7 +1115,7 @@ end = first + face->num_charmaps; /* points after the last one */ - for ( cur = first; cur < end; ++cur ) + for ( cur = first; cur < end; cur++ ) { if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR && @@ -1226,7 +1250,7 @@ args.pathname = (char*)pathname; args.stream = NULL; - return FT_Open_Face( library, &args, face_index, aface ); + return ft_open_face_internal( library, &args, face_index, aface, 1 ); } #endif @@ -1253,7 +1277,7 @@ args.memory_size = file_size; args.stream = NULL; - return FT_Open_Face( library, &args, face_index, aface ); + return ft_open_face_internal( library, &args, face_index, aface, 1 ); } @@ -1288,7 +1312,7 @@ /* Finalizer for a memory stream; gets called by FT_Done_Face(). */ /* It frees the memory it uses. */ - /* From ftmac.c. */ + /* From `ftmac.c'. */ static void memory_stream_close( FT_Stream stream ) { @@ -1304,7 +1328,7 @@ /* Create a new memory stream from a buffer and a size. */ - /* From ftmac.c. */ + /* From `ftmac.c'. */ static FT_Error new_memory_stream( FT_Library library, FT_Byte* base, @@ -1324,7 +1348,7 @@ return FT_THROW( Invalid_Argument ); *astream = NULL; - memory = library->memory; + memory = library->memory; if ( FT_NEW( stream ) ) goto Exit; @@ -1340,7 +1364,7 @@ /* Create a new FT_Face given a buffer and a driver name. */ - /* from ftmac.c */ + /* From `ftmac.c'. */ FT_LOCAL_DEF( FT_Error ) open_face_from_buffer( FT_Library library, FT_Byte* base, @@ -1366,11 +1390,11 @@ return error; } - args.flags = FT_OPEN_STREAM; + args.flags = FT_OPEN_STREAM; args.stream = stream; if ( driver_name ) { - args.flags = args.flags | FT_OPEN_DRIVER; + args.flags = args.flags | FT_OPEN_DRIVER; args.driver = FT_Get_Module( library, driver_name ); } @@ -1384,9 +1408,9 @@ face_index &= 0x7FFF0000L; /* retain GX data */ #endif - error = FT_Open_Face( library, &args, face_index, aface ); + error = ft_open_face_internal( library, &args, face_index, aface, 0 ); - if ( error == FT_Err_Ok ) + if ( !error ) (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; else #ifdef FT_MACINTOSH @@ -1407,7 +1431,7 @@ /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */ /* format too. Here, since we can't expect that the TrueType font */ - /* driver is loaded unconditially, we must parse the font by */ + /* driver is loaded unconditionally, we must parse the font by */ /* ourselves. We are only interested in the name of the table and */ /* the offset. */ @@ -1472,6 +1496,7 @@ if ( face_index >= 0 && pstable_index == face_index ) return FT_Err_Ok; } + return FT_THROW( Table_Missing ); } @@ -1509,14 +1534,29 @@ if ( error ) goto Exit; - if ( FT_Stream_Seek( stream, pos + offset ) ) + if ( offset > stream->size ) + { + FT_TRACE2(( "open_face_PS_from_sfnt_stream: invalid table offset\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + else if ( length > stream->size - offset ) + { + FT_TRACE2(( "open_face_PS_from_sfnt_stream: invalid table length\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + error = FT_Stream_Seek( stream, pos + offset ); + if ( error ) goto Exit; if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) ) goto Exit; error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length ); - if ( error ) { + if ( error ) + { FT_FREE( sfnt_ps ); goto Exit; } @@ -1562,6 +1602,7 @@ { FT_Error error = FT_ERR( Cannot_Open_Resource ); FT_Memory memory = library->memory; + FT_Byte* pfb_data = NULL; int i, type, flags; FT_ULong len; @@ -1577,12 +1618,12 @@ /* Find the length of all the POST resources, concatenated. Assume */ /* worst case (each resource in its own section). */ pfb_len = 0; - for ( i = 0; i < resource_cnt; ++i ) + for ( i = 0; i < resource_cnt; i++ ) { error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] ); if ( error ) goto Exit; - if ( FT_READ_ULONG( temp ) ) + if ( FT_READ_ULONG( temp ) ) /* actually LONG */ goto Exit; /* FT2 allocator takes signed long buffer length, @@ -1590,12 +1631,15 @@ */ FT_TRACE4(( " POST fragment #%d: length=0x%08x" " total pfb_len=0x%08x\n", - i, temp, pfb_len + temp + 6)); + i, temp, pfb_len + temp + 6 )); + if ( FT_MAC_RFORK_MAX_LEN < temp || FT_MAC_RFORK_MAX_LEN - temp < pfb_len + 6 ) { FT_TRACE2(( " MacOS resource length cannot exceed" - " 0x%08x\n", FT_MAC_RFORK_MAX_LEN )); + " 0x%08x\n", + FT_MAC_RFORK_MAX_LEN )); + error = FT_THROW( Invalid_Offset ); goto Exit; } @@ -1603,15 +1647,20 @@ pfb_len += temp + 6; } - FT_TRACE2(( " total buffer size to concatenate %d" - " POST fragments: 0x%08x\n", - resource_cnt, pfb_len + 2)); - if ( pfb_len + 2 < 6 ) { + FT_TRACE2(( " total buffer size to concatenate" + " %d POST fragments: 0x%08x\n", + resource_cnt, pfb_len + 2 )); + + if ( pfb_len + 2 < 6 ) + { FT_TRACE2(( " too long fragment length makes" - " pfb_len confused: pfb_len=0x%08x\n", pfb_len )); + " pfb_len confused: pfb_len=0x%08x\n", + pfb_len )); + error = FT_THROW( Array_Too_Large ); goto Exit; } + if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) goto Exit; @@ -1624,9 +1673,10 @@ pfb_pos = 6; pfb_lenpos = 2; - len = 0; + len = 0; type = 1; - for ( i = 0; i < resource_cnt; ++i ) + + for ( i = 0; i < resource_cnt; i++ ) { error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] ); if ( error ) @@ -1645,18 +1695,24 @@ if ( FT_READ_USHORT( flags ) ) goto Exit2; - FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", - i, offsets[i], rlen, flags )); + + FT_TRACE3(( "POST fragment[%d]:" + " offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", + i, offsets[i], rlen, flags )); error = FT_ERR( Array_Too_Large ); - /* postpone the check of rlen longer than buffer until FT_Stream_Read() */ + + /* postpone the check of `rlen longer than buffer' */ + /* until `FT_Stream_Read' */ + if ( ( flags >> 8 ) == 0 ) /* Comment, should not be loaded */ { - FT_TRACE3(( " Skip POST fragment #%d because it is a comment\n", i )); + FT_TRACE3(( " Skip POST fragment #%d because it is a comment\n", + i )); continue; } - /* the flags are part of the resource, so rlen >= 2. */ + /* the flags are part of the resource, so rlen >= 2, */ /* but some fonts declare rlen = 0 for empty fragment */ if ( rlen > 2 ) rlen -= 2; @@ -1668,9 +1724,12 @@ else { FT_TRACE3(( " Write POST fragment #%d header (4-byte) to buffer" - " %p + 0x%08x\n", i, pfb_data, pfb_lenpos )); + " %p + 0x%08x\n", + i, pfb_data, pfb_lenpos )); + if ( pfb_lenpos + 3 > pfb_len + 2 ) goto Exit2; + pfb_data[pfb_lenpos ] = (FT_Byte)( len ); pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); @@ -1680,13 +1739,16 @@ break; FT_TRACE3(( " Write POST fragment #%d header (6-byte) to buffer" - " %p + 0x%08x\n", i, pfb_data, pfb_pos )); + " %p + 0x%08x\n", + i, pfb_data, pfb_pos )); + if ( pfb_pos + 6 > pfb_len + 2 ) goto Exit2; + pfb_data[pfb_pos++] = 0x80; type = flags >> 8; - len = rlen; + len = rlen; pfb_data[pfb_pos++] = (FT_Byte)type; pfb_lenpos = pfb_pos; @@ -1700,14 +1762,18 @@ goto Exit2; FT_TRACE3(( " Load POST fragment #%d (%d byte) to buffer" - " %p + 0x%08x\n", i, rlen, pfb_data, pfb_pos )); + " %p + 0x%08x\n", + i, rlen, pfb_data, pfb_pos )); + error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); if ( error ) goto Exit2; + pfb_pos += rlen; } error = FT_ERR( Array_Too_Large ); + if ( pfb_pos + 2 > pfb_len + 2 ) goto Exit2; pfb_data[pfb_pos++] = 0x80; @@ -1728,11 +1794,12 @@ aface ); Exit2: - if ( error == FT_ERR( Array_Too_Large ) ) + if ( FT_ERR_EQ( error, Array_Too_Large ) ) FT_TRACE2(( " Abort due to too-short buffer to store" " all POST fragments\n" )); - else if ( error == FT_ERR( Invalid_Offset ) ) + else if ( FT_ERR_EQ( error, Invalid_Offset ) ) FT_TRACE2(( " Abort due to invalid offset in a POST fragment\n" )); + if ( error ) error = FT_ERR( Cannot_Open_Resource ); FT_FREE( pfb_data ); @@ -1764,8 +1831,8 @@ FT_Long face_index_in_resource = 0; - if ( face_index == -1 ) - face_index = 0; + if ( face_index < 0 ) + face_index = -face_index - 1; if ( face_index >= resource_cnt ) return FT_THROW( Cannot_Open_Resource ); @@ -1776,7 +1843,7 @@ if ( FT_READ_LONG( rlen ) ) goto Exit; - if ( rlen == -1 ) + if ( rlen < 1 ) return FT_THROW( Cannot_Open_Resource ); if ( (FT_ULong)rlen > FT_MAC_RFORK_MAX_LEN ) return FT_THROW( Invalid_Offset ); @@ -1790,7 +1857,8 @@ goto Exit; /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */ - if ( FT_Stream_Seek( stream, flag_offset + 4 ) ) + error = FT_Stream_Seek( stream, flag_offset + 4 ); + if ( error ) goto Exit; if ( FT_ALLOC( sfnt_data, rlen ) ) @@ -1828,19 +1896,19 @@ { FT_Memory memory = library->memory; FT_Error error; - FT_Long map_offset, rdara_pos; + FT_Long map_offset, rdata_pos; FT_Long *data_offsets; FT_Long count; error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset, - &map_offset, &rdara_pos ); + &map_offset, &rdata_pos ); if ( error ) return error; /* POST resources must be sorted to concatenate properly */ error = FT_Raccess_Get_DataOffsets( library, stream, - map_offset, rdara_pos, + map_offset, rdata_pos, TTAG_POST, TRUE, &data_offsets, &count ); if ( !error ) @@ -1857,7 +1925,7 @@ /* sfnt resources should not be sorted to preserve the face order by QuickDraw API */ error = FT_Raccess_Get_DataOffsets( library, stream, - map_offset, rdara_pos, + map_offset, rdata_pos, TTAG_sfnt, FALSE, &data_offsets, &count ); if ( !error ) @@ -1890,7 +1958,7 @@ FT_Long dlen, offset; - if ( NULL == stream ) + if ( !stream ) return FT_THROW( Invalid_Stream_Operation ); error = FT_Stream_Seek( stream, 0 ); @@ -1964,13 +2032,15 @@ { FT_TRACE3(( "Skip rule %d: darwin vfs resource fork" " is already checked and" - " no font is found\n", i )); + " no font is found\n", + i )); continue; } if ( errors[i] ) { - FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i )); + FT_TRACE3(( "Error 0x%x has occurred in rule %d\n", + errors[i], i )); continue; } @@ -2080,6 +2150,17 @@ FT_Long face_index, FT_Face *aface ) { + return ft_open_face_internal( library, args, face_index, aface, 1 ); + } + + + static FT_Error + ft_open_face_internal( FT_Library library, + const FT_Open_Args* args, + FT_Long face_index, + FT_Face *aface, + FT_Bool test_mac_fonts ) + { FT_Error error; FT_Driver driver = NULL; FT_Memory memory = NULL; @@ -2090,6 +2171,23 @@ FT_Module* cur; FT_Module* limit; +#ifndef FT_CONFIG_OPTION_MAC_FONTS + FT_UNUSED( test_mac_fonts ); +#endif + + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE3(( "FT_Open_Face: " )); + if ( face_index < 0 ) + FT_TRACE3(( "Requesting number of faces and named instances\n")); + else + { + FT_TRACE3(( "Requesting face %ld", face_index & 0xFFFFL )); + if ( face_index & 0x7FFF0000L ) + FT_TRACE3(( ", named instance %ld", face_index >> 16 )); + FT_TRACE3(( "\n" )); + } +#endif /* test for valid `library' delayed to `FT_Stream_New' */ @@ -2167,11 +2265,13 @@ goto Success; #ifdef FT_CONFIG_OPTION_MAC_FONTS - if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 && + if ( test_mac_fonts && + ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 && FT_ERR_EQ( error, Table_Missing ) ) { /* TrueType but essential tables are missing */ - if ( FT_Stream_Seek( stream, 0 ) ) + error = FT_Stream_Seek( stream, 0 ); + if ( error ) break; error = open_face_PS_from_sfnt_stream( library, @@ -2203,16 +2303,20 @@ goto Fail2; #if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS ) - error = load_mac_face( library, stream, face_index, aface, args ); - if ( !error ) + if ( test_mac_fonts ) { - /* We don't want to go to Success here. We've already done that. */ - /* On the other hand, if we succeeded we still need to close this */ - /* stream (we opened a different stream which extracted the */ - /* interesting information out of this stream here. That stream */ - /* will still be open and the face will point to it). */ - FT_Stream_Free( stream, external_stream ); - return error; + error = load_mac_face( library, stream, face_index, aface, args ); + if ( !error ) + { + /* We don't want to go to Success here. We've already done */ + /* that. On the other hand, if we succeeded we still need to */ + /* close this stream (we opened a different stream which */ + /* extracted the interesting information out of this stream */ + /* here. That stream will still be open and the face will */ + /* point to it). */ + FT_Stream_Free( stream, external_stream ); + return error; + } } if ( FT_ERR_NEQ( error, Unknown_File_Format ) ) @@ -2285,11 +2389,24 @@ if ( bsize->height < 0 ) - bsize->height = (FT_Short)-bsize->height; + bsize->height = -bsize->height; if ( bsize->x_ppem < 0 ) - bsize->x_ppem = (FT_Short)-bsize->x_ppem; + bsize->x_ppem = -bsize->x_ppem; if ( bsize->y_ppem < 0 ) bsize->y_ppem = -bsize->y_ppem; + + /* check whether negation actually has worked */ + if ( bsize->height < 0 || bsize->x_ppem < 0 || bsize->y_ppem < 0 ) + { + FT_TRACE0(( "FT_Open_Face:" + " Invalid bitmap dimensions for stroke %d," + " now disabled\n", i )); + bsize->width = 0; + bsize->height = 0; + bsize->size = 0; + bsize->x_ppem = 0; + bsize->y_ppem = 0; + } } } @@ -2323,7 +2440,20 @@ destroy_face( memory, face, driver ); Exit: - FT_TRACE4(( "FT_Open_Face: Return %d\n", error )); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !error && face_index < 0 ) + { + FT_TRACE3(( "FT_Open_Face: The font has %ld face%s\n" + " and %ld named instance%s for face %ld\n", + face->num_faces, + face->num_faces == 1 ? "" : "s", + face->style_flags >> 16, + ( face->style_flags >> 16 ) == 1 ? "" : "s", + -face_index - 1 )); + } +#endif + + FT_TRACE4(( "FT_Open_Face: Return 0x%x\n", error )); return error; } @@ -2589,6 +2719,9 @@ w = FT_PIX_ROUND( w ); h = FT_PIX_ROUND( h ); + if ( !w || !h ) + return FT_THROW( Invalid_Pixel_Size ); + for ( i = 0; i < face->num_fixed_sizes; i++ ) { FT_Bitmap_Size* bsize = face->available_sizes + i; @@ -2608,6 +2741,8 @@ } } + FT_TRACE3(( "FT_Match_Size: no matching bitmap strike\n" )); + return FT_THROW( Invalid_Pixel_Size ); } @@ -3327,7 +3462,7 @@ FT_CMap cmap = NULL; - if ( clazz == NULL || charmap == NULL || charmap->face == NULL ) + if ( !clazz || !charmap || !charmap->face ) return FT_THROW( Invalid_Argument ); face = charmap->face; @@ -3472,7 +3607,7 @@ FT_CMap ucmap = FT_CMAP( face->charmap ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); @@ -3513,7 +3648,7 @@ FT_CharMap charmap = find_variant_selector_charmap( face ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); @@ -3552,7 +3687,7 @@ FT_CharMap charmap = find_variant_selector_charmap( face ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); FT_Memory memory = FT_FACE_MEMORY( face ); @@ -3580,7 +3715,7 @@ FT_CharMap charmap = find_variant_selector_charmap( face ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); FT_Memory memory = FT_FACE_MEMORY( face ); @@ -3614,7 +3749,7 @@ FT_CharMap charmap = find_variant_selector_charmap( face ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); FT_Memory memory = FT_FACE_MEMORY( face ); @@ -3742,7 +3877,7 @@ if ( face && FT_IS_SFNT( face ) ) { FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service != NULL ) + if ( service ) table = service->get_table( face, tag ); } @@ -3766,7 +3901,7 @@ return FT_THROW( Invalid_Face_Handle ); FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service == NULL ) + if ( !service ) return FT_THROW( Unimplemented_Feature ); return service->load_table( face, tag, offset, buffer, length ); @@ -3791,7 +3926,7 @@ return FT_THROW( Invalid_Face_Handle ); FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service == NULL ) + if ( !service ) return FT_THROW( Unimplemented_Feature ); return service->table_info( face, table_index, tag, &offset, length ); @@ -3813,7 +3948,7 @@ face = charmap->face; FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); - if ( service == NULL ) + if ( !service ) return 0; if ( service->get_cmap_info( charmap, &cmap_info )) return 0; @@ -3837,7 +3972,7 @@ face = charmap->face; FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); - if ( service == NULL ) + if ( !service ) return -1; if ( service->get_cmap_info( charmap, &cmap_info )) return -1; @@ -4156,39 +4291,51 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_bitmap - /* we convert to a single bitmap format for computing the checksum */ - if ( !error ) + /* + * Computing the MD5 checksum is expensive, unnecessarily distorting a + * possible profiling of FreeType if compiled with tracing support. For + * this reason, we execute the following code only if explicitly + * requested. + */ + + /* we use FT_TRACE3 in this block */ + if ( ft_trace_levels[trace_bitmap] >= 3 ) { - FT_Bitmap bitmap; - FT_Error err; + /* we convert to a single bitmap format for computing the checksum */ + if ( !error && slot->bitmap.buffer ) + { + FT_Bitmap bitmap; + FT_Error err; - FT_Bitmap_Init( &bitmap ); + FT_Bitmap_Init( &bitmap ); - /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */ - err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 ); - if ( !err ) - { - MD5_CTX ctx; - unsigned char md5[16]; - int i; - unsigned int rows = bitmap.rows; - unsigned int pitch = (unsigned int)bitmap.pitch; - - - MD5_Init( &ctx ); - MD5_Update( &ctx, bitmap.buffer, rows * pitch ); - MD5_Final( md5, &ctx ); - - FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n" - " ", - rows, pitch )); - for ( i = 0; i < 16; i++ ) - FT_TRACE3(( "%02X", md5[i] )); - FT_TRACE3(( "\n" )); - } + /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */ + err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 ); + if ( !err ) + { + MD5_CTX ctx; + unsigned char md5[16]; + int i; + unsigned int rows = bitmap.rows; + unsigned int pitch = (unsigned int)bitmap.pitch; + + + MD5_Init( &ctx ); + if ( bitmap.buffer ) + MD5_Update( &ctx, bitmap.buffer, rows * pitch ); + MD5_Final( md5, &ctx ); + + FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n" + " ", + rows, pitch )); + for ( i = 0; i < 16; i++ ) + FT_TRACE3(( "%02X", md5[i] )); + FT_TRACE3(( "\n" )); + } - FT_Bitmap_Done( library, &bitmap ); + FT_Bitmap_Done( library, &bitmap ); + } } #undef FT_COMPONENT @@ -4282,7 +4429,7 @@ { FT_Error error; FT_Memory memory; - FT_Module module; + FT_Module module = NULL; FT_UInt nn; @@ -4434,7 +4581,8 @@ FT_BASE_DEF( FT_Pointer ) ft_module_get_service( FT_Module module, - const char* service_id ) + const char* service_id, + FT_Bool global ) { FT_Pointer result = NULL; @@ -4447,7 +4595,7 @@ if ( module->clazz->get_interface ) result = module->clazz->get_interface( module, service_id ); - if ( result == NULL ) + if ( global && !result ) { /* we didn't find it, look in all other modules then */ FT_Library library = module->library; @@ -4464,7 +4612,7 @@ if ( cur[0]->clazz->get_interface ) { result = cur[0]->clazz->get_interface( cur[0], service_id ); - if ( result != NULL ) + if ( result ) break; } } @@ -4523,7 +4671,8 @@ const FT_String* module_name, const FT_String* property_name, void* value, - FT_Bool set ) + FT_Bool set, + FT_Bool value_is_string ) { FT_Module* cur; FT_Module* limit; @@ -4593,8 +4742,13 @@ return FT_THROW( Unimplemented_Feature ); } - return set ? service->set_property( cur[0], property_name, value ) - : service->get_property( cur[0], property_name, value ); + return set ? service->set_property( cur[0], + property_name, + value, + value_is_string ) + : service->get_property( cur[0], + property_name, + value ); } @@ -4610,7 +4764,8 @@ module_name, property_name, (void*)value, - TRUE ); + TRUE, + FALSE ); } @@ -4626,10 +4781,33 @@ module_name, property_name, value, + FALSE, FALSE ); } +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + + /* this variant is used for handling the FREETYPE_PROPERTIES */ + /* environment variable */ + + FT_BASE_DEF( FT_Error ) + ft_property_string_set( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + FT_String* value ) + { + return ft_property_do( library, + module_name, + property_name, + (void*)value, + TRUE, + TRUE ); + } + +#endif + + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -4885,7 +5063,8 @@ service = (FT_Service_TrueTypeEngine) ft_module_get_service( module, - FT_SERVICE_ID_TRUETYPE_ENGINE ); + FT_SERVICE_ID_TRUETYPE_ENGINE, + 0 ); if ( service ) result = service->engine_type; } diff --git a/third_party/freetype/src/base/ftoutln.c b/third_party/freetype/src/base/ftoutln.c index 35cc9f5569..464a066dcc 100644 --- a/third_party/freetype/src/base/ftoutln.c +++ b/third_party/freetype/src/base/ftoutln.c @@ -4,7 +4,7 @@ /* */ /* FreeType outline management (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -42,7 +42,7 @@ static - const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0 }; + const FT_Outline null_outline = { 0, 0, NULL, NULL, NULL, 0 }; /* documentation is in ftoutln.h */ @@ -287,7 +287,7 @@ return FT_Err_Ok; Exit: - FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); + FT_TRACE5(( "FT_Outline_Decompose: Error 0x%x\n", error )); return error; Invalid_Outline: @@ -415,11 +415,14 @@ if ( source == target ) return FT_Err_Ok; - FT_ARRAY_COPY( target->points, source->points, source->n_points ); - - FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); + if ( source->n_points ) + { + FT_ARRAY_COPY( target->points, source->points, source->n_points ); + FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); + } - FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); + if ( source->n_contours ) + FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); /* copy all flags, except the `FT_OUTLINE_OWNER' one */ is_owner = target->flags & FT_OUTLINE_OWNER; @@ -942,6 +945,9 @@ l_in = 0; last = outline->contours[c]; + /* pacify compiler */ + in.x = in.y = anchor.x = anchor.y = 0; + /* Counter j cycles though the points; counter i advances only */ /* when points are moved; anchor k marks the first moved point. */ for ( i = last, j = first, k = -1; @@ -1074,13 +1080,16 @@ FT_Int last = outline->contours[c]; - v_prev = points[last]; + v_prev.x = points[last].x >> xshift; + v_prev.y = points[last].y >> yshift; for ( n = first; n <= last; n++ ) { - v_cur = points[n]; - area += ( ( v_cur.y - v_prev.y ) >> yshift ) * - ( ( v_cur.x + v_prev.x ) >> xshift ); + v_cur.x = points[n].x >> xshift; + v_cur.y = points[n].y >> yshift; + + area += ( v_cur.y - v_prev.y ) * ( v_cur.x + v_prev.x ); + v_prev = v_cur; } diff --git a/third_party/freetype/src/base/ftpic.c b/third_party/freetype/src/base/ftpic.c index 6c4b1cd4e6..0f84fddc98 100644 --- a/third_party/freetype/src/base/ftpic.c +++ b/third_party/freetype/src/base/ftpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services (body). */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/base/ftrfork.c b/third_party/freetype/src/base/ftrfork.c index c30c76678e..f7b81375dd 100644 --- a/third_party/freetype/src/base/ftrfork.c +++ b/third_party/freetype/src/base/ftrfork.c @@ -4,7 +4,7 @@ /* */ /* Embedded resource forks accessor (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2017 by */ /* Masatake YAMATO and Redhat K.K. */ /* */ /* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ @@ -56,7 +56,7 @@ { FT_Error error; unsigned char head[16], head2[16]; - FT_Long map_pos, rdata_len; + FT_Long map_pos, map_len, rdata_len; int allzeros, allmatch, i; FT_Long type_list; @@ -67,12 +67,15 @@ if ( error ) return error; - error = FT_Stream_Read( stream, (FT_Byte *)head, 16 ); + error = FT_Stream_Read( stream, (FT_Byte*)head, 16 ); if ( error ) return error; /* ensure positive values */ - if ( head[0] >= 0x80 || head[4] >= 0x80 || head[8] >= 0x80 ) + if ( head[0] >= 0x80 || + head[4] >= 0x80 || + head[8] >= 0x80 || + head[12] >= 0x80 ) return FT_THROW( Unknown_File_Format ); *rdata_pos = ( head[ 0] << 24 ) | @@ -87,14 +90,36 @@ ( head[ 9] << 16 ) | ( head[10] << 8 ) | head[11]; + map_len = ( head[12] << 24 ) | + ( head[13] << 16 ) | + ( head[14] << 8 ) | + head[15]; - /* map_len = head[12] .. head[15] */ - - if ( *rdata_pos != map_pos - rdata_len || map_pos == 0 ) + /* the map must not be empty */ + if ( !map_pos ) return FT_THROW( Unknown_File_Format ); - if ( FT_LONG_MAX - rfork_offset < *rdata_pos || - FT_LONG_MAX - rfork_offset < map_pos ) + /* check whether rdata and map overlap */ + if ( *rdata_pos < map_pos ) + { + if ( *rdata_pos > map_pos - rdata_len ) + return FT_THROW( Unknown_File_Format ); + } + else + { + if ( map_pos > *rdata_pos - map_len ) + return FT_THROW( Unknown_File_Format ); + } + + /* check whether end of rdata or map exceeds stream size */ + if ( FT_LONG_MAX - rdata_len < *rdata_pos || + FT_LONG_MAX - map_len < map_pos || + + FT_LONG_MAX - ( *rdata_pos + rdata_len ) < rfork_offset || + FT_LONG_MAX - ( map_pos + map_len ) < rfork_offset || + + (FT_ULong)( rfork_offset + *rdata_pos + rdata_len ) > stream->size || + (FT_ULong)( rfork_offset + map_pos + map_len ) > stream->size ) return FT_THROW( Unknown_File_Format ); *rdata_pos += rfork_offset; @@ -112,7 +137,7 @@ allzeros = 1; allmatch = 1; - for ( i = 0; i < 16; ++i ) + for ( i = 0; i < 16; i++ ) { if ( head2[i] != 0 ) allzeros = 0; @@ -124,15 +149,14 @@ /* If we have reached this point then it is probably a mac resource */ /* file. Now, does it contain any interesting resources? */ - /* Skip handle to next resource map, the file resource number, and */ - /* attributes. */ + (void)FT_STREAM_SKIP( 4 /* skip handle to next resource map */ + 2 /* skip file resource number */ + 2 ); /* skip attributes */ - if ( FT_READ_USHORT( type_list ) ) + if ( FT_READ_SHORT( type_list ) ) return error; - if ( type_list == -1 ) + if ( type_list < 0 ) return FT_THROW( Unknown_File_Format ); error = FT_Stream_Seek( stream, (FT_ULong)( map_pos + type_list ) ); @@ -181,15 +205,34 @@ if ( error ) return error; - if ( FT_READ_USHORT( cnt ) ) + if ( FT_READ_SHORT( cnt ) ) return error; cnt++; - for ( i = 0; i < cnt; ++i ) + /* `rpos' is a signed 16bit integer offset to resource records; the */ + /* size of a resource record is 12 bytes. The map header is 28 bytes, */ + /* and a type list needs 10 bytes or more. If we assume that the name */ + /* list is empty and we have only a single entry in the type list, */ + /* there can be at most */ + /* */ + /* (32768 - 28 - 10) / 12 = 2727 */ + /* */ + /* resources. */ + /* */ + /* A type list starts with a two-byte counter, followed by 10-byte */ + /* type records. Assuming that there are no resources, the number of */ + /* type records can be at most */ + /* */ + /* (32768 - 28 - 2) / 8 = 4079 */ + /* */ + if ( cnt > 4079 ) + return FT_THROW( Invalid_Table ); + + for ( i = 0; i < cnt; i++ ) { if ( FT_READ_LONG( tag_internal ) || - FT_READ_USHORT( subcnt ) || - FT_READ_USHORT( rpos ) ) + FT_READ_SHORT( subcnt ) || + FT_READ_SHORT( rpos ) ) return error; FT_TRACE2(( "Resource tags: %c%c%c%c\n", @@ -205,6 +248,11 @@ *count = subcnt + 1; rpos += map_offset; + /* a zero count might be valid in the resource specification, */ + /* however, it is completely useless to us */ + if ( *count < 1 || *count > 2727 ) + return FT_THROW( Invalid_Table ); + error = FT_Stream_Seek( stream, (FT_ULong)rpos ); if ( error ) return error; @@ -212,35 +260,44 @@ if ( FT_NEW_ARRAY( ref, *count ) ) return error; - for ( j = 0; j < *count; ++j ) + for ( j = 0; j < *count; j++ ) { - if ( FT_READ_USHORT( ref[j].res_id ) ) + if ( FT_READ_SHORT( ref[j].res_id ) ) goto Exit; - if ( FT_STREAM_SKIP( 2 ) ) /* resource name */ + if ( FT_STREAM_SKIP( 2 ) ) /* resource name offset */ goto Exit; - if ( FT_READ_LONG( temp ) ) + if ( FT_READ_LONG( temp ) ) /* attributes (8bit), offset (24bit) */ goto Exit; - if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ + if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ + goto Exit; + + if ( ref[j].res_id < 0 || temp < 0 ) + { + error = FT_THROW( Invalid_Table ); goto Exit; + } ref[j].offset = temp & 0xFFFFFFL; + FT_TRACE3(( " [%d]:" " resource_id=0x%04x, offset=0x%08x\n", j, ref[j].res_id, ref[j].offset )); } - if (sort_by_res_id) + if ( sort_by_res_id ) { - ft_qsort( ref, (size_t)*count, sizeof ( FT_RFork_Ref ), - ( int(*)(const void*, const void*) ) - ft_raccess_sort_ref_by_id ); + ft_qsort( ref, + (size_t)*count, + sizeof ( FT_RFork_Ref ), + ( int(*)(const void*, + const void*) )ft_raccess_sort_ref_by_id ); FT_TRACE3(( " -- sort resources by their ids --\n" )); - for ( j = 0; j < *count; ++ j ) { + + for ( j = 0; j < *count; j++ ) FT_TRACE3(( " [%d]:" " resource_id=0x%04x, offset=0x%08x\n", j, ref[j].res_id, ref[j].offset )); - } } if ( FT_NEW_ARRAY( offsets_internal, *count ) ) @@ -250,7 +307,7 @@ * gap between reference IDs are acceptable? * further investigation on Apple implementation is needed. */ - for ( j = 0; j < *count; ++j ) + for ( j = 0; j < *count; j++ ) offsets_internal[j] = rdata_pos + ref[j].offset; *offsets = offsets_internal; @@ -403,7 +460,7 @@ errors[i] = FT_Err_Ok; if ( errors[i] ) - continue ; + continue; errors[i] = (FT_RACCESS_GUESS_TABLE_GET[i].func)( library, stream, base_name, diff --git a/third_party/freetype/src/base/ftsnames.c b/third_party/freetype/src/base/ftsnames.c index 80304e5c85..a5b41eb884 100644 --- a/third_party/freetype/src/base/ftsnames.c +++ b/third_party/freetype/src/base/ftsnames.c @@ -7,7 +7,7 @@ /* */ /* This is _not_ used to retrieve glyph names! */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,7 +58,7 @@ /* load name on demand */ - if ( entry->stringLength > 0 && entry->string == NULL ) + if ( entry->stringLength > 0 && !entry->string ) { FT_Memory memory = face->memory; FT_Stream stream = face->stream; diff --git a/third_party/freetype/src/base/ftstream.c b/third_party/freetype/src/base/ftstream.c index b68f3f82d2..a3f8c8b3c9 100644 --- a/third_party/freetype/src/base/ftstream.c +++ b/third_party/freetype/src/base/ftstream.c @@ -4,7 +4,7 @@ /* */ /* I/O stream support (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -778,7 +778,7 @@ case ft_frame_short_be: case ft_frame_ushort_be: /* read a 2-byte big-endian short */ - value = FT_NEXT_USHORT( cursor) ; + value = FT_NEXT_USHORT( cursor ); sign_shift = 16; break; diff --git a/third_party/freetype/src/base/ftsystem.c b/third_party/freetype/src/base/ftsystem.c index 1938fd8917..324f949a49 100644 --- a/third_party/freetype/src/base/ftsystem.c +++ b/third_party/freetype/src/base/ftsystem.c @@ -4,7 +4,7 @@ /* */ /* ANSI-specific FreeType low-level system interface (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/base/fttrigon.c b/third_party/freetype/src/base/fttrigon.c index 5b24304c2f..7a4d17c829 100644 --- a/third_party/freetype/src/base/fttrigon.c +++ b/third_party/freetype/src/base/fttrigon.c @@ -4,7 +4,7 @@ /* */ /* FreeType trigonometric functions (body). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -71,7 +71,8 @@ /* 0x40000000 comes from regression analysis between true */ /* and CORDIC hypotenuse, so it minimizes the error */ - val = (FT_Fixed)( ( (FT_Int64)val * FT_TRIG_SCALE + 0x40000000UL ) >> 32 ); + val = (FT_Fixed)( + ( (FT_UInt64)val * FT_TRIG_SCALE + 0x40000000UL ) >> 32 ); return s < 0 ? -val : val; } diff --git a/third_party/freetype/src/base/fttype1.c b/third_party/freetype/src/base/fttype1.c index c549382afd..4d16a6371a 100644 --- a/third_party/freetype/src/base/fttype1.c +++ b/third_party/freetype/src/base/fttype1.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file for PS names support (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/base/ftutil.c b/third_party/freetype/src/base/ftutil.c index f5b72db708..dccc209f4d 100644 --- a/third_party/freetype/src/base/ftutil.c +++ b/third_party/freetype/src/base/ftutil.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file for memory and list management (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -74,7 +74,7 @@ if ( size > 0 ) { block = memory->alloc( memory, size ); - if ( block == NULL ) + if ( !block ) error = FT_THROW( Out_Of_Memory ); } else if ( size < 0 ) @@ -141,7 +141,7 @@ } else if ( cur_count == 0 ) { - FT_ASSERT( block == NULL ); + FT_ASSERT( !block ); block = ft_mem_alloc( memory, new_count*item_size, &error ); } @@ -153,7 +153,7 @@ block2 = memory->realloc( memory, cur_size, new_size, block ); - if ( block2 == NULL ) + if ( !block2 ) error = FT_THROW( Out_Of_Memory ); else block = block2; diff --git a/third_party/freetype/src/cff/cf2arrst.c b/third_party/freetype/src/cff/cf2arrst.c index 89f3e9f1d7..6796450fe1 100644 --- a/third_party/freetype/src/cff/cf2arrst.c +++ b/third_party/freetype/src/cff/cf2arrst.c @@ -58,7 +58,7 @@ FT_Error* error, size_t sizeItem ) { - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); /* initialize the structure */ arrstack->memory = memory; @@ -78,7 +78,7 @@ FT_Memory memory = arrstack->memory; /* for FT_FREE */ - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); arrstack->allocated = 0; arrstack->count = 0; @@ -95,7 +95,7 @@ cf2_arrstack_setNumElements( CF2_ArrStack arrstack, size_t numElements ) { - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); { FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ @@ -140,7 +140,7 @@ cf2_arrstack_setCount( CF2_ArrStack arrstack, size_t numElements ) { - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); if ( numElements > arrstack->allocated ) { @@ -157,7 +157,7 @@ FT_LOCAL_DEF( void ) cf2_arrstack_clear( CF2_ArrStack arrstack ) { - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); arrstack->count = 0; } @@ -167,7 +167,7 @@ FT_LOCAL_DEF( size_t ) cf2_arrstack_size( const CF2_ArrStack arrstack ) { - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); return arrstack->count; } @@ -176,7 +176,7 @@ FT_LOCAL_DEF( void* ) cf2_arrstack_getBuffer( const CF2_ArrStack arrstack ) { - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); return arrstack->ptr; } @@ -190,7 +190,7 @@ void* newPtr; - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); if ( idx >= arrstack->count ) { @@ -212,7 +212,7 @@ cf2_arrstack_push( CF2_ArrStack arrstack, const void* ptr ) { - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); if ( arrstack->count == arrstack->allocated ) { @@ -225,7 +225,7 @@ } } - FT_ASSERT( ptr != NULL ); + FT_ASSERT( ptr ); { size_t offset = arrstack->count * arrstack->sizeItem; diff --git a/third_party/freetype/src/cff/cf2arrst.h b/third_party/freetype/src/cff/cf2arrst.h index ff5ad8b126..3c21a3b672 100644 --- a/third_party/freetype/src/cff/cf2arrst.h +++ b/third_party/freetype/src/cff/cf2arrst.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2ARRST_H__ -#define __CF2ARRST_H__ +#ifndef CF2ARRST_H_ +#define CF2ARRST_H_ #include "cf2error.h" @@ -94,7 +94,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2ARRST_H__ */ +#endif /* CF2ARRST_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cf2blues.h b/third_party/freetype/src/cff/cf2blues.h index 2f38fcad8f..96fb60f38d 100644 --- a/third_party/freetype/src/cff/cf2blues.h +++ b/third_party/freetype/src/cff/cf2blues.h @@ -65,8 +65,8 @@ */ -#ifndef __CF2BLUES_H__ -#define __CF2BLUES_H__ +#ifndef CF2BLUES_H_ +#define CF2BLUES_H_ #include "cf2glue.h" @@ -179,7 +179,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2BLUES_H__ */ +#endif /* CF2BLUES_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cf2error.c b/third_party/freetype/src/cff/cf2error.c index b5595a3d1f..e3dd69f50d 100644 --- a/third_party/freetype/src/cff/cf2error.c +++ b/third_party/freetype/src/cff/cf2error.c @@ -44,7 +44,7 @@ cf2_setError( FT_Error* error, FT_Error value ) { - if ( error && *error == 0 ) + if ( error && !*error ) *error = value; } diff --git a/third_party/freetype/src/cff/cf2error.h b/third_party/freetype/src/cff/cf2error.h index 6453ebcb7b..512edd1d21 100644 --- a/third_party/freetype/src/cff/cf2error.h +++ b/third_party/freetype/src/cff/cf2error.h @@ -36,13 +36,13 @@ /***************************************************************************/ -#ifndef __CF2ERROR_H__ -#define __CF2ERROR_H__ +#ifndef CF2ERROR_H_ +#define CF2ERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX CF2_Err_ @@ -70,7 +70,7 @@ FT_BEGIN_HEADER * Upon a function call if the error code is anything other than * `FT_Err_Ok', which is guaranteed to be zero, we * will return without altering that error. This will allow the - * error to propogate and be handled at the appropriate location in + * error to propagate and be handled at the appropriate location in * the code. * * This allows a style of code where the error code is initialized @@ -113,7 +113,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2ERROR_H__ */ +#endif /* CF2ERROR_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cf2fixed.h b/third_party/freetype/src/cff/cf2fixed.h index d6d9faf8e5..2e4b5032fa 100644 --- a/third_party/freetype/src/cff/cf2fixed.h +++ b/third_party/freetype/src/cff/cf2fixed.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2FIXED_H__ -#define __CF2FIXED_H__ +#ifndef CF2FIXED_H_ +#define CF2FIXED_H_ FT_BEGIN_HEADER @@ -51,8 +51,8 @@ FT_BEGIN_HEADER #define CF2_FIXED_MAX ( (CF2_Fixed)0x7FFFFFFFL ) #define CF2_FIXED_MIN ( (CF2_Fixed)0x80000000L ) -#define CF2_FIXED_ONE 0x10000L -#define CF2_FIXED_EPSILON 0x0001 +#define CF2_FIXED_ONE ( (CF2_Fixed)0x10000L ) +#define CF2_FIXED_EPSILON ( (CF2_Fixed)0x0001 ) /* in C 89, left and right shift of negative numbers is */ /* implementation specific behaviour in the general case */ @@ -89,7 +89,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2FIXED_H__ */ +#endif /* CF2FIXED_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cf2font.c b/third_party/freetype/src/cff/cf2font.c index 83fd348f2d..a86e3619b4 100644 --- a/third_party/freetype/src/cff/cf2font.c +++ b/third_party/freetype/src/cff/cf2font.c @@ -234,7 +234,8 @@ } - /* set up values for the current FontDict and matrix */ + /* set up values for the current FontDict and matrix; */ + /* called for each glyph to be rendered */ /* caller's transform is adjusted for subpixel positioning */ static void @@ -246,6 +247,9 @@ FT_Bool needExtraSetup = FALSE; + CFF_VStoreRec* vstore; + FT_Bool hasVariations = FALSE; + /* character space units */ CF2_Fixed boldenX = font->syntheticEmboldeningAmountX; CF2_Fixed boldenY = font->syntheticEmboldeningAmountY; @@ -253,6 +257,9 @@ CFF_SubFont subFont; CF2_Fixed ppem; + CF2_UInt lenNormalizedV = 0; + FT_Fixed* normalizedV = NULL; + /* clear previous error */ font->error = FT_Err_Ok; @@ -266,6 +273,48 @@ needExtraSetup = TRUE; } + /* check for variation vectors */ + vstore = cf2_getVStore( decoder ); + hasVariations = ( vstore->dataCount != 0 ); + + if ( hasVariations ) + { +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* check whether Private DICT in this subfont needs to be reparsed */ + font->error = cf2_getNormalizedVector( decoder, + &lenNormalizedV, + &normalizedV ); + if ( font->error ) + return; + + if ( cff_blend_check_vector( &subFont->blend, + subFont->private_dict.vsindex, + lenNormalizedV, + normalizedV ) ) + { + /* blend has changed, reparse */ + cff_load_private_dict( decoder->cff, + subFont, + lenNormalizedV, + normalizedV ); + needExtraSetup = TRUE; + } +#endif + + /* copy from subfont */ + font->blend.font = subFont->blend.font; + + /* clear state of charstring blend */ + font->blend.usedBV = FALSE; + + /* initialize value for charstring */ + font->vsindex = subFont->private_dict.vsindex; + + /* store vector inputs for blends in charstring */ + font->lenNDV = lenNormalizedV; + font->NDV = normalizedV; + } + /* if ppem has changed, we need to recompute some cached data */ /* note: because of CID font matrix concatenation, ppem and transform */ /* do not necessarily track. */ @@ -423,7 +472,8 @@ /* compute blue zones for this instance */ cf2_blues_init( &font->blues, font ); - } + + } /* needExtraSetup */ } diff --git a/third_party/freetype/src/cff/cf2font.h b/third_party/freetype/src/cff/cf2font.h index 86cf02f49d..17ecd17bbb 100644 --- a/third_party/freetype/src/cff/cf2font.h +++ b/third_party/freetype/src/cff/cf2font.h @@ -36,12 +36,13 @@ /***************************************************************************/ -#ifndef __CF2FONT_H__ -#define __CF2FONT_H__ +#ifndef CF2FONT_H_ +#define CF2FONT_H_ #include "cf2ft.h" #include "cf2blues.h" +#include "cffload.h" FT_BEGIN_HEADER @@ -54,6 +55,7 @@ FT_BEGIN_HEADER /* (Hiragino Kaku Gothic ProN W3; */ /* 8.2d6e1; 2014-12-19) that exceed */ /* this limit */ +#define CF2_STORAGE_SIZE 32 /* typedef is in `cf2glue.h' */ @@ -62,6 +64,7 @@ FT_BEGIN_HEADER FT_Memory memory; FT_Error error; /* shared error for this instance */ + FT_Bool isCFF2; CF2_RenderingFlags renderingFlags; /* variables that depend on Transform: */ @@ -73,6 +76,12 @@ FT_BEGIN_HEADER CF2_Matrix outerTransform; /* post hinting; includes rotations */ CF2_Fixed ppem; /* transform-dependent */ + /* variation data */ + CFF_BlendRec blend; /* cached charstring blend vector */ + CF2_UInt vsindex; /* current vsindex */ + CF2_UInt lenNDV; /* current length NDV or zero */ + FT_Fixed* NDV; /* ptr to current NDV or NULL */ + CF2_Int unitsPerEm; CF2_Fixed syntheticEmboldeningAmountX; /* character space units */ @@ -115,7 +124,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2FONT_H__ */ +#endif /* CF2FONT_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cf2ft.c b/third_party/freetype/src/cff/cf2ft.c index d2544a2345..c0d067e94e 100644 --- a/third_party/freetype/src/cff/cf2ft.c +++ b/third_party/freetype/src/cff/cf2ft.c @@ -104,7 +104,8 @@ FT_Memory memory = font->memory; - (void)memory; + FT_FREE( font->blend.lastNDV ); + FT_FREE( font->blend.BV ); } } @@ -239,7 +240,7 @@ FT_Memory memory, FT_Error* error ) { - FT_MEM_ZERO( outline, sizeof ( CF2_OutlineRec ) ); + FT_ZERO( outline ); outline->root.memory = memory; outline->root.error = error; @@ -311,7 +312,7 @@ font = (CF2_Font)decoder->cff->cf2_instance.data; /* on first glyph, allocate instance structure */ - if ( decoder->cff->cf2_instance.data == NULL ) + if ( !decoder->cff->cf2_instance.data ) { decoder->cff->cf2_instance.finalizer = (FT_Generic_Finalizer)cf2_free_instance; @@ -366,6 +367,9 @@ &hinted, &scaled ); + /* copy isCFF2 boolean from TT_Face to CF2_Font */ + font->isCFF2 = builder->face->isCFF2; + font->renderingFlags = 0; if ( hinted ) font->renderingFlags |= CF2_FlagsHinted; @@ -413,6 +417,44 @@ } + /* get pointer to VStore structure */ + FT_LOCAL_DEF( CFF_VStore ) + cf2_getVStore( CFF_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->cff ); + + return &decoder->cff->vstore; + } + + + /* get maxstack value from CFF2 Top DICT */ + FT_LOCAL_DEF( FT_UInt ) + cf2_getMaxstack( CFF_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->cff ); + + return decoder->cff->top_font.font_dict.maxstack; + } + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* Get normalized design vector for current render request; */ + /* return pointer and length. */ + /* */ + /* Note: Uses FT_Fixed not CF2_Fixed for the vector. */ + FT_LOCAL_DEF( FT_Error ) + cf2_getNormalizedVector( CFF_Decoder* decoder, + CF2_UInt *len, + FT_Fixed* *vec ) + { + FT_ASSERT( decoder && decoder->builder.face ); + FT_ASSERT( vec && len ); + + return cff_get_var_blend( decoder->builder.face, len, vec, NULL ); + } +#endif + + /* get `y_ppem' from `CFF_Size' */ FT_LOCAL_DEF( CF2_Fixed ) cf2_getPpemY( CFF_Decoder* decoder ) @@ -544,14 +586,17 @@ /* return 0 on success */ FT_LOCAL_DEF( CF2_Int ) cf2_initGlobalRegionBuffer( CFF_Decoder* decoder, - CF2_UInt idx, + CF2_Int subrNum, CF2_Buffer buf ) { + CF2_UInt idx; + + FT_ASSERT( decoder ); FT_ZERO( buf ); - idx += (CF2_UInt)decoder->globals_bias; + idx = (CF2_UInt)( subrNum + decoder->globals_bias ); if ( idx >= decoder->num_globals ) return TRUE; /* error */ @@ -628,14 +673,17 @@ FT_LOCAL_DEF( CF2_Int ) cf2_initLocalRegionBuffer( CFF_Decoder* decoder, - CF2_UInt idx, + CF2_Int subrNum, CF2_Buffer buf ) { + CF2_UInt idx; + + FT_ASSERT( decoder ); FT_ZERO( buf ); - idx += (CF2_UInt)decoder->locals_bias; + idx = (CF2_UInt)( subrNum + decoder->locals_bias ); if ( idx >= decoder->num_locals ) return TRUE; /* error */ diff --git a/third_party/freetype/src/cff/cf2ft.h b/third_party/freetype/src/cff/cf2ft.h index 3073df382f..b054a6e950 100644 --- a/third_party/freetype/src/cff/cf2ft.h +++ b/third_party/freetype/src/cff/cf2ft.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2FT_H__ -#define __CF2FT_H__ +#ifndef CF2FT_H_ +#define CF2FT_H_ #include "cf2types.h" @@ -64,6 +64,18 @@ FT_BEGIN_HEADER FT_LOCAL( CFF_SubFont ) cf2_getSubfont( CFF_Decoder* decoder ); + FT_LOCAL( CFF_VStore ) + cf2_getVStore( CFF_Decoder* decoder ); + + FT_LOCAL( FT_UInt ) + cf2_getMaxstack( CFF_Decoder* decoder ); + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_LOCAL( FT_Error ) + cf2_getNormalizedVector( CFF_Decoder* decoder, + CF2_UInt *len, + FT_Fixed* *vec ); +#endif FT_LOCAL( CF2_Fixed ) cf2_getPpemY( CFF_Decoder* decoder ); @@ -99,7 +111,7 @@ FT_BEGIN_HEADER FT_LOCAL( CF2_Int ) cf2_initGlobalRegionBuffer( CFF_Decoder* decoder, - CF2_UInt idx, + CF2_Int subrNum, CF2_Buffer buf ); FT_LOCAL( FT_Error ) cf2_getSeacComponent( CFF_Decoder* decoder, @@ -110,7 +122,7 @@ FT_BEGIN_HEADER CF2_Buffer buf ); FT_LOCAL( CF2_Int ) cf2_initLocalRegionBuffer( CFF_Decoder* decoder, - CF2_UInt idx, + CF2_Int subrNum, CF2_Buffer buf ); FT_LOCAL( CF2_Fixed ) @@ -141,7 +153,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2FT_H__ */ +#endif /* CF2FT_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cf2glue.h b/third_party/freetype/src/cff/cf2glue.h index a24da39e93..56a7c248f4 100644 --- a/third_party/freetype/src/cff/cf2glue.h +++ b/third_party/freetype/src/cff/cf2glue.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2GLUE_H__ -#define __CF2GLUE_H__ +#ifndef CF2GLUE_H_ +#define CF2GLUE_H_ /* common includes for other modules */ @@ -138,7 +138,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2GLUE_H__ */ +#endif /* CF2GLUE_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cf2hints.c b/third_party/freetype/src/cff/cf2hints.c index 0e27000210..c8f7dfeba6 100644 --- a/third_party/freetype/src/cff/cf2hints.c +++ b/third_party/freetype/src/cff/cf2hints.c @@ -401,10 +401,10 @@ /* calculate all four possibilities; moves down are negative */ CF2_Fixed downMoveDown = 0 - fracDown; CF2_Fixed upMoveDown = 0 - fracUp; - CF2_Fixed downMoveUp = fracDown == 0 + CF2_Fixed downMoveUp = ( fracDown == 0 ) ? 0 : cf2_intToFixed( 1 ) - fracDown; - CF2_Fixed upMoveUp = fracUp == 0 + CF2_Fixed upMoveUp = ( fracUp == 0 ) ? 0 : cf2_intToFixed( 1 ) - fracUp; @@ -587,8 +587,9 @@ } /* paired edges must be in proper order */ - FT_ASSERT( !isPair || - topHintEdge->csCoord >= bottomHintEdge->csCoord ); + if ( isPair && + topHintEdge->csCoord < bottomHintEdge->csCoord ) + return; /* linear search to find index value of insertion point */ indexInsert = 0; diff --git a/third_party/freetype/src/cff/cf2hints.h b/third_party/freetype/src/cff/cf2hints.h index f25d91bf89..a8984542a0 100644 --- a/third_party/freetype/src/cff/cf2hints.h +++ b/third_party/freetype/src/cff/cf2hints.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2HINTS_H__ -#define __CF2HINTS_H__ +#ifndef CF2HINTS_H_ +#define CF2HINTS_H_ FT_BEGIN_HEADER @@ -220,7 +220,7 @@ FT_BEGIN_HEADER /* character space miter limit threshold */ CF2_Fixed miterLimit; - /* vertical/horzizontal snap distance in character space */ + /* vertical/horizontal snap distance in character space */ CF2_Fixed snapThreshold; FT_Vector offsetStart0; /* first and second points of first */ @@ -283,7 +283,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2HINTS_H__ */ +#endif /* CF2HINTS_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cf2intrp.c b/third_party/freetype/src/cff/cf2intrp.c index ff3fa9aaaa..6bf298a4d6 100644 --- a/third_party/freetype/src/cff/cf2intrp.c +++ b/third_party/freetype/src/cff/cf2intrp.c @@ -47,6 +47,8 @@ #include "cf2error.h" +#include "cffload.h" + /*************************************************************************/ /* */ @@ -184,7 +186,7 @@ return; FT_ASSERT( hintmask->byteCount > 0 ); - FT_ASSERT( hintmask->byteCount < + FT_ASSERT( hintmask->byteCount <= sizeof ( hintmask->mask ) / sizeof ( hintmask->mask[0] ) ); /* set mask to all ones */ @@ -215,8 +217,8 @@ cf2_cmdESC, /* 12 */ cf2_cmdRESERVED_13, /* 13 */ cf2_cmdENDCHAR, /* 14 */ - cf2_cmdRESERVED_15, /* 15 */ - cf2_cmdRESERVED_16, /* 16 */ + cf2_cmdVSINDEX, /* 15 */ + cf2_cmdBLEND, /* 16 */ cf2_cmdRESERVED_17, /* 17 */ cf2_cmdHSTEMHM, /* 18 */ cf2_cmdHINTMASK, /* 19 */ @@ -273,7 +275,8 @@ cf2_escHFLEX, /* 34 */ cf2_escFLEX, /* 35 */ cf2_escHFLEX1, /* 36 */ - cf2_escFLEX1 /* 37 */ + cf2_escFLEX1, /* 37 */ + cf2_escRESERVED_38 /* 38 & all higher */ }; @@ -293,7 +296,8 @@ /* variable accumulates delta values from operand stack */ CF2_Fixed position = hintOffset; - if ( hasWidthArg && ! *haveWidth ) + + if ( hasWidthArg && !*haveWidth ) *width = cf2_stack_getReal( opStack, 0 ) + cf2_getNominalWidthX( font->decoder ); @@ -343,7 +347,7 @@ vals[0] = *curX; vals[1] = *curY; index = 0; - isHFlex = readFromStack[9] == FALSE; + isHFlex = FT_BOOL( readFromStack[9] == FALSE ); top = isHFlex ? 9 : 10; for ( i = 0; i < top; i++ ) @@ -402,6 +406,43 @@ } + /* Blend numOperands on the stack, */ + /* store results into the first numBlends values, */ + /* then pop remaining arguments. */ + static void + cf2_doBlend( const CFF_Blend blend, + CF2_Stack opStack, + CF2_UInt numBlends ) + { + CF2_UInt delta; + CF2_UInt base; + CF2_UInt i, j; + CF2_UInt numOperands = (CF2_UInt)( numBlends * blend->lenBV ); + + + base = cf2_stack_count( opStack ) - numOperands; + delta = base + numBlends; + + for ( i = 0; i < numBlends; i++ ) + { + const CF2_Fixed* weight = &blend->BV[1]; + + /* start with first term */ + CF2_Fixed sum = cf2_stack_getReal( opStack, i + base ); + + + for ( j = 1; j < blend->lenBV; j++ ) + sum += FT_MulFix( *weight++, cf2_stack_getReal( opStack, delta++ ) ); + + /* store blended result */ + cf2_stack_setReal( opStack, i + base, sum ); + } + + /* leave only `numBlends' results on stack */ + cf2_stack_pop( opStack, numOperands - numBlends ); + } + + /* * `error' is a shared error code used by many objects in this * routine. Before the code continues from an error, it must check and @@ -444,8 +485,11 @@ CF2_Fixed hintOriginY = curY; CF2_Stack opStack = NULL; + FT_UInt stackSize; FT_Byte op1; /* first opcode byte */ + CF2_F16Dot16 storage[CF2_STORAGE_SIZE]; /* for `put' and `get' */ + /* instruction limit; 20,000,000 matches Avalon */ FT_UInt32 instructionLimit = 20000000UL; @@ -466,6 +510,8 @@ CF2_GlyphPathRec glyphPath; + FT_ZERO( &storage ); + /* initialize the remaining objects */ cf2_arrstack_init( &subrStack, memory, @@ -515,19 +561,24 @@ * If one of the above operators occurs without explicitly specifying * a width, we assume the default width. * + * CFF2 charstrings always return the default width (0). + * */ - haveWidth = FALSE; + haveWidth = font->isCFF2 ? TRUE : FALSE; *width = cf2_getDefaultWidthX( decoder ); /* - * Note: at this point, all pointers to resources must be NULL - * and all local objects must be initialized. - * There must be no branches to exit: above this point. + * Note: At this point, all pointers to resources must be NULL + * and all local objects must be initialized. + * There must be no branches to `exit:' above this point. * */ /* allocate an operand stack */ - opStack = cf2_stack_init( memory, error ); + stackSize = font->isCFF2 ? cf2_getMaxstack( decoder ) + : CF2_OPERAND_STACK_SIZE; + opStack = cf2_stack_init( memory, error, stackSize ); + if ( !opStack ) { lastError = FT_THROW( Out_Of_Memory ); @@ -556,14 +607,23 @@ { /* If we've reached the end of the charstring, simulate a */ /* cf2_cmdRETURN or cf2_cmdENDCHAR. */ + /* We do this for both CFF and CFF2. */ if ( charstringIndex ) op1 = cf2_cmdRETURN; /* end of buffer for subroutine */ else op1 = cf2_cmdENDCHAR; /* end of buffer for top level charstring */ } else + { op1 = (FT_Byte)cf2_buf_readByte( charstring ); + /* Explicit RETURN and ENDCHAR in CFF2 should be ignored. */ + /* Note: Trace message will report 0 instead of 11 or 14. */ + if ( ( op1 == cf2_cmdRETURN || op1 == cf2_cmdENDCHAR ) && + font->isCFF2 ) + op1 = cf2_cmdRESERVED_0; + } + /* check for errors once per loop */ if ( *error ) goto exit; @@ -581,13 +641,78 @@ case cf2_cmdRESERVED_2: case cf2_cmdRESERVED_9: case cf2_cmdRESERVED_13: - case cf2_cmdRESERVED_15: - case cf2_cmdRESERVED_16: case cf2_cmdRESERVED_17: /* we may get here if we have a prior error */ FT_TRACE4(( " unknown op (%d)\n", op1 )); break; + case cf2_cmdVSINDEX: + FT_TRACE4(( " vsindex\n" )); + + if ( !font->isCFF2 ) + break; /* clear stack & ignore */ + + if ( font->blend.usedBV ) + { + /* vsindex not allowed after blend */ + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + { + FT_Int temp = cf2_stack_popInt( opStack ); + + + if ( temp >= 0 ) + font->vsindex = (FT_UInt)temp; + } + break; + + case cf2_cmdBLEND: + { + FT_UInt numBlends; + + + FT_TRACE4(( " blend\n" )); + + if ( !font->isCFF2 ) + break; /* clear stack & ignore */ + + /* do we have a `blend' op in a non-variant font? */ + if ( !font->blend.font ) + { + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + /* check cached blend vector */ + if ( cff_blend_check_vector( &font->blend, + font->vsindex, + font->lenNDV, + font->NDV ) ) + { + lastError = cff_blend_build_vector( &font->blend, + font->vsindex, + font->lenNDV, + font->NDV ); + if ( lastError ) + goto exit; + } + + /* do the blend */ + numBlends = (FT_UInt)cf2_stack_popInt( opStack ); + if ( numBlends > stackSize ) + { + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + cf2_doBlend( &font->blend, opStack, numBlends ); + + font->blend.usedBV = TRUE; + } + continue; /* do not clear the stack */ + case cf2_cmdHSTEMHM: case cf2_cmdHSTEM: FT_TRACE4(( op1 == cf2_cmdHSTEMHM ? " hstemhm\n" : " hstem\n" )); @@ -608,7 +733,7 @@ 0 ); if ( font->decoder->width_only ) - goto exit; + goto exit; break; @@ -632,7 +757,7 @@ 0 ); if ( font->decoder->width_only ) - goto exit; + goto exit; break; @@ -646,7 +771,7 @@ haveWidth = TRUE; if ( font->decoder->width_only ) - goto exit; + goto exit; curY += cf2_stack_popFixed( opStack ); @@ -680,7 +805,7 @@ CF2_UInt index; CF2_UInt count = cf2_stack_count( opStack ); - FT_Bool isX = op1 == cf2_cmdHLINETO; + FT_Bool isX = FT_BOOL( op1 == cf2_cmdHLINETO ); FT_TRACE4(( isX ? " hlineto\n" : " vlineto\n" )); @@ -746,7 +871,7 @@ case cf2_cmdCALLGSUBR: case cf2_cmdCALLSUBR: { - CF2_UInt subrIndex; + CF2_Int subrNum; FT_TRACE4(( op1 == cf2_cmdCALLGSUBR ? " callgsubr" @@ -766,17 +891,17 @@ (size_t)charstringIndex + 1 ); /* set up the new CFF region and pointer */ - subrIndex = (CF2_UInt)cf2_stack_popInt( opStack ); + subrNum = cf2_stack_popInt( opStack ); switch ( op1 ) { case cf2_cmdCALLGSUBR: FT_TRACE4(( " (idx %d, entering level %d)\n", - subrIndex + (CF2_UInt)decoder->globals_bias, + subrNum + decoder->globals_bias, charstringIndex + 1 )); if ( cf2_initGlobalRegionBuffer( decoder, - subrIndex, + subrNum, charstring ) ) { lastError = FT_THROW( Invalid_Glyph_Format ); @@ -787,11 +912,11 @@ default: /* cf2_cmdCALLSUBR */ FT_TRACE4(( " (idx %d, entering level %d)\n", - subrIndex + (CF2_UInt)decoder->locals_bias, + subrNum + decoder->locals_bias, charstringIndex + 1 )); if ( cf2_initLocalRegionBuffer( decoder, - subrIndex, + subrNum, charstring ) ) { lastError = FT_THROW( Invalid_Glyph_Format ); @@ -825,135 +950,10 @@ FT_Byte op2 = (FT_Byte)cf2_buf_readByte( charstring ); + /* first switch for 2-byte operators handles CFF2 */ + /* and opcodes that are reserved for both CFF and CFF2 */ switch ( op2 ) { - case cf2_escDOTSECTION: - /* something about `flip type of locking' -- ignore it */ - FT_TRACE4(( " dotsection\n" )); - - break; - - /* TODO: should these operators be supported? */ - case cf2_escAND: /* in spec */ - FT_TRACE4(( " and\n" )); - - CF2_FIXME; - break; - - case cf2_escOR: /* in spec */ - FT_TRACE4(( " or\n" )); - - CF2_FIXME; - break; - - case cf2_escNOT: /* in spec */ - FT_TRACE4(( " not\n" )); - - CF2_FIXME; - break; - - case cf2_escABS: /* in spec */ - FT_TRACE4(( " abs\n" )); - - CF2_FIXME; - break; - - case cf2_escADD: /* in spec */ - FT_TRACE4(( " add\n" )); - - CF2_FIXME; - break; - - case cf2_escSUB: /* in spec */ - FT_TRACE4(( " sub\n" )); - - CF2_FIXME; - break; - - case cf2_escDIV: /* in spec */ - FT_TRACE4(( " div\n" )); - - CF2_FIXME; - break; - - case cf2_escNEG: /* in spec */ - FT_TRACE4(( " neg\n" )); - - CF2_FIXME; - break; - - case cf2_escEQ: /* in spec */ - FT_TRACE4(( " eq\n" )); - - CF2_FIXME; - break; - - case cf2_escDROP: /* in spec */ - FT_TRACE4(( " drop\n" )); - - CF2_FIXME; - break; - - case cf2_escPUT: /* in spec */ - FT_TRACE4(( " put\n" )); - - CF2_FIXME; - break; - - case cf2_escGET: /* in spec */ - FT_TRACE4(( " get\n" )); - - CF2_FIXME; - break; - - case cf2_escIFELSE: /* in spec */ - FT_TRACE4(( " ifelse\n" )); - - CF2_FIXME; - break; - - case cf2_escRANDOM: /* in spec */ - FT_TRACE4(( " random\n" )); - - CF2_FIXME; - break; - - case cf2_escMUL: /* in spec */ - FT_TRACE4(( " mul\n" )); - - CF2_FIXME; - break; - - case cf2_escSQRT: /* in spec */ - FT_TRACE4(( " sqrt\n" )); - - CF2_FIXME; - break; - - case cf2_escDUP: /* in spec */ - FT_TRACE4(( " dup\n" )); - - CF2_FIXME; - break; - - case cf2_escEXCH: /* in spec */ - FT_TRACE4(( " exch\n" )); - - CF2_FIXME; - break; - - case cf2_escINDEX: /* in spec */ - FT_TRACE4(( " index\n" )); - - CF2_FIXME; - break; - - case cf2_escROLL: /* in spec */ - FT_TRACE4(( " roll\n" )); - - CF2_FIXME; - break; - case cf2_escHFLEX: { static const FT_Bool readFromStack[12] = @@ -1050,6 +1050,7 @@ } continue; + /* these opcodes are reserved in both CFF & CFF2 */ case cf2_escRESERVED_1: case cf2_escRESERVED_2: case cf2_escRESERVED_6: @@ -1063,12 +1064,342 @@ case cf2_escRESERVED_31: case cf2_escRESERVED_32: case cf2_escRESERVED_33: - default: FT_TRACE4(( " unknown op (12, %d)\n", op2 )); + break; + + default: + { + if ( font->isCFF2 || op2 >= cf2_escRESERVED_38 ) + FT_TRACE4(( " unknown op (12, %d)\n", op2 )); + else + { + /* second switch for 2-byte operators handles just CFF */ + switch ( op2 ) + { + + case cf2_escDOTSECTION: + /* something about `flip type of locking' -- ignore it */ + FT_TRACE4(( " dotsection\n" )); + + break; + + case cf2_escAND: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + + + FT_TRACE4(( " and\n" )); + + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushInt( opStack, arg1 && arg2 ); + } + continue; /* do not clear the stack */ + + case cf2_escOR: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + + + FT_TRACE4(( " or\n" )); + + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushInt( opStack, arg1 || arg2 ); + } + continue; /* do not clear the stack */ + + case cf2_escNOT: + { + CF2_F16Dot16 arg; + + + FT_TRACE4(( " not\n" )); + + arg = cf2_stack_popFixed( opStack ); + + cf2_stack_pushInt( opStack, !arg ); + } + continue; /* do not clear the stack */ + + case cf2_escABS: + { + CF2_F16Dot16 arg; + + + FT_TRACE4(( " abs\n" )); + + arg = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, FT_ABS( arg ) ); + } + continue; /* do not clear the stack */ + + case cf2_escADD: + { + CF2_F16Dot16 summand1; + CF2_F16Dot16 summand2; + + + FT_TRACE4(( " add\n" )); + + summand2 = cf2_stack_popFixed( opStack ); + summand1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, summand1 + summand2 ); + } + continue; /* do not clear the stack */ + + case cf2_escSUB: + { + CF2_F16Dot16 minuend; + CF2_F16Dot16 subtrahend; + + + FT_TRACE4(( " sub\n" )); + + subtrahend = cf2_stack_popFixed( opStack ); + minuend = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, minuend - subtrahend ); + } + continue; /* do not clear the stack */ + + case cf2_escDIV: + { + CF2_F16Dot16 dividend; + CF2_F16Dot16 divisor; + + + FT_TRACE4(( " div\n" )); + + divisor = cf2_stack_popFixed( opStack ); + dividend = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, FT_DivFix( dividend, divisor ) ); + } + continue; /* do not clear the stack */ + + case cf2_escNEG: + { + CF2_F16Dot16 arg; + + + FT_TRACE4(( " neg\n" )); + + arg = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, -arg ); + } + continue; /* do not clear the stack */ + + case cf2_escEQ: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + + + FT_TRACE4(( " eq\n" )); + + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushInt( opStack, arg1 == arg2 ); + } + continue; /* do not clear the stack */ + + case cf2_escDROP: + FT_TRACE4(( " drop\n" )); + + (void)cf2_stack_popFixed( opStack ); + continue; /* do not clear the stack */ + + case cf2_escPUT: + { + CF2_F16Dot16 val; + CF2_Int idx; + + + FT_TRACE4(( " put\n" )); - }; /* end of switch statement checking `op2' */ + idx = cf2_stack_popInt( opStack ); + val = cf2_stack_popFixed( opStack ); + if ( idx >= 0 && idx < CF2_STORAGE_SIZE ) + storage[idx] = val; + } + continue; /* do not clear the stack */ + + case cf2_escGET: + { + CF2_Int idx; + + + FT_TRACE4(( " get\n" )); + + idx = cf2_stack_popInt( opStack ); + + if ( idx >= 0 && idx < CF2_STORAGE_SIZE ) + cf2_stack_pushFixed( opStack, storage[idx] ); + } + continue; /* do not clear the stack */ + + case cf2_escIFELSE: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + CF2_F16Dot16 cond1; + CF2_F16Dot16 cond2; + + + FT_TRACE4(( " ifelse\n" )); + + cond2 = cf2_stack_popFixed( opStack ); + cond1 = cf2_stack_popFixed( opStack ); + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, cond1 <= cond2 ? arg1 : arg2 ); + } + continue; /* do not clear the stack */ + + case cf2_escRANDOM: /* in spec */ + FT_TRACE4(( " random\n" )); + + CF2_FIXME; + break; + + case cf2_escMUL: + { + CF2_F16Dot16 factor1; + CF2_F16Dot16 factor2; + + + FT_TRACE4(( " mul\n" )); + + factor2 = cf2_stack_popFixed( opStack ); + factor1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, FT_MulFix( factor1, factor2 ) ); + } + continue; /* do not clear the stack */ + + case cf2_escSQRT: + { + CF2_F16Dot16 arg; + + + FT_TRACE4(( " sqrt\n" )); + + arg = cf2_stack_popFixed( opStack ); + if ( arg > 0 ) + { + FT_Fixed root = arg; + FT_Fixed new_root; + + + /* Babylonian method */ + for (;;) + { + new_root = ( root + FT_DivFix( arg, root ) + 1 ) >> 1; + if ( new_root == root ) + break; + root = new_root; + } + arg = new_root; + } + else + arg = 0; + + cf2_stack_pushFixed( opStack, arg ); + } + continue; /* do not clear the stack */ + + case cf2_escDUP: + { + CF2_F16Dot16 arg; + + + FT_TRACE4(( " dup\n" )); + + arg = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, arg ); + cf2_stack_pushFixed( opStack, arg ); + } + continue; /* do not clear the stack */ + + case cf2_escEXCH: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + + + FT_TRACE4(( " exch\n" )); + + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, arg2 ); + cf2_stack_pushFixed( opStack, arg1 ); + } + continue; /* do not clear the stack */ + + case cf2_escINDEX: + { + CF2_Int idx; + CF2_UInt size; + + + FT_TRACE4(( " index\n" )); + + idx = cf2_stack_popInt( opStack ); + size = cf2_stack_count( opStack ); + + if ( size > 0 ) + { + /* for `cf2_stack_getReal', index 0 is bottom of stack */ + CF2_UInt gr_idx; + + + if ( idx < 0 ) + gr_idx = size - 1; + else if ( (CF2_UInt)idx >= size ) + gr_idx = 0; + else + gr_idx = size - 1 - (CF2_UInt)idx; + + cf2_stack_pushFixed( opStack, + cf2_stack_getReal( opStack, gr_idx ) ); + } + } + continue; /* do not clear the stack */ + + case cf2_escROLL: + { + CF2_Int idx; + CF2_Int count; + + + FT_TRACE4(( " roll\n" )); + + idx = cf2_stack_popInt( opStack ); + count = cf2_stack_popInt( opStack ); + + cf2_stack_roll( opStack, count, idx ); + } + continue; /* do not clear the stack */ + + } /* end of 2nd switch checking op2 */ + } + } + } /* end of 1st switch checking op2 */ } /* case cf2_cmdESC */ + break; case cf2_cmdENDCHAR: @@ -1085,12 +1416,13 @@ haveWidth = TRUE; if ( font->decoder->width_only ) - goto exit; + goto exit; /* close path if still open */ cf2_glyphpath_closeOpenPath( &glyphPath ); - if ( cf2_stack_count( opStack ) > 1 ) + /* disable seac for CFF2 (charstring ending with args on stack) */ + if ( !font->isCFF2 && cf2_stack_count( opStack ) > 1 ) { /* must be either 4 or 5 -- */ /* this is a (deprecated) implied `seac' operator */ @@ -1117,8 +1449,8 @@ error2 = cf2_getSeacComponent( decoder, achar, &component ); if ( error2 ) { - lastError = error2; /* pass FreeType error through */ - goto exit; + lastError = error2; /* pass FreeType error through */ + goto exit; } cf2_interpT2CharString( font, &component, @@ -1172,7 +1504,7 @@ 0 ); if ( font->decoder->width_only ) - goto exit; + goto exit; if ( op1 == cf2_cmdHINTMASK ) { @@ -1231,7 +1563,7 @@ haveWidth = TRUE; if ( font->decoder->width_only ) - goto exit; + goto exit; curY += cf2_stack_popFixed( opStack ); curX += cf2_stack_popFixed( opStack ); @@ -1250,7 +1582,7 @@ haveWidth = TRUE; if ( font->decoder->width_only ) - goto exit; + goto exit; curX += cf2_stack_popFixed( opStack ); @@ -1319,7 +1651,7 @@ { x1 = cf2_stack_getReal( opStack, index ) + curX; - ++index; + index++; } else x1 = curX; @@ -1364,7 +1696,7 @@ { y1 = cf2_stack_getReal( opStack, index ) + curY; - ++index; + index++; } else y1 = curY; @@ -1392,7 +1724,7 @@ CF2_UInt count, count1 = cf2_stack_count( opStack ); CF2_UInt index = 0; - FT_Bool alternate = op1 == cf2_cmdHVCURVETO; + FT_Bool alternate = FT_BOOL( op1 == cf2_cmdHVCURVETO ); /* if `cf2_stack_count' isn't of the form 8n, 8n+1, */ @@ -1421,7 +1753,7 @@ { x3 = cf2_stack_getReal( opStack, index + 4 ) + x2; - ++index; + index++; } else x3 = x2; @@ -1440,7 +1772,7 @@ { y3 = cf2_stack_getReal( opStack, index + 4 ) + y2; - ++index; + index++; } else y3 = y2; @@ -1463,9 +1795,12 @@ { CF2_Int v; + CF2_Int byte1 = cf2_buf_readByte( charstring ); + CF2_Int byte2 = cf2_buf_readByte( charstring ); + - v = (FT_Short)( ( cf2_buf_readByte( charstring ) << 8 ) | - cf2_buf_readByte( charstring ) ); + v = (FT_Short)( ( byte1 << 8 ) | + byte2 ); FT_TRACE4(( " %d", v )); @@ -1527,14 +1862,18 @@ { CF2_Fixed v; + FT_UInt32 byte1 = (FT_UInt32)cf2_buf_readByte( charstring ); + FT_UInt32 byte2 = (FT_UInt32)cf2_buf_readByte( charstring ); + FT_UInt32 byte3 = (FT_UInt32)cf2_buf_readByte( charstring ); + FT_UInt32 byte4 = (FT_UInt32)cf2_buf_readByte( charstring ); - v = (CF2_Fixed) - ( ( (FT_UInt32)cf2_buf_readByte( charstring ) << 24 ) | - ( (FT_UInt32)cf2_buf_readByte( charstring ) << 16 ) | - ( (FT_UInt32)cf2_buf_readByte( charstring ) << 8 ) | - (FT_UInt32)cf2_buf_readByte( charstring ) ); - FT_TRACE4(( " %.2f", v / 65536.0 )); + v = (CF2_Fixed)( ( byte1 << 24 ) | + ( byte2 << 16 ) | + ( byte3 << 8 ) | + byte4 ); + + FT_TRACE4(( " %.5f", v / 65536.0 )); cf2_stack_pushFixed( opStack, v ); } @@ -1555,6 +1894,9 @@ /* check whether last error seen is also the first one */ cf2_setError( error, lastError ); + if ( *error ) + FT_TRACE4(( "charstring error %d\n", *error )); + /* free resources from objects we've used */ cf2_glyphpath_finalize( &glyphPath ); cf2_arrstack_finalize( &vStemHintArray ); diff --git a/third_party/freetype/src/cff/cf2intrp.h b/third_party/freetype/src/cff/cf2intrp.h index b5d8947838..ec030e8944 100644 --- a/third_party/freetype/src/cff/cf2intrp.h +++ b/third_party/freetype/src/cff/cf2intrp.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2INTRP_H__ -#define __CF2INTRP_H__ +#ifndef CF2INTRP_H_ +#define CF2INTRP_H_ #include "cf2ft.h" @@ -77,7 +77,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2INTRP_H__ */ +#endif /* CF2INTRP_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cf2read.h b/third_party/freetype/src/cff/cf2read.h index 7ef7c8c149..b0b0db803a 100644 --- a/third_party/freetype/src/cff/cf2read.h +++ b/third_party/freetype/src/cff/cf2read.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2READ_H__ -#define __CF2READ_H__ +#ifndef CF2READ_H_ +#define CF2READ_H_ FT_BEGIN_HEADER @@ -62,7 +62,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2READ_H__ */ +#endif /* CF2READ_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cf2stack.c b/third_party/freetype/src/cff/cf2stack.c index 8332b5d91a..12a026d21d 100644 --- a/third_party/freetype/src/cff/cf2stack.c +++ b/third_party/freetype/src/cff/cf2stack.c @@ -51,21 +51,31 @@ /* `error'). */ FT_LOCAL_DEF( CF2_Stack ) cf2_stack_init( FT_Memory memory, - FT_Error* e ) + FT_Error* e, + FT_UInt stackSize ) { - FT_Error error = FT_Err_Ok; /* for FT_QNEW */ + FT_Error error = FT_Err_Ok; /* for FT_NEW */ CF2_Stack stack = NULL; - if ( !FT_QNEW( stack ) ) + if ( !FT_NEW( stack ) ) { - /* initialize the structure; FT_QNEW zeroes it */ + /* initialize the structure; FT_NEW zeroes it */ stack->memory = memory; stack->error = e; - stack->top = &stack->buffer[0]; /* empty stack */ } + /* allocate the stack buffer */ + if ( FT_NEW_ARRAY( stack->buffer, stackSize ) ) + { + FT_FREE( stack ); + return NULL; + } + + stack->stackSize = stackSize; + stack->top = stack->buffer; /* empty stack */ + return stack; } @@ -77,6 +87,8 @@ { FT_Memory memory = stack->memory; + /* free the buffer */ + FT_FREE( stack->buffer ); /* free the main structure */ FT_FREE( stack ); @@ -87,7 +99,7 @@ FT_LOCAL_DEF( CF2_UInt ) cf2_stack_count( CF2_Stack stack ) { - return (CF2_UInt)( stack->top - &stack->buffer[0] ); + return (CF2_UInt)( stack->top - stack->buffer ); } @@ -95,7 +107,7 @@ cf2_stack_pushInt( CF2_Stack stack, CF2_Int val ) { - if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] ) + if ( stack->top == stack->buffer + stack->stackSize ) { CF2_SET_ERROR( stack->error, Stack_Overflow ); return; /* stack overflow */ @@ -103,7 +115,7 @@ stack->top->u.i = val; stack->top->type = CF2_NumberInt; - ++stack->top; + stack->top++; } @@ -111,7 +123,7 @@ cf2_stack_pushFixed( CF2_Stack stack, CF2_Fixed val ) { - if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] ) + if ( stack->top == stack->buffer + stack->stackSize ) { CF2_SET_ERROR( stack->error, Stack_Overflow ); return; /* stack overflow */ @@ -119,7 +131,7 @@ stack->top->u.r = val; stack->top->type = CF2_NumberFixed; - ++stack->top; + stack->top++; } @@ -127,7 +139,7 @@ FT_LOCAL_DEF( CF2_Int ) cf2_stack_popInt( CF2_Stack stack ) { - if ( stack->top == &stack->buffer[0] ) + if ( stack->top == stack->buffer ) { CF2_SET_ERROR( stack->error, Stack_Underflow ); return 0; /* underflow */ @@ -138,24 +150,24 @@ return 0; /* type mismatch */ } - --stack->top; + stack->top--; return stack->top->u.i; } /* Note: type mismatch is silently cast */ - /* TODO: check this */ + /* TODO: check this */ FT_LOCAL_DEF( CF2_Fixed ) cf2_stack_popFixed( CF2_Stack stack ) { - if ( stack->top == &stack->buffer[0] ) + if ( stack->top == stack->buffer ) { CF2_SET_ERROR( stack->error, Stack_Underflow ); return cf2_intToFixed( 0 ); /* underflow */ } - --stack->top; + stack->top--; switch ( stack->top->type ) { @@ -170,12 +182,12 @@ /* Note: type mismatch is silently cast */ - /* TODO: check this */ + /* TODO: check this */ FT_LOCAL_DEF( CF2_Fixed ) cf2_stack_getReal( CF2_Stack stack, CF2_UInt idx ) { - FT_ASSERT( cf2_stack_count( stack ) <= CF2_OPERAND_STACK_SIZE ); + FT_ASSERT( cf2_stack_count( stack ) <= stack->stackSize ); if ( idx >= cf2_stack_count( stack ) ) { @@ -195,10 +207,121 @@ } + /* provide random access to stack */ + FT_LOCAL_DEF( void ) + cf2_stack_setReal( CF2_Stack stack, + CF2_UInt idx, + CF2_Fixed val ) + { + if ( idx > cf2_stack_count( stack ) ) + { + CF2_SET_ERROR( stack->error, Stack_Overflow ); + return; + } + + stack->buffer[idx].u.r = val; + stack->buffer[idx].type = CF2_NumberFixed; + } + + + /* discard (pop) num values from stack */ + FT_LOCAL_DEF( void ) + cf2_stack_pop( CF2_Stack stack, + CF2_UInt num ) + { + if ( num > cf2_stack_count( stack ) ) + { + CF2_SET_ERROR( stack->error, Stack_Underflow ); + return; + } + stack->top -= num; + } + + + FT_LOCAL_DEF( void ) + cf2_stack_roll( CF2_Stack stack, + CF2_Int count, + CF2_Int shift ) + { + /* we initialize this variable to avoid compiler warnings */ + CF2_StackNumber last = { { 0 }, CF2_NumberInt }; + + CF2_Int start_idx, idx, i; + + + if ( count < 2 ) + return; /* nothing to do (values 0 and 1), or undefined value */ + + if ( (CF2_UInt)count > cf2_stack_count( stack ) ) + { + CF2_SET_ERROR( stack->error, Stack_Overflow ); + return; + } + + if ( shift < 0 ) + shift = -( ( -shift ) % count ); + else + shift %= count; + + if ( shift == 0 ) + return; /* nothing to do */ + + /* We use the following algorithm to do the rolling, */ + /* which needs two temporary variables only. */ + /* */ + /* Example: */ + /* */ + /* count = 8 */ + /* shift = 2 */ + /* */ + /* stack indices before roll: 7 6 5 4 3 2 1 0 */ + /* stack indices after roll: 1 0 7 6 5 4 3 2 */ + /* */ + /* The value of index 0 gets moved to index 2, while */ + /* the old value of index 2 gets moved to index 4, */ + /* and so on. We thus have the following copying */ + /* chains for shift value 2. */ + /* */ + /* 0 -> 2 -> 4 -> 6 -> 0 */ + /* 1 -> 3 -> 5 -> 7 -> 1 */ + /* */ + /* If `count' and `shift' are incommensurable, we */ + /* have a single chain only. Otherwise, increase */ + /* the start index by 1 after the first chain, then */ + /* do the next chain until all elements in all */ + /* chains are handled. */ + + start_idx = -1; + idx = -1; + for ( i = 0; i < count; i++ ) + { + CF2_StackNumber tmp; + + + if ( start_idx == idx ) + { + start_idx++; + idx = start_idx; + last = stack->buffer[idx]; + } + + idx += shift; + if ( idx >= count ) + idx -= count; + else if ( idx < 0 ) + idx += count; + + tmp = stack->buffer[idx]; + stack->buffer[idx] = last; + last = tmp; + } + } + + FT_LOCAL_DEF( void ) cf2_stack_clear( CF2_Stack stack ) { - stack->top = &stack->buffer[0]; + stack->top = stack->buffer; } diff --git a/third_party/freetype/src/cff/cf2stack.h b/third_party/freetype/src/cff/cf2stack.h index 7d6d1961fe..ef08eefe41 100644 --- a/third_party/freetype/src/cff/cf2stack.h +++ b/third_party/freetype/src/cff/cf2stack.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2STACK_H__ -#define __CF2STACK_H__ +#ifndef CF2STACK_H_ +#define CF2STACK_H_ FT_BEGIN_HEADER @@ -62,15 +62,17 @@ FT_BEGIN_HEADER { FT_Memory memory; FT_Error* error; - CF2_StackNumber buffer[CF2_OPERAND_STACK_SIZE]; + CF2_StackNumber* buffer; CF2_StackNumber* top; + FT_UInt stackSize; } CF2_StackRec, *CF2_Stack; FT_LOCAL( CF2_Stack ) cf2_stack_init( FT_Memory memory, - FT_Error* error ); + FT_Error* error, + FT_UInt stackSize ); FT_LOCAL( void ) cf2_stack_free( CF2_Stack stack ); @@ -92,6 +94,19 @@ FT_BEGIN_HEADER FT_LOCAL( CF2_Fixed ) cf2_stack_getReal( CF2_Stack stack, CF2_UInt idx ); + FT_LOCAL( void ) + cf2_stack_setReal( CF2_Stack stack, + CF2_UInt idx, + CF2_Fixed val ); + + FT_LOCAL( void ) + cf2_stack_pop( CF2_Stack stack, + CF2_UInt num ); + + FT_LOCAL( void ) + cf2_stack_roll( CF2_Stack stack, + CF2_Int count, + CF2_Int idx ); FT_LOCAL( void ) cf2_stack_clear( CF2_Stack stack ); @@ -100,7 +115,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2STACK_H__ */ +#endif /* CF2STACK_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cf2types.h b/third_party/freetype/src/cff/cf2types.h index ac6a02266e..5b7e1239af 100644 --- a/third_party/freetype/src/cff/cf2types.h +++ b/third_party/freetype/src/cff/cf2types.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2TYPES_H__ -#define __CF2TYPES_H__ +#ifndef CF2TYPES_H_ +#define CF2TYPES_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -72,7 +72,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2TYPES_H__ */ +#endif /* CF2TYPES_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cff.c b/third_party/freetype/src/cff/cff.c index bb2cfb5253..545fb202c9 100644 --- a/third_party/freetype/src/cff/cff.c +++ b/third_party/freetype/src/cff/cff.c @@ -4,7 +4,7 @@ /* */ /* FreeType OpenType driver component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/cff/cffcmap.c b/third_party/freetype/src/cff/cffcmap.c index e7538e9840..4adce7a54d 100644 --- a/third_party/freetype/src/cff/cffcmap.c +++ b/third_party/freetype/src/cff/cffcmap.c @@ -4,7 +4,7 @@ /* */ /* CFF character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -104,15 +104,21 @@ } - FT_DEFINE_CMAP_CLASS(cff_cmap_encoding_class_rec, + FT_DEFINE_CMAP_CLASS( + cff_cmap_encoding_class_rec, + sizeof ( CFF_CMapStdRec ), - (FT_CMap_InitFunc) cff_cmap_encoding_init, - (FT_CMap_DoneFunc) cff_cmap_encoding_done, - (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, - (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next, + (FT_CMap_InitFunc) cff_cmap_encoding_init, /* init */ + (FT_CMap_DoneFunc) cff_cmap_encoding_done, /* done */ + (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, /* char_index */ + (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ ) @@ -202,15 +208,22 @@ } - FT_DEFINE_CMAP_CLASS(cff_cmap_unicode_class_rec, + FT_DEFINE_CMAP_CLASS( + cff_cmap_unicode_class_rec, + sizeof ( PS_UnicodesRec ), - (FT_CMap_InitFunc) cff_cmap_unicode_init, - (FT_CMap_DoneFunc) cff_cmap_unicode_done, - (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, - (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next, + (FT_CMap_InitFunc) cff_cmap_unicode_init, /* init */ + (FT_CMap_DoneFunc) cff_cmap_unicode_done, /* done */ + (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, /* char_index */ + (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ ) + /* END */ diff --git a/third_party/freetype/src/cff/cffcmap.h b/third_party/freetype/src/cff/cffcmap.h index 6eaed636ec..7792e04248 100644 --- a/third_party/freetype/src/cff/cffcmap.h +++ b/third_party/freetype/src/cff/cffcmap.h @@ -4,7 +4,7 @@ /* */ /* CFF character mapping table (cmap) support (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFFCMAP_H__ -#define __CFFCMAP_H__ +#ifndef CFFCMAP_H_ +#define CFFCMAP_H_ #include "cffobjs.h" @@ -61,7 +61,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFCMAP_H__ */ +#endif /* CFFCMAP_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cffdrivr.c b/third_party/freetype/src/cff/cffdrivr.c index a718b7a002..467b3edc70 100644 --- a/third_party/freetype/src/cff/cffdrivr.c +++ b/third_party/freetype/src/cff/cffdrivr.c @@ -4,7 +4,7 @@ /* */ /* OpenType font driver implementation (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,6 +32,10 @@ #include "cffcmap.h" #include "cffparse.h" +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_SERVICE_MULTIPLE_MASTERS_H +#endif + #include "cfferrs.h" #include "cffpic.h" @@ -207,6 +211,13 @@ if ( flags & FT_LOAD_VERTICAL_LAYOUT ) { +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* no fast retrieval for blended MM fonts without VVAR table */ + if ( !ttface->is_default_instance && + !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + return FT_THROW( Unimplemented_Feature ); +#endif + /* check whether we have data from the `vmtx' table at all; */ /* otherwise we extract the info from the CFF glyphstrings */ /* (instead of synthesizing a global value using the `OS/2' */ @@ -232,6 +243,13 @@ } else { +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* no fast retrieval for blended MM fonts without HVAR table */ + if ( !ttface->is_default_instance && + !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + return FT_THROW( Unimplemented_Feature ); +#endif + /* check whether we have data from the `hmtx' table at all */ if ( !ttface->horizontal.number_Of_HMetrics ) goto Missing_Table; @@ -291,6 +309,35 @@ FT_Error error; + /* CFF2 table does not have glyph names; */ + /* we need to use `post' table method */ + if ( font->version_major == 2 ) + { + FT_Library library = FT_FACE_LIBRARY( face ); + FT_Module sfnt_module = FT_Get_Module( library, "sfnt" ); + FT_Service_GlyphDict service = + (FT_Service_GlyphDict)ft_module_get_service( + sfnt_module, + FT_SERVICE_ID_GLYPH_DICT, + 0 ); + + + if ( service && service->get_name ) + return service->get_name( FT_FACE( face ), + glyph_index, + buffer, + buffer_max ); + else + { + FT_ERROR(( "cff_get_glyph_name:" + " cannot get glyph name from a CFF2 font\n" + " " + " without the `PSNames' module\n" )); + error = FT_THROW( Missing_Module ); + goto Exit; + } + } + if ( !font->psnames ) { FT_ERROR(( "cff_get_glyph_name:" @@ -332,6 +379,31 @@ cff = (CFF_FontRec *)face->extra.data; charset = &cff->charset; + /* CFF2 table does not have glyph names; */ + /* we need to use `post' table method */ + if ( cff->version_major == 2 ) + { + FT_Library library = FT_FACE_LIBRARY( face ); + FT_Module sfnt_module = FT_Get_Module( library, "sfnt" ); + FT_Service_GlyphDict service = + (FT_Service_GlyphDict)ft_module_get_service( + sfnt_module, + FT_SERVICE_ID_GLYPH_DICT, + 0 ); + + + if ( service && service->name_index ) + return service->name_index( FT_FACE( face ), glyph_name ); + else + { + FT_ERROR(( "cff_get_name_index:" + " cannot get glyph index from a CFF2 font\n" + " " + " without the `PSNames' module\n" )); + return 0; + } + } + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); if ( !psnames ) return 0; @@ -358,8 +430,9 @@ FT_DEFINE_SERVICE_GLYPHDICTREC( cff_service_glyph_dict, - (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)cff_get_name_index + + (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, /* get_name */ + (FT_GlyphDict_NameIndexFunc)cff_get_name_index /* name_index */ ) @@ -383,11 +456,11 @@ FT_Error error = FT_Err_Ok; - if ( cff && cff->font_info == NULL ) + if ( cff && !cff->font_info ) { - CFF_FontRecDict dict = &cff->top_font.font_dict; + CFF_FontRecDict dict = &cff->top_font.font_dict; PS_FontInfoRec *font_info = NULL; - FT_Memory memory = face->root.memory; + FT_Memory memory = face->root.memory; if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) ) @@ -421,11 +494,14 @@ FT_DEFINE_SERVICE_PSINFOREC( cff_service_ps_info, - (PS_GetFontInfoFunc) cff_ps_get_font_info, - (PS_GetFontExtraFunc) NULL, - (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, - (PS_GetFontPrivateFunc)NULL, /* unsupported with CFF fonts */ - (PS_GetFontValueFunc) NULL /* not implemented */ + + (PS_GetFontInfoFunc) cff_ps_get_font_info, /* ps_get_font_info */ + (PS_GetFontExtraFunc) NULL, /* ps_get_font_extra */ + (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, /* ps_has_glyph_names */ + /* unsupported with CFF fonts */ + (PS_GetFontPrivateFunc)NULL, /* ps_get_font_private */ + /* not implemented */ + (PS_GetFontValueFunc) NULL /* ps_get_font_value */ ) @@ -444,14 +520,15 @@ /* following the OpenType specification 1.7, we return the name stored */ /* in the `name' table for a CFF wrapped into an SFNT container */ - if ( sfnt ) + if ( FT_IS_SFNT( FT_FACE( face ) ) && sfnt ) { FT_Library library = FT_FACE_LIBRARY( face ); FT_Module sfnt_module = FT_Get_Module( library, "sfnt" ); FT_Service_PsFontName service = (FT_Service_PsFontName)ft_module_get_service( sfnt_module, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME ); + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, + 0 ); if ( service && service->get_ps_font_name ) @@ -464,7 +541,8 @@ FT_DEFINE_SERVICE_PSFONTNAMEREC( cff_service_ps_name, - (FT_PsName_GetFunc)cff_get_ps_name + + (FT_PsName_GetFunc)cff_get_ps_name /* get_ps_font_name */ ) @@ -489,21 +567,21 @@ FT_Library library = FT_FACE_LIBRARY( face ); - cmap_info->language = 0; - cmap_info->format = 0; - if ( cmap->clazz != &CFF_CMAP_ENCODING_CLASS_REC_GET && cmap->clazz != &CFF_CMAP_UNICODE_CLASS_REC_GET ) { FT_Module sfnt = FT_Get_Module( library, "sfnt" ); FT_Service_TTCMaps service = (FT_Service_TTCMaps)ft_module_get_service( sfnt, - FT_SERVICE_ID_TT_CMAP ); + FT_SERVICE_ID_TT_CMAP, + 0 ); if ( service && service->get_cmap_info ) error = service->get_cmap_info( charmap, cmap_info ); } + else + error = FT_THROW( Invalid_CharMap_Format ); return error; } @@ -511,7 +589,8 @@ FT_DEFINE_SERVICE_TTCMAPSREC( cff_service_get_cmap_info, - (TT_CMap_Info_GetFunc)cff_get_cmap_info + + (TT_CMap_Info_GetFunc)cff_get_cmap_info /* get_cmap_info */ ) @@ -542,7 +621,7 @@ if ( registry ) { - if ( cff->registry == NULL ) + if ( !cff->registry ) cff->registry = cff_index_get_sid_string( cff, dict->cid_registry ); *registry = cff->registry; @@ -550,7 +629,7 @@ if ( ordering ) { - if ( cff->ordering == NULL ) + if ( !cff->ordering ) cff->ordering = cff_index_get_sid_string( cff, dict->cid_ordering ); *ordering = cff->ordering; @@ -641,9 +720,13 @@ FT_DEFINE_SERVICE_CIDREC( cff_service_cid_info, - (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros, - (FT_CID_GetIsInternallyCIDKeyedFunc) cff_get_is_cid, - (FT_CID_GetCIDFromGlyphIndexFunc) cff_get_cid_from_glyph_index + + (FT_CID_GetRegistryOrderingSupplementFunc) + cff_get_ros, /* get_ros */ + (FT_CID_GetIsInternallyCIDKeyedFunc) + cff_get_is_cid, /* get_is_cid */ + (FT_CID_GetCIDFromGlyphIndexFunc) + cff_get_cid_from_glyph_index /* get_cid_from_glyph_index */ ) @@ -654,26 +737,62 @@ static FT_Error cff_property_set( FT_Module module, /* CFF_Driver */ const char* property_name, - const void* value ) + const void* value, + FT_Bool value_is_string ) { FT_Error error = FT_Err_Ok; CFF_Driver driver = (CFF_Driver)module; +#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + FT_UNUSED( value_is_string ); +#endif + if ( !ft_strcmp( property_name, "darkening-parameters" ) ) { - FT_Int* darken_params = (FT_Int*)value; + FT_Int* darken_params; + FT_Int x1, y1, x2, y2, x3, y3, x4, y4; - FT_Int x1 = darken_params[0]; - FT_Int y1 = darken_params[1]; - FT_Int x2 = darken_params[2]; - FT_Int y2 = darken_params[3]; - FT_Int x3 = darken_params[4]; - FT_Int y3 = darken_params[5]; - FT_Int x4 = darken_params[6]; - FT_Int y4 = darken_params[7]; +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + FT_Int dp[8]; + if ( value_is_string ) + { + const char* s = (const char*)value; + char* ep; + int i; + + + /* eight comma-separated numbers */ + for ( i = 0; i < 7; i++ ) + { + dp[i] = (FT_Int)ft_strtol( s, &ep, 10 ); + if ( *ep != ',' || s == ep ) + return FT_THROW( Invalid_Argument ); + + s = ep + 1; + } + + dp[7] = (FT_Int)ft_strtol( s, &ep, 10 ); + if ( !( *ep == '\0' || *ep == ' ' ) || s == ep ) + return FT_THROW( Invalid_Argument ); + + darken_params = dp; + } + else +#endif + darken_params = (FT_Int*)value; + + x1 = darken_params[0]; + y1 = darken_params[1]; + x2 = darken_params[2]; + y2 = darken_params[3]; + x3 = darken_params[4]; + y3 = darken_params[5]; + x4 = darken_params[6]; + y4 = darken_params[7]; + if ( x1 < 0 || x2 < 0 || x3 < 0 || x4 < 0 || y1 < 0 || y2 < 0 || y3 < 0 || y4 < 0 || x1 > x2 || x2 > x3 || x3 > x4 || @@ -693,24 +812,62 @@ } else if ( !ft_strcmp( property_name, "hinting-engine" ) ) { - FT_UInt* hinting_engine = (FT_UInt*)value; +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + if ( value_is_string ) + { + const char* s = (const char*)value; -#ifndef CFF_CONFIG_OPTION_OLD_ENGINE - if ( *hinting_engine != FT_CFF_HINTING_ADOBE ) - error = FT_ERR( Unimplemented_Feature ); + if ( !ft_strcmp( s, "adobe" ) ) + driver->hinting_engine = FT_CFF_HINTING_ADOBE; +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + else if ( !ft_strcmp( s, "freetype" ) ) + driver->hinting_engine = FT_CFF_HINTING_FREETYPE; +#endif + else + return FT_THROW( Invalid_Argument ); + } else #endif - driver->hinting_engine = *hinting_engine; + { + FT_UInt* hinting_engine = (FT_UInt*)value; - return error; + if ( *hinting_engine == FT_CFF_HINTING_ADOBE +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + || *hinting_engine == FT_CFF_HINTING_FREETYPE +#endif + ) + driver->hinting_engine = *hinting_engine; + else + error = FT_ERR( Unimplemented_Feature ); + + return error; + } } else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) { - FT_Bool* no_stem_darkening = (FT_Bool*)value; +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + if ( value_is_string ) + { + const char* s = (const char*)value; + long nsd = ft_strtol( s, NULL, 10 ); + + + if ( nsd == 0 ) + driver->no_stem_darkening = 0; + else if ( nsd == 1 ) + driver->no_stem_darkening = 1; + else + return FT_THROW( Invalid_Argument ); + } + else +#endif + { + FT_Bool* no_stem_darkening = (FT_Bool*)value; - driver->no_stem_darkening = *no_stem_darkening; + driver->no_stem_darkening = *no_stem_darkening; + } return error; } @@ -776,8 +933,92 @@ FT_DEFINE_SERVICE_PROPERTIESREC( cff_service_properties, - (FT_Properties_SetFunc)cff_property_set, - (FT_Properties_GetFunc)cff_property_get ) + + (FT_Properties_SetFunc)cff_property_set, /* set_property */ + (FT_Properties_GetFunc)cff_property_get ) /* get_property */ + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + /* + * MULTIPLE MASTER SERVICE + * + */ + + static FT_Error + cff_set_mm_blend( CFF_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->set_mm_blend( FT_FACE( face ), num_coords, coords ); + } + + + static FT_Error + cff_get_mm_blend( CFF_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->get_mm_blend( FT_FACE( face ), num_coords, coords ); + } + + + static FT_Error + cff_get_mm_var( CFF_Face face, + FT_MM_Var* *master ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->get_mm_var( FT_FACE( face ), master ); + } + + + static FT_Error + cff_set_var_design( CFF_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->set_var_design( FT_FACE( face ), num_coords, coords ); + } + + + static FT_Error + cff_get_var_design( CFF_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->get_var_design( FT_FACE( face ), num_coords, coords ); + } + + + FT_DEFINE_SERVICE_MULTIMASTERSREC( + cff_service_multi_masters, + + (FT_Get_MM_Func) NULL, /* get_mm */ + (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ + (FT_Set_MM_Blend_Func) cff_set_mm_blend, /* set_mm_blend */ + (FT_Get_MM_Blend_Func) cff_get_mm_blend, /* get_mm_blend */ + (FT_Get_MM_Var_Func) cff_get_mm_var, /* get_mm_var */ + (FT_Set_Var_Design_Func)cff_set_var_design, /* set_var_design */ + (FT_Get_Var_Design_Func)cff_get_var_design, /* get_var_design */ + + (FT_Get_Var_Blend_Func) cff_get_var_blend, /* get_var_blend */ + (FT_Done_Blend_Func) cff_done_blend /* done_blend */ + ) +#endif /*************************************************************************/ @@ -792,9 +1033,24 @@ /*************************************************************************/ /*************************************************************************/ -#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES +#if !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES && \ + defined TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_DEFINE_SERVICEDESCREC8( + cff_services, + + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, + FT_SERVICE_ID_MULTI_MASTERS, &CFF_SERVICE_MULTI_MASTERS_GET, + FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, + FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, + FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET + ) +#elif !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES FT_DEFINE_SERVICEDESCREC7( cff_services, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, @@ -803,9 +1059,22 @@ FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET ) +#elif defined TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_DEFINE_SERVICEDESCREC7( + cff_services, + + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, + FT_SERVICE_ID_MULTI_MASTERS, &CFF_SERVICE_MULTI_MASTERS_GET, + FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, + FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, + FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET + ) #else FT_DEFINE_SERVICEDESCREC6( cff_services, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, @@ -835,7 +1104,7 @@ #endif result = ft_service_list_lookup( CFF_SERVICES_GET, module_interface ); - if ( result != NULL ) + if ( result ) return result; /* `driver' is not yet evaluated in non-PIC mode */ @@ -865,42 +1134,41 @@ FT_DEFINE_DRIVER( cff_driver_class, - FT_MODULE_FONT_DRIVER | - FT_MODULE_DRIVER_SCALABLE | - FT_MODULE_DRIVER_HAS_HINTER, + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | + FT_MODULE_DRIVER_HAS_HINTER | + FT_MODULE_DRIVER_HINTS_LIGHTLY, sizeof ( CFF_DriverRec ), "cff", 0x10000L, 0x20000L, - 0, /* module-specific interface */ + NULL, /* module-specific interface */ - cff_driver_init, - cff_driver_done, - cff_get_interface, + cff_driver_init, /* FT_Module_Constructor module_init */ + cff_driver_done, /* FT_Module_Destructor module_done */ + cff_get_interface, /* FT_Module_Requester get_interface */ - /* now the specific driver fields */ sizeof ( TT_FaceRec ), sizeof ( CFF_SizeRec ), sizeof ( CFF_GlyphSlotRec ), - cff_face_init, - cff_face_done, - cff_size_init, - cff_size_done, - cff_slot_init, - cff_slot_done, - - cff_glyph_load, + cff_face_init, /* FT_Face_InitFunc init_face */ + cff_face_done, /* FT_Face_DoneFunc done_face */ + cff_size_init, /* FT_Size_InitFunc init_size */ + cff_size_done, /* FT_Size_DoneFunc done_size */ + cff_slot_init, /* FT_Slot_InitFunc init_slot */ + cff_slot_done, /* FT_Slot_DoneFunc done_slot */ - cff_get_kerning, - 0, /* FT_Face_AttachFunc */ - cff_get_advances, + cff_glyph_load, /* FT_Slot_LoadFunc load_glyph */ - cff_size_request, + cff_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ + cff_get_advances, /* FT_Face_GetAdvancesFunc get_advances */ - CFF_SIZE_SELECT + cff_size_request, /* FT_Size_RequestFunc request_size */ + CFF_SIZE_SELECT /* FT_Size_SelectFunc select_size */ ) diff --git a/third_party/freetype/src/cff/cffdrivr.h b/third_party/freetype/src/cff/cffdrivr.h index 9527f5e149..05381e66db 100644 --- a/third_party/freetype/src/cff/cffdrivr.h +++ b/third_party/freetype/src/cff/cffdrivr.h @@ -4,7 +4,7 @@ /* */ /* High-level OpenType driver interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFFDRIVER_H__ -#define __CFFDRIVER_H__ +#ifndef CFFDRIVER_H_ +#define CFFDRIVER_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFDRIVER_H__ */ +#endif /* CFFDRIVER_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cfferrs.h b/third_party/freetype/src/cff/cfferrs.h index 543bdb07c2..40808c1051 100644 --- a/third_party/freetype/src/cff/cfferrs.h +++ b/third_party/freetype/src/cff/cfferrs.h @@ -4,7 +4,7 @@ /* */ /* CFF error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __CFFERRS_H__ -#define __CFFERRS_H__ +#ifndef CFFERRS_H_ +#define CFFERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX CFF_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __CFFERRS_H__ */ +#endif /* CFFERRS_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cffgload.c b/third_party/freetype/src/cff/cffgload.c index 5f57403e22..f8e80c100d 100644 --- a/third_party/freetype/src/cff/cffgload.c +++ b/third_party/freetype/src/cff/cffgload.c @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -391,7 +391,7 @@ /* clear everything */ - FT_MEM_ZERO( decoder, sizeof ( *decoder ) ); + FT_ZERO( decoder ); /* initialize builder */ cff_builder_init( &decoder->builder, face, size, slot, hinting ); @@ -680,7 +680,7 @@ #endif /* FT_CONFIG_OPTION_INCREMENTAL */ { - CFF_Font cff = (CFF_Font)(face->extra.data); + CFF_Font cff = (CFF_Font)(face->extra.data); return cff_index_access_element( &cff->charstrings_index, glyph_index, @@ -826,7 +826,7 @@ /* the seac operator must not be nested */ decoder->seac = TRUE; error = cff_decoder_parse_charstrings( decoder, charstring, - charstring_len ); + charstring_len, 0 ); decoder->seac = FALSE; cff_free_glyph_data( face, &charstring, charstring_len ); @@ -856,7 +856,7 @@ /* the seac operator must not be nested */ decoder->seac = TRUE; error = cff_decoder_parse_charstrings( decoder, charstring, - charstring_len ); + charstring_len, 0 ); decoder->seac = FALSE; cff_free_glyph_data( face, &charstring, charstring_len ); @@ -895,13 +895,17 @@ /* */ /* charstring_len :: The length in bytes of the charstring stream. */ /* */ + /* in_dict :: Set to 1 if function is called from top or */ + /* private DICT (needed for Multiple Master CFFs). */ + /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) cff_decoder_parse_charstrings( CFF_Decoder* decoder, FT_Byte* charstring_base, - FT_ULong charstring_len ) + FT_ULong charstring_len, + FT_Bool in_dict ) { FT_Error error; CFF_Decoder_Zone* zone; @@ -913,6 +917,10 @@ FT_Fixed* stack; FT_Int charstring_type = decoder->cff->top_font.font_dict.charstring_type; + FT_UShort num_designs = + decoder->cff->top_font.font_dict.num_designs; + FT_UShort num_axes = + decoder->cff->top_font.font_dict.num_axes; T2_Hints_Funcs hinter; @@ -1018,7 +1026,7 @@ if ( !( val & 0xFFFFL ) ) FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) )); else - FT_TRACE4(( " %.2f", val / 65536.0 )); + FT_TRACE4(( " %.5f", val / 65536.0 )); #endif } @@ -1241,6 +1249,44 @@ if ( op == cff_op_unknown ) continue; + /* in Multiple Master CFFs, T2 charstrings can appear in */ + /* dictionaries, but some operators are prohibited */ + if ( in_dict ) + { + switch ( op ) + { + case cff_op_hstem: + case cff_op_vstem: + case cff_op_vmoveto: + case cff_op_rlineto: + case cff_op_hlineto: + case cff_op_vlineto: + case cff_op_rrcurveto: + case cff_op_hstemhm: + case cff_op_hintmask: + case cff_op_cntrmask: + case cff_op_rmoveto: + case cff_op_hmoveto: + case cff_op_vstemhm: + case cff_op_rcurveline: + case cff_op_rlinecurve: + case cff_op_vvcurveto: + case cff_op_hhcurveto: + case cff_op_vhcurveto: + case cff_op_hvcurveto: + case cff_op_hflex: + case cff_op_flex: + case cff_op_hflex1: + case cff_op_flex1: + case cff_op_callsubr: + case cff_op_callgsubr: + goto MM_Error; + + default: + break; + } + } + /* check arguments */ req_args = cff_argument_counts[op]; if ( req_args & CFF_COUNT_CHECK_WIDTH ) @@ -1278,7 +1324,9 @@ case cff_op_endchar: /* If there is a width specified for endchar, we either have */ /* 1 argument or 5 arguments. We like to argue. */ - set_width_ok = ( num_args == 5 ) || ( num_args == 1 ); + set_width_ok = in_dict + ? 0 + : ( ( num_args == 5 ) || ( num_args == 1 ) ); break; default: @@ -1971,6 +2019,10 @@ return error; case cff_op_endchar: + /* in dictionaries, `endchar' simply indicates end of data */ + if ( in_dict ) + return error; + FT_TRACE4(( " endchar\n" )); /* We are going to emulate the seac operator. */ @@ -2082,15 +2134,14 @@ if ( args[0] > 0 ) { - FT_Int count = 9; - FT_Fixed root = args[0]; + FT_Fixed root = args[0]; FT_Fixed new_root; for (;;) { new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1; - if ( new_root == root || count <= 0 ) + if ( new_root == root ) break; root = new_root; } @@ -2199,6 +2250,10 @@ FT_TRACE4(( " put\n" )); + /* the Type2 specification before version 16-March-2000 */ + /* didn't give a hard-coded size limit of the temporary */ + /* storage array; instead, an argument of the */ + /* `MultipleMaster' operator set the size */ if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) decoder->buildchar[idx] = val; } @@ -2221,14 +2276,68 @@ break; case cff_op_store: - FT_TRACE4(( " store\n")); + /* this operator was removed from the Type2 specification */ + /* in version 16-March-2000 */ - goto Unimplemented; + /* since we currently don't handle interpolation of multiple */ + /* master fonts, this is a no-op */ + FT_TRACE4(( " store\n")); + break; case cff_op_load: - FT_TRACE4(( " load\n" )); + /* this operator was removed from the Type2 specification */ + /* in version 16-March-2000 */ + { + FT_Int reg_idx = (FT_Int)args[0]; + FT_Int idx = (FT_Int)args[1]; + FT_Int count = (FT_Int)args[2]; + + + FT_TRACE4(( " load\n" )); + + /* since we currently don't handle interpolation of multiple */ + /* master fonts, we store a vector [1 0 0 ...] in the */ + /* temporary storage array regardless of the Registry index */ + if ( reg_idx >= 0 && reg_idx <= 2 && + idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS && + count >= 0 && count <= num_axes ) + { + FT_Int end, i; + + + end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS ); + + if ( idx < end ) + decoder->buildchar[idx] = 1 << 16; + + for ( i = idx + 1; i < end; i++ ) + decoder->buildchar[i] = 0; + } + } + break; - goto Unimplemented; + case cff_op_blend: + /* this operator was removed from the Type2 specification */ + /* in version 16-March-2000 */ + { + FT_Int num_results = (FT_Int)( args[0] >> 16 ); + + + FT_TRACE4(( " blend\n" )); + + if ( num_results < 0 ) + goto Syntax_Error; + + if ( num_results * (FT_Int)num_designs > num_args ) + goto Stack_Underflow; + + /* since we currently don't handle interpolation of multiple */ + /* master fonts, return the `num_results' values of the */ + /* first master */ + args -= num_results * ( num_designs - 1 ); + num_args -= num_results * ( num_designs - 1 ); + } + break; case cff_op_dotsection: /* this operator is deprecated and ignored by the parser */ @@ -2336,7 +2445,7 @@ case cff_op_and: { - FT_Fixed cond = args[0] && args[1]; + FT_Fixed cond = ( args[0] && args[1] ); FT_TRACE4(( " and\n" )); @@ -2348,7 +2457,7 @@ case cff_op_or: { - FT_Fixed cond = args[0] || args[1]; + FT_Fixed cond = ( args[0] || args[1] ); FT_TRACE4(( " or\n" )); @@ -2358,11 +2467,23 @@ } break; - case cff_op_eq: + case cff_op_not: { FT_Fixed cond = !args[0]; + FT_TRACE4(( " not\n" )); + + args[0] = cond ? 0x10000L : 0; + args++; + } + break; + + case cff_op_eq: + { + FT_Fixed cond = ( args[0] == args[1] ); + + FT_TRACE4(( " eq\n" )); args[0] = cond ? 0x10000L : 0; @@ -2489,7 +2610,6 @@ break; default: - Unimplemented: FT_ERROR(( "Unimplemented opcode: %d", ip[-1] )); if ( ip[-1] == 12 ) @@ -2513,6 +2633,11 @@ Fail: return error; + MM_Error: + FT_TRACE4(( "cff_decoder_parse_charstrings:" + " invalid opcode found in top DICT charstring\n")); + return FT_THROW( Invalid_File_Format ); + Syntax_Error: FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" )); return FT_THROW( Invalid_File_Format ); @@ -2586,7 +2711,8 @@ if ( !error ) error = cff_decoder_parse_charstrings( &decoder, charstring, - charstring_len ); + charstring_len, + 0 ); cff_free_glyph_data( face, &charstring, &charstring_len ); } @@ -2816,6 +2942,7 @@ cff_decoder_init( &decoder, face, size, glyph, hinting, FT_LOAD_TARGET_MODE( load_flags ) ); + /* this is for pure CFFs */ if ( load_flags & FT_LOAD_ADVANCE_ONLY ) decoder.width_only = TRUE; @@ -2837,7 +2964,8 @@ if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE ) error = cff_decoder_parse_charstrings( &decoder, charstring, - charstring_len ); + charstring_len, + 0 ); else #endif { diff --git a/third_party/freetype/src/cff/cffgload.h b/third_party/freetype/src/cff/cffgload.h index 5f2655f3d9..0fa93b4398 100644 --- a/third_party/freetype/src/cff/cffgload.h +++ b/third_party/freetype/src/cff/cffgload.h @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFFGLOAD_H__ -#define __CFFGLOAD_H__ +#ifndef CFFGLOAD_H_ +#define CFFGLOAD_H_ #include <ft2build.h> @@ -227,7 +227,8 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) cff_decoder_parse_charstrings( CFF_Decoder* decoder, FT_Byte* charstring_base, - FT_ULong charstring_len ); + FT_ULong charstring_len, + FT_Bool in_dict ); #endif FT_LOCAL( FT_Error ) @@ -239,7 +240,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFGLOAD_H__ */ +#endif /* CFFGLOAD_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cffload.c b/third_party/freetype/src/cff/cffload.c index c61222d651..935e612a09 100644 --- a/third_party/freetype/src/cff/cffload.c +++ b/third_party/freetype/src/cff/cffload.c @@ -4,7 +4,7 @@ /* */ /* OpenType and CFF data/program tables loader (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,20 @@ #include FT_TRUETYPE_TAGS_H #include FT_TYPE1_TABLES_H +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_MULTIPLE_MASTERS_H +#include FT_SERVICE_MULTIPLE_MASTERS_H +#endif + #include "cffload.h" #include "cffparse.h" #include "cfferrs.h" +#define FT_FIXED_ONE ( (FT_Fixed)0x10000 ) + + #if 1 static const FT_UShort cff_isoadobe_charset[229] = @@ -225,19 +233,33 @@ static FT_Error cff_index_init( CFF_Index idx, FT_Stream stream, - FT_Bool load ) + FT_Bool load, + FT_Bool cff2 ) { FT_Error error; FT_Memory memory = stream->memory; - FT_UShort count; + FT_UInt count; - FT_MEM_ZERO( idx, sizeof ( *idx ) ); + FT_ZERO( idx ); idx->stream = stream; idx->start = FT_STREAM_POS(); - if ( !FT_READ_USHORT( count ) && - count > 0 ) + + if ( cff2 ) + { + if ( FT_READ_ULONG( count ) ) + goto Exit; + idx->hdr_size = 5; + } + else + { + if ( FT_READ_USHORT( count ) ) + goto Exit; + idx->hdr_size = 3; + } + + if ( count > 0 ) { FT_Byte offsize; FT_ULong size; @@ -258,7 +280,7 @@ idx->off_size = offsize; size = (FT_ULong)( count + 1 ) * offsize; - idx->data_offset = idx->start + 3 + size; + idx->data_offset = idx->start + idx->hdr_size + size; if ( FT_STREAM_SKIP( size - offsize ) ) goto Exit; @@ -310,7 +332,7 @@ FT_FRAME_RELEASE( idx->bytes ); FT_FREE( idx->offsets ); - FT_MEM_ZERO( idx, sizeof ( *idx ) ); + FT_ZERO( idx ); } } @@ -323,7 +345,7 @@ FT_Memory memory = stream->memory; - if ( idx->count > 0 && idx->offsets == NULL ) + if ( idx->count > 0 && !idx->offsets ) { FT_Byte offsize = idx->off_size; FT_ULong data_size; @@ -335,7 +357,7 @@ data_size = (FT_ULong)( idx->count + 1 ) * offsize; if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) || - FT_STREAM_SEEK( idx->start + 3 ) || + FT_STREAM_SEEK( idx->start + idx->hdr_size ) || FT_FRAME_ENTER( data_size ) ) goto Exit; @@ -382,28 +404,31 @@ static FT_Error cff_index_get_pointers( CFF_Index idx, FT_Byte*** table, - FT_Byte** pool ) + FT_Byte** pool, + FT_ULong* pool_size ) { FT_Error error = FT_Err_Ok; FT_Memory memory = idx->stream->memory; FT_Byte** t = NULL; FT_Byte* new_bytes = NULL; + FT_ULong new_size; *table = NULL; - if ( idx->offsets == NULL ) + if ( !idx->offsets ) { error = cff_index_load_offsets( idx ); if ( error ) goto Exit; } - if ( idx->count > 0 && - !FT_NEW_ARRAY( t, idx->count + 1 ) && - ( !pool || !FT_ALLOC( new_bytes, - idx->data_size + idx->count ) ) ) + new_size = idx->data_size + idx->count; + + if ( idx->count > 0 && + !FT_NEW_ARRAY( t, idx->count + 1 ) && + ( !pool || !FT_ALLOC( new_bytes, new_size ) ) ) { FT_ULong n, cur_offset; FT_ULong extra = 0; @@ -459,6 +484,8 @@ if ( pool ) *pool = new_bytes; + if ( pool_size ) + *pool_size = new_size; } Exit: @@ -488,7 +515,7 @@ FT_ULong pos = element * idx->off_size; - if ( FT_STREAM_SEEK( idx->start + 3 + pos ) ) + if ( FT_STREAM_SEEK( idx->start + idx->hdr_size + pos ) ) goto Exit; off1 = cff_index_read_offset( idx, &error ); @@ -501,8 +528,8 @@ { element++; off2 = cff_index_read_offset( idx, &error ); - } - while ( off2 == 0 && element < idx->count ); + + } while ( off2 == 0 && element < idx->count ); } } else /* use offsets table */ @@ -584,20 +611,26 @@ FT_UInt element ) { CFF_Index idx = &font->name_index; - FT_Memory memory = idx->stream->memory; + FT_Memory memory; FT_Byte* bytes; FT_ULong byte_len; FT_Error error; FT_String* name = 0; + if ( !idx->stream ) /* CFF2 does not include a name index */ + goto Exit; + + memory = idx->stream->memory; + error = cff_index_access_element( idx, element, &bytes, &byte_len ); if ( error ) goto Exit; if ( !FT_ALLOC( name, byte_len + 1 ) ) { - FT_MEM_COPY( name, bytes, byte_len ); + if ( byte_len ) + FT_MEM_COPY( name, bytes, byte_len ); name[byte_len] = 0; } cff_index_forget_element( idx, &bytes ); @@ -719,6 +752,11 @@ FT_Byte fd = 0; + /* if there is no FDSelect, return zero */ + /* Note: CFF2 with just one Font Dict has no FDSelect */ + if ( !fdselect->data ) + goto Exit; + switch ( fdselect->format ) { case 0: @@ -771,6 +809,7 @@ ; } + Exit: return fd; } @@ -809,7 +848,7 @@ /* When multiple GIDs map to the same CID, we choose the lowest */ /* GID. This is not described in any spec, but it matches the */ /* behaviour of recent Acroread versions. */ - for ( j = (FT_Long)num_glyphs - 1; j >= 0 ; j-- ) + for ( j = (FT_Long)num_glyphs - 1; j >= 0; j-- ) charset->cids[charset->sids[j]] = (FT_UShort)j; charset->max_cid = max_cid; @@ -871,8 +910,8 @@ FT_UShort glyph_sid; - /* If the the offset is greater than 2, we have to parse the */ - /* charset table. */ + /* If the offset is greater than 2, we have to parse the charset */ + /* table. */ if ( offset > 2 ) { FT_UInt j; @@ -1049,6 +1088,512 @@ static void + cff_vstore_done( CFF_VStoreRec* vstore, + FT_Memory memory ) + { + FT_UInt i; + + + /* free regionList and axisLists */ + if ( vstore->varRegionList ) + { + for ( i = 0; i < vstore->regionCount; i++ ) + FT_FREE( vstore->varRegionList[i].axisList ); + } + FT_FREE( vstore->varRegionList ); + + /* free varData and indices */ + if ( vstore->varData ) + { + for ( i = 0; i < vstore->dataCount; i++ ) + FT_FREE( vstore->varData[i].regionIndices ); + } + FT_FREE( vstore->varData ); + } + + + /* convert 2.14 to Fixed */ + #define FT_fdot14ToFixed( x ) ( (FT_Fixed)( (FT_ULong)(x) << 2 ) ) + + + static FT_Error + cff_vstore_load( CFF_VStoreRec* vstore, + FT_Stream stream, + FT_ULong base_offset, + FT_ULong offset ) + { + FT_Memory memory = stream->memory; + FT_Error error = FT_ERR( Invalid_File_Format ); + + FT_ULong* dataOffsetArray = NULL; + FT_UInt i, j; + + + /* no offset means no vstore to parse */ + if ( offset ) + { + FT_UInt vsOffset; + FT_UInt format; + FT_ULong regionListOffset; + + + /* we need to parse the table to determine its size; */ + /* skip table length */ + if ( FT_STREAM_SEEK( base_offset + offset ) || + FT_STREAM_SKIP( 2 ) ) + goto Exit; + + /* actual variation store begins after the length */ + vsOffset = FT_STREAM_POS(); + + /* check the header */ + if ( FT_READ_USHORT( format ) ) + goto Exit; + if ( format != 1 ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* read top level fields */ + if ( FT_READ_ULONG( regionListOffset ) || + FT_READ_USHORT( vstore->dataCount ) ) + goto Exit; + + /* make temporary copy of item variation data offsets; */ + /* we'll parse region list first, then come back */ + if ( FT_NEW_ARRAY( dataOffsetArray, vstore->dataCount ) ) + goto Exit; + + for ( i = 0; i < vstore->dataCount; i++ ) + { + if ( FT_READ_ULONG( dataOffsetArray[i] ) ) + goto Exit; + } + + /* parse regionList and axisLists */ + if ( FT_STREAM_SEEK( vsOffset + regionListOffset ) || + FT_READ_USHORT( vstore->axisCount ) || + FT_READ_USHORT( vstore->regionCount ) ) + goto Exit; + + if ( FT_NEW_ARRAY( vstore->varRegionList, vstore->regionCount ) ) + goto Exit; + + for ( i = 0; i < vstore->regionCount; i++ ) + { + CFF_VarRegion* region = &vstore->varRegionList[i]; + + + if ( FT_NEW_ARRAY( region->axisList, vstore->axisCount ) ) + goto Exit; + + for ( j = 0; j < vstore->axisCount; j++ ) + { + CFF_AxisCoords* axis = ®ion->axisList[j]; + + FT_Int16 start14, peak14, end14; + + + if ( FT_READ_SHORT( start14 ) || + FT_READ_SHORT( peak14 ) || + FT_READ_SHORT( end14 ) ) + goto Exit; + + axis->startCoord = FT_fdot14ToFixed( start14 ); + axis->peakCoord = FT_fdot14ToFixed( peak14 ); + axis->endCoord = FT_fdot14ToFixed( end14 ); + } + } + + /* use dataOffsetArray now to parse varData items */ + if ( FT_NEW_ARRAY( vstore->varData, vstore->dataCount ) ) + goto Exit; + + for ( i = 0; i < vstore->dataCount; i++ ) + { + CFF_VarData* data = &vstore->varData[i]; + + + if ( FT_STREAM_SEEK( vsOffset + dataOffsetArray[i] ) ) + goto Exit; + + /* ignore `itemCount' and `shortDeltaCount' */ + /* because CFF2 has no delta sets */ + if ( FT_STREAM_SKIP( 4 ) ) + goto Exit; + + /* Note: just record values; consistency is checked later */ + /* by cff_blend_build_vector when it consumes `vstore' */ + + if ( FT_READ_USHORT( data->regionIdxCount ) ) + goto Exit; + + if ( FT_NEW_ARRAY( data->regionIndices, data->regionIdxCount ) ) + goto Exit; + + for ( j = 0; j < data->regionIdxCount; j++ ) + { + if ( FT_READ_USHORT( data->regionIndices[j] ) ) + goto Exit; + } + } + } + + error = FT_Err_Ok; + + Exit: + FT_FREE( dataOffsetArray ); + if ( error ) + cff_vstore_done( vstore, memory ); + + return error; + } + + + /* Clear blend stack (after blend values are consumed). */ + /* */ + /* TODO: Should do this in cff_run_parse, but subFont */ + /* ref is not available there. */ + /* */ + /* Allocation is not changed when stack is cleared. */ + FT_LOCAL_DEF( void ) + cff_blend_clear( CFF_SubFont subFont ) + { + subFont->blend_top = subFont->blend_stack; + subFont->blend_used = 0; + } + + + /* Blend numOperands on the stack, */ + /* store results into the first numBlends values, */ + /* then pop remaining arguments. */ + /* */ + /* This is comparable to `cf2_doBlend' but */ + /* the cffparse stack is different and can't be written. */ + /* Blended values are written to a different buffer, */ + /* using reserved operator 255. */ + /* */ + /* Blend calculation is done in 16.16 fixed point. */ + FT_LOCAL_DEF( FT_Error ) + cff_blend_doBlend( CFF_SubFont subFont, + CFF_Parser parser, + FT_UInt numBlends ) + { + FT_UInt delta; + FT_UInt base; + FT_UInt i, j; + FT_UInt size; + + CFF_Blend blend = &subFont->blend; + + FT_Memory memory = subFont->blend.font->memory; /* for FT_REALLOC */ + FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ + + /* compute expected number of operands for this blend */ + FT_UInt numOperands = (FT_UInt)( numBlends * blend->lenBV ); + FT_UInt count = (FT_UInt)( parser->top - 1 - parser->stack ); + + + if ( numOperands > count ) + { + FT_TRACE4(( " cff_blend_doBlend: Stack underflow %d args\n", count )); + + error = FT_THROW( Stack_Underflow ); + goto Exit; + } + + /* check whether we have room for `numBlends' values at `blend_top' */ + size = 5 * numBlends; /* add 5 bytes per entry */ + if ( subFont->blend_used + size > subFont->blend_alloc ) + { + FT_Byte* blend_stack_old = subFont->blend_stack; + FT_Byte* blend_top_old = subFont->blend_top; + + + /* increase or allocate `blend_stack' and reset `blend_top'; */ + /* prepare to append `numBlends' values to the buffer */ + if ( FT_REALLOC( subFont->blend_stack, + subFont->blend_alloc, + subFont->blend_alloc + size ) ) + goto Exit; + + subFont->blend_top = subFont->blend_stack + subFont->blend_used; + subFont->blend_alloc += size; + + /* iterate over the parser stack and adjust pointers */ + /* if the reallocated buffer has a different address */ + if ( blend_stack_old && + subFont->blend_stack != blend_stack_old ) + { + FT_PtrDist offset = subFont->blend_stack - blend_stack_old; + FT_Byte** p; + + + for ( p = parser->stack; p < parser->top; p++ ) + { + if ( *p >= blend_stack_old && *p < blend_top_old ) + *p += offset; + } + } + } + subFont->blend_used += size; + + base = count - numOperands; /* index of first blend arg */ + delta = base + numBlends; /* index of first delta arg */ + + for ( i = 0; i < numBlends; i++ ) + { + const FT_Int32* weight = &blend->BV[1]; + FT_Int32 sum; + + + /* convert inputs to 16.16 fixed point */ + sum = cff_parse_num( parser, &parser->stack[i + base] ) * 65536; + + for ( j = 1; j < blend->lenBV; j++ ) + sum += FT_MulFix( *weight++, + cff_parse_num( parser, + &parser->stack[delta++] ) * 65536 ); + + /* point parser stack to new value on blend_stack */ + parser->stack[i + base] = subFont->blend_top; + + /* Push blended result as Type 2 5-byte fixed point number. This */ + /* will not conflict with actual DICTs because 255 is a reserved */ + /* opcode in both CFF and CFF2 DICTs. See `cff_parse_num' for */ + /* decode of this, which rounds to an integer. */ + *subFont->blend_top++ = 255; + *subFont->blend_top++ = ( (FT_UInt32)sum & 0xFF000000U ) >> 24; + *subFont->blend_top++ = ( (FT_UInt32)sum & 0x00FF0000U ) >> 16; + *subFont->blend_top++ = ( (FT_UInt32)sum & 0x0000FF00U ) >> 8; + *subFont->blend_top++ = (FT_UInt32)sum & 0x000000FFU; + } + + /* leave only numBlends results on parser stack */ + parser->top = &parser->stack[base + numBlends]; + + Exit: + return error; + } + + + /* Compute a blend vector from variation store index and normalized */ + /* vector based on pseudo-code in OpenType Font Variations Overview. */ + /* */ + /* Note: lenNDV == 0 produces a default blend vector, (1,0,0,...). */ + FT_LOCAL_DEF( FT_Error ) + cff_blend_build_vector( CFF_Blend blend, + FT_UInt vsindex, + FT_UInt lenNDV, + FT_Fixed* NDV ) + { + FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ + FT_Memory memory = blend->font->memory; /* for FT_REALLOC */ + + FT_UInt len; + CFF_VStore vs; + CFF_VarData* varData; + FT_UInt master; + + + FT_ASSERT( lenNDV == 0 || NDV ); + + blend->builtBV = FALSE; + + vs = &blend->font->vstore; + + /* VStore and fvar must be consistent */ + if ( lenNDV != 0 && lenNDV != vs->axisCount ) + { + FT_TRACE4(( " cff_blend_build_vector: Axis count mismatch\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( vsindex >= vs->dataCount ) + { + FT_TRACE4(( " cff_blend_build_vector: vsindex out of range\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* select the item variation data structure */ + varData = &vs->varData[vsindex]; + + /* prepare buffer for the blend vector */ + len = varData->regionIdxCount + 1; /* add 1 for default component */ + if ( FT_REALLOC( blend->BV, + blend->lenBV * sizeof( *blend->BV ), + len * sizeof( *blend->BV ) ) ) + goto Exit; + + blend->lenBV = len; + + /* outer loop steps through master designs to be blended */ + for ( master = 0; master < len; master++ ) + { + FT_UInt j; + FT_UInt idx; + CFF_VarRegion* varRegion; + + + /* default factor is always one */ + if ( master == 0 ) + { + blend->BV[master] = FT_FIXED_ONE; + FT_TRACE4(( " build blend vector len %d\n" + " [ %f ", + len, + blend->BV[master] / 65536.0 )); + continue; + } + + /* VStore array does not include default master, so subtract one */ + idx = varData->regionIndices[master - 1]; + varRegion = &vs->varRegionList[idx]; + + if ( idx >= vs->regionCount ) + { + FT_TRACE4(( " cff_blend_build_vector:" + " region index out of range\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* Note: `lenNDV' could be zero. */ + /* In that case, build default blend vector (1,0,0...). */ + /* In the normal case, initialize each component to 1 */ + /* before inner loop. */ + if ( lenNDV != 0 ) + blend->BV[master] = FT_FIXED_ONE; /* default */ + + /* inner loop steps through axes in this region */ + for ( j = 0; j < lenNDV; j++ ) + { + CFF_AxisCoords* axis = &varRegion->axisList[j]; + FT_Fixed axisScalar; + + + /* compute the scalar contribution of this axis; */ + /* ignore invalid ranges */ + if ( axis->startCoord > axis->peakCoord || + axis->peakCoord > axis->endCoord ) + axisScalar = FT_FIXED_ONE; + + else if ( axis->startCoord < 0 && + axis->endCoord > 0 && + axis->peakCoord != 0 ) + axisScalar = FT_FIXED_ONE; + + /* peak of 0 means ignore this axis */ + else if ( axis->peakCoord == 0 ) + axisScalar = FT_FIXED_ONE; + + /* ignore this region if coords are out of range */ + else if ( NDV[j] < axis->startCoord || + NDV[j] > axis->endCoord ) + axisScalar = 0; + + /* calculate a proportional factor */ + else + { + if ( NDV[j] == axis->peakCoord ) + axisScalar = FT_FIXED_ONE; + else if ( NDV[j] < axis->peakCoord ) + axisScalar = FT_DivFix( NDV[j] - axis->startCoord, + axis->peakCoord - axis->startCoord ); + else + axisScalar = FT_DivFix( axis->endCoord - NDV[j], + axis->endCoord - axis->peakCoord ); + } + + /* take product of all the axis scalars */ + blend->BV[master] = FT_MulFix( blend->BV[master], axisScalar ); + } + + FT_TRACE4(( ", %f ", + blend->BV[master] / 65536.0 )); + } + + FT_TRACE4(( "]\n" )); + + /* record the parameters used to build the blend vector */ + blend->lastVsindex = vsindex; + + if ( lenNDV != 0 ) + { + /* user has set a normalized vector */ + if ( FT_REALLOC( blend->lastNDV, + blend->lenNDV * sizeof ( *NDV ), + lenNDV * sizeof ( *NDV ) ) ) + goto Exit; + + blend->lenNDV = lenNDV; + FT_MEM_COPY( blend->lastNDV, + NDV, + lenNDV * sizeof ( *NDV ) ); + } + + blend->builtBV = TRUE; + + Exit: + return error; + } + + + /* `lenNDV' is zero for default vector; */ + /* return TRUE if blend vector needs to be built. */ + FT_LOCAL_DEF( FT_Bool ) + cff_blend_check_vector( CFF_Blend blend, + FT_UInt vsindex, + FT_UInt lenNDV, + FT_Fixed* NDV ) + { + if ( !blend->builtBV || + blend->lastVsindex != vsindex || + blend->lenNDV != lenNDV || + ( lenNDV && + memcmp( NDV, + blend->lastNDV, + lenNDV * sizeof ( *NDV ) ) != 0 ) ) + { + /* need to build blend vector */ + return TRUE; + } + + return FALSE; + } + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + FT_LOCAL_DEF( FT_Error ) + cff_get_var_blend( CFF_Face face, + FT_UInt *num_coords, + FT_Fixed* *coords, + FT_MM_Var* *mm_var ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->get_var_blend( FT_FACE( face ), num_coords, coords, mm_var ); + } + + + FT_LOCAL_DEF( void ) + cff_done_blend( CFF_Face face ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + mm->done_blend( FT_FACE( face ) ); + } + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + + static void cff_encoding_done( CFF_Encoding encoding ) { encoding->format = 0; @@ -1300,26 +1845,127 @@ } + /* Parse private dictionary; first call is always from `cff_face_init', */ + /* so NDV has not been set for CFF2 variation. */ + /* */ + /* `cff_slot_load' must call this function each time NDV changes. */ + FT_LOCAL_DEF( FT_Error ) + cff_load_private_dict( CFF_Font font, + CFF_SubFont subfont, + FT_UInt lenNDV, + FT_Fixed* NDV ) + { + FT_Error error = FT_Err_Ok; + CFF_ParserRec parser; + CFF_FontRecDict top = &subfont->font_dict; + CFF_Private priv = &subfont->private_dict; + FT_Stream stream = font->stream; + FT_UInt stackSize; + + + /* store handle needed to access memory, vstore for blend; */ + /* we need this for clean-up even if there is no private DICT */ + subfont->blend.font = font; + subfont->blend.usedBV = FALSE; /* clear state */ + + if ( !top->private_offset || !top->private_size ) + goto Exit2; /* no private DICT, do nothing */ + + /* set defaults */ + FT_ZERO( priv ); + + priv->blue_shift = 7; + priv->blue_fuzz = 1; + priv->lenIV = -1; + priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); + priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); + + /* provide inputs for blend calculations */ + priv->subfont = subfont; + subfont->lenNDV = lenNDV; + subfont->NDV = NDV; + + stackSize = font->cff2 ? font->top_font.font_dict.maxstack + : CFF_MAX_STACK_DEPTH + 1; + + if ( cff_parser_init( &parser, + font->cff2 ? CFF2_CODE_PRIVATE : CFF_CODE_PRIVATE, + priv, + font->library, + stackSize, + top->num_designs, + top->num_axes ) ) + goto Exit; + + if ( FT_STREAM_SEEK( font->base_offset + top->private_offset ) || + FT_FRAME_ENTER( top->private_size ) ) + goto Exit; + + FT_TRACE4(( " private dictionary:\n" )); + error = cff_parser_run( &parser, + (FT_Byte*)stream->cursor, + (FT_Byte*)stream->limit ); + FT_FRAME_EXIT(); + + if ( error ) + goto Exit; + + /* ensure that `num_blue_values' is even */ + priv->num_blue_values &= ~1; + + Exit: + /* clean up */ + cff_blend_clear( subfont ); /* clear blend stack */ + cff_parser_done( &parser ); /* free parser stack */ + + Exit2: + /* no clean up (parser not initialized) */ + return error; + } + + + /* There are 3 ways to call this function, distinguished by code. */ + /* */ + /* . CFF_CODE_TOPDICT for either a CFF Top DICT or a CFF Font DICT */ + /* . CFF2_CODE_TOPDICT for CFF2 Top DICT */ + /* . CFF2_CODE_FONTDICT for CFF2 Font DICT */ + static FT_Error - cff_subfont_load( CFF_SubFont font, + cff_subfont_load( CFF_SubFont subfont, CFF_Index idx, FT_UInt font_index, FT_Stream stream, FT_ULong base_offset, - FT_Library library ) + FT_UInt code, + CFF_Font font ) { FT_Error error; CFF_ParserRec parser; FT_Byte* dict = NULL; FT_ULong dict_len; - CFF_FontRecDict top = &font->font_dict; - CFF_Private priv = &font->private_dict; - - - cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library ); + CFF_FontRecDict top = &subfont->font_dict; + CFF_Private priv = &subfont->private_dict; + + FT_Bool cff2 = FT_BOOL( code == CFF2_CODE_TOPDICT || + code == CFF2_CODE_FONTDICT ); + FT_UInt stackSize = cff2 ? CFF2_DEFAULT_STACK + : CFF_MAX_STACK_DEPTH; + + + /* Note: We use default stack size for CFF2 Font DICT because */ + /* Top and Font DICTs are not allowed to have blend operators. */ + error = cff_parser_init( &parser, + code, + &subfont->font_dict, + font->library, + stackSize, + 0, + 0 ); + if ( error ) + goto Exit; /* set defaults */ - FT_MEM_ZERO( top, sizeof ( *top ) ); + FT_ZERO( top ); top->underline_position = -( 100L << 16 ); top->underline_thickness = 50L << 16; @@ -1342,14 +1988,35 @@ top->cid_ordering = 0xFFFFU; top->cid_font_name = 0xFFFFU; - error = cff_index_access_element( idx, font_index, &dict, &dict_len ); + /* set default stack size */ + top->maxstack = cff2 ? CFF2_DEFAULT_STACK : 48; + + if ( idx->count ) /* count is nonzero for a real index */ + error = cff_index_access_element( idx, font_index, &dict, &dict_len ); + else + { + /* CFF2 has a fake top dict index; */ + /* simulate `cff_index_access_element' */ + + /* Note: macros implicitly use `stream' and set `error' */ + if ( FT_STREAM_SEEK( idx->data_offset ) || + FT_FRAME_EXTRACT( idx->data_size, dict ) ) + goto Exit; + + dict_len = idx->data_size; + } + if ( !error ) { FT_TRACE4(( " top dictionary:\n" )); error = cff_parser_run( &parser, dict, dict + dict_len ); } - cff_index_forget_element( idx, &dict ); + /* clean up regardless of error */ + if ( idx->count ) + cff_index_forget_element( idx, &dict ); + else + FT_FRAME_RELEASE( dict ); if ( error ) goto Exit; @@ -1358,35 +2025,14 @@ if ( top->cid_registry != 0xFFFFU ) goto Exit; - /* parse the private dictionary, if any */ - if ( top->private_offset && top->private_size ) - { - /* set defaults */ - FT_MEM_ZERO( priv, sizeof ( *priv ) ); - - priv->blue_shift = 7; - priv->blue_fuzz = 1; - priv->lenIV = -1; - priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); - priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); - - cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library ); - - if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) || - FT_FRAME_ENTER( font->font_dict.private_size ) ) - goto Exit; - - FT_TRACE4(( " private dictionary:\n" )); - error = cff_parser_run( &parser, - (FT_Byte*)stream->cursor, - (FT_Byte*)stream->limit ); - FT_FRAME_EXIT(); - if ( error ) - goto Exit; - - /* ensure that `num_blue_values' is even */ - priv->num_blue_values &= ~1; - } + /* Parse the private dictionary, if any. */ + /* */ + /* CFF2 does not have a private dictionary in the Top DICT */ + /* but may have one in a Font DICT. We need to parse */ + /* the latter here in order to load any local subrs. */ + error = cff_load_private_dict( font, subfont, 0, 0 ); + if ( error ) + goto Exit; /* read the local subrs, if any */ if ( priv->local_subrs_offset ) @@ -1395,17 +2041,19 @@ priv->local_subrs_offset ) ) goto Exit; - error = cff_index_init( &font->local_subrs_index, stream, 1 ); + error = cff_index_init( &subfont->local_subrs_index, stream, 1, cff2 ); if ( error ) goto Exit; - error = cff_index_get_pointers( &font->local_subrs_index, - &font->local_subrs, NULL ); + error = cff_index_get_pointers( &subfont->local_subrs_index, + &subfont->local_subrs, NULL, NULL ); if ( error ) goto Exit; } Exit: + cff_parser_done( &parser ); /* free parser stack */ + return error; } @@ -1418,6 +2066,10 @@ { cff_index_done( &subfont->local_subrs_index ); FT_FREE( subfont->local_subrs ); + + FT_FREE( subfont->blend.lastNDV ); + FT_FREE( subfont->blend.BV ); + FT_FREE( subfont->blend_stack ); } } @@ -1427,18 +2079,18 @@ FT_Stream stream, FT_Int face_index, CFF_Font font, - FT_Bool pure_cff ) + FT_Bool pure_cff, + FT_Bool cff2 ) { static const FT_Frame_Field cff_header_fields[] = { #undef FT_STRUCTURE #define FT_STRUCTURE CFF_FontRec - FT_FRAME_START( 4 ), + FT_FRAME_START( 3 ), FT_FRAME_BYTE( version_major ), FT_FRAME_BYTE( version_minor ), FT_FRAME_BYTE( header_size ), - FT_FRAME_BYTE( absolute_offsize ), FT_FRAME_END }; @@ -1453,42 +2105,131 @@ FT_ZERO( font ); FT_ZERO( &string_index ); - font->stream = stream; - font->memory = memory; - dict = &font->top_font.font_dict; - base_offset = FT_STREAM_POS(); + dict = &font->top_font.font_dict; + base_offset = FT_STREAM_POS(); + + font->library = library; + font->stream = stream; + font->memory = memory; + font->cff2 = cff2; + font->base_offset = base_offset; /* read CFF font header */ if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) ) goto Exit; - /* check format */ - if ( font->version_major != 1 || - font->header_size < 4 || - font->absolute_offsize > 4 ) + if ( cff2 ) { - FT_TRACE2(( " not a CFF font header\n" )); - error = FT_THROW( Unknown_File_Format ); - goto Exit; + if ( font->version_major != 2 || + font->header_size < 5 ) + { + FT_TRACE2(( " not a CFF2 font header\n" )); + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + if ( FT_READ_USHORT( font->top_dict_length ) ) + goto Exit; + } + else + { + FT_Byte absolute_offset; + + + if ( FT_READ_BYTE( absolute_offset ) ) + goto Exit; + + if ( font->version_major != 1 || + font->header_size < 4 || + absolute_offset > 4 ) + { + FT_TRACE2(( " not a CFF font header\n" )); + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } } /* skip the rest of the header */ - if ( FT_STREAM_SKIP( font->header_size - 4 ) ) + if ( FT_STREAM_SEEK( base_offset + font->header_size ) ) + { + /* For pure CFFs we have read only four bytes so far. Contrary to */ + /* other formats like SFNT those bytes doesn't define a signature; */ + /* it is thus possible that the font isn't a CFF at all. */ + if ( pure_cff ) + { + FT_TRACE2(( " not a CFF file\n" )); + error = FT_THROW( Unknown_File_Format ); + } goto Exit; + } - /* read the name, top dict, string and global subrs index */ - 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( &string_index, - stream, 1 ) ) || - FT_SET_ERROR( cff_index_init( &font->global_subrs_index, - stream, 1 ) ) || - FT_SET_ERROR( cff_index_get_pointers( &string_index, - &font->strings, - &font->string_pool ) ) ) - goto Exit; + if ( cff2 ) + { + /* For CFF2, the top dict data immediately follow the header */ + /* and the length is stored in the header `offSize' field; */ + /* there is no index for it. */ + /* */ + /* Use the `font_dict_index' to save the current position */ + /* and length of data, but leave count at zero as an indicator. */ + FT_ZERO( &font->font_dict_index ); + + font->font_dict_index.data_offset = FT_STREAM_POS(); + font->font_dict_index.data_size = font->top_dict_length; + + /* skip the top dict data for now, we will parse it later */ + if ( FT_STREAM_SKIP( font->top_dict_length ) ) + goto Exit; + + /* next, read the global subrs index */ + if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index, + stream, 1, cff2 ) ) ) + goto Exit; + } + else + { + /* for CFF, read the name, top dict, string and global subrs index */ + if ( FT_SET_ERROR( cff_index_init( &font->name_index, + stream, 0, cff2 ) ) ) + { + if ( pure_cff ) + { + FT_TRACE2(( " not a CFF file\n" )); + error = FT_THROW( Unknown_File_Format ); + } + goto Exit; + } + + /* font names must not be empty */ + if ( font->name_index.data_size < font->name_index.count ) + { + /* for pure CFFs, we still haven't checked enough bytes */ + /* to be sure that it is a CFF at all */ + error = pure_cff ? FT_THROW( Unknown_File_Format ) + : FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( FT_SET_ERROR( cff_index_init( &font->font_dict_index, + stream, 0, cff2 ) ) || + FT_SET_ERROR( cff_index_init( &string_index, + stream, 1, cff2 ) ) || + FT_SET_ERROR( cff_index_init( &font->global_subrs_index, + stream, 1, cff2 ) ) || + FT_SET_ERROR( cff_index_get_pointers( &string_index, + &font->strings, + &font->string_pool, + &font->string_pool_size ) ) ) + goto Exit; + + /* there must be a Top DICT index entry for each name index entry */ + if ( font->name_index.count > font->font_dict_index.count ) + { + FT_ERROR(( "cff_font_load:" + " not enough entries in Top DICT index\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + } font->num_strings = string_index.count; @@ -1534,34 +2275,47 @@ subfont_index, stream, base_offset, - library ); + cff2 ? CFF2_CODE_TOPDICT : CFF_CODE_TOPDICT, + font ); if ( error ) goto Exit; if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) goto Exit; - error = cff_index_init( &font->charstrings_index, stream, 0 ); + error = cff_index_init( &font->charstrings_index, stream, 0, cff2 ); if ( error ) goto Exit; - /* now, check for a CID font */ - if ( dict->cid_registry != 0xFFFFU ) + /* now, check for a CID or CFF2 font */ + if ( dict->cid_registry != 0xFFFFU || + cff2 ) { CFF_IndexRec fd_index; CFF_SubFont sub = NULL; FT_UInt idx; + /* for CFF2, read the Variation Store if available; */ + /* this must follow the Top DICT parse and precede any Private DICT */ + error = cff_vstore_load( &font->vstore, + stream, + base_offset, + dict->vstore_offset ); + if ( error ) + goto Exit; + /* this is a CID-keyed font, we must now allocate a table of */ /* sub-fonts, then load each of them separately */ if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) ) goto Exit; - error = cff_index_init( &fd_index, stream, 0 ); + error = cff_index_init( &fd_index, stream, 0, cff2 ); if ( error ) goto Exit; + /* Font Dicts are not limited to 256 for CFF2. */ + /* TODO: support this for CFF2 */ if ( fd_index.count > CFF_MAX_CID_FONTS ) { FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" )); @@ -1582,17 +2336,25 @@ { sub = font->subfonts[idx]; FT_TRACE4(( "parsing subfont %u\n", idx )); - error = cff_subfont_load( sub, &fd_index, idx, - stream, base_offset, library ); + error = cff_subfont_load( sub, + &fd_index, + idx, + stream, + base_offset, + cff2 ? CFF2_CODE_FONTDICT + : CFF_CODE_TOPDICT, + font ); if ( error ) goto Fail_CID; } - /* now load the FD Select array */ - error = CFF_Load_FD_Select( &font->fd_select, - font->charstrings_index.count, - stream, - base_offset + dict->cid_fd_select_offset ); + /* now load the FD Select array; */ + /* CFF2 omits FDSelect if there is only one FD */ + if ( !cff2 || fd_index.count > 1 ) + error = CFF_Load_FD_Select( &font->fd_select, + font->charstrings_index.count, + stream, + base_offset + dict->cid_fd_select_offset ); Fail_CID: cff_index_done( &fd_index ); @@ -1614,13 +2376,13 @@ font->num_glyphs = font->charstrings_index.count; error = cff_index_get_pointers( &font->global_subrs_index, - &font->global_subrs, NULL ); + &font->global_subrs, NULL, NULL ); if ( error ) goto Exit; /* read the Charset and Encoding tables if available */ - if ( font->num_glyphs > 0 ) + if ( !cff2 && font->num_glyphs > 0 ) { FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff ); @@ -1668,7 +2430,7 @@ cff_index_done( &font->charstrings_index ); /* release font dictionaries, but only if working with */ - /* a CID keyed CFF font */ + /* a CID keyed CFF font or a CFF2 font */ if ( font->num_subfonts > 0 ) { for ( idx = 0; idx < font->num_subfonts; idx++ ) @@ -1680,6 +2442,7 @@ cff_encoding_done( &font->encoding ); cff_charset_done( &font->charset, font->stream ); + cff_vstore_done( &font->vstore, memory ); cff_subfont_done( memory, &font->top_font ); diff --git a/third_party/freetype/src/cff/cffload.h b/third_party/freetype/src/cff/cffload.h index 459e7b0446..8be645261b 100644 --- a/third_party/freetype/src/cff/cffload.h +++ b/third_party/freetype/src/cff/cffload.h @@ -4,7 +4,7 @@ /* */ /* OpenType & CFF data/program tables loader (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,12 +16,14 @@ /***************************************************************************/ -#ifndef __CFFLOAD_H__ -#define __CFFLOAD_H__ +#ifndef CFFLOAD_H_ +#define CFFLOAD_H_ #include <ft2build.h> #include "cfftypes.h" +#include "cffparse.h" +#include "cffobjs.h" /* for CFF_Face */ FT_BEGIN_HEADER @@ -60,24 +62,62 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) - cff_font_load( FT_Library library, - FT_Stream stream, - FT_Int face_index, - CFF_Font font, - FT_Bool pure_cff ); + cff_font_load( FT_Library library, + FT_Stream stream, + FT_Int face_index, + CFF_Font font, + FT_Bool pure_cff, + FT_Bool cff2 ); FT_LOCAL( void ) cff_font_done( CFF_Font font ); + FT_LOCAL( FT_Error ) + cff_load_private_dict( CFF_Font font, + CFF_SubFont subfont, + FT_UInt lenNDV, + FT_Fixed* NDV ); + FT_LOCAL( FT_Byte ) cff_fd_select_get( CFF_FDSelect fdselect, FT_UInt glyph_index ); + FT_LOCAL( FT_Bool ) + cff_blend_check_vector( CFF_Blend blend, + FT_UInt vsindex, + FT_UInt lenNDV, + FT_Fixed* NDV ); + + FT_LOCAL( FT_Error ) + cff_blend_build_vector( CFF_Blend blend, + FT_UInt vsindex, + FT_UInt lenNDV, + FT_Fixed* NDV ); + + FT_LOCAL( void ) + cff_blend_clear( CFF_SubFont subFont ); + + FT_LOCAL( FT_Error ) + cff_blend_doBlend( CFF_SubFont subfont, + CFF_Parser parser, + FT_UInt numBlends ); + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_LOCAL( FT_Error ) + cff_get_var_blend( CFF_Face face, + FT_UInt *num_coords, + FT_Fixed* *coords, + FT_MM_Var* *mm_var ); + + FT_LOCAL( void ) + cff_done_blend( CFF_Face face ); +#endif + FT_END_HEADER -#endif /* __CFFLOAD_H__ */ +#endif /* CFFLOAD_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cffobjs.c b/third_party/freetype/src/cff/cffobjs.c index 0e0d5b034b..a63935002c 100644 --- a/third_party/freetype/src/cff/cffobjs.c +++ b/third_party/freetype/src/cff/cffobjs.c @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -114,7 +114,7 @@ FT_UInt n, count; - FT_MEM_ZERO( priv, sizeof ( *priv ) ); + FT_ZERO( priv ); count = priv->num_blue_values = cpriv->num_blue_values; for ( n = 0; n < count; n++ ) @@ -450,7 +450,7 @@ FT_Int idx; - for ( idx = 1; idx <= style_name_length; ++idx ) + for ( idx = 1; idx <= style_name_length; idx++ ) { if ( family_name[family_name_length - idx] != style_name[style_name_length - idx] ) @@ -469,7 +469,7 @@ family_name[idx] == ' ' || family_name[idx] == '_' || family_name[idx] == '+' ) ) - --idx; + idx--; if ( idx > 0 ) family_name[idx + 1] = '\0'; @@ -491,6 +491,7 @@ FT_Service_PsCMaps psnames; PSHinter_Service pshinter; FT_Bool pure_cff = 1; + FT_Bool cff2 = 0; FT_Bool sfnt_format = 0; FT_Library library = cffface->driver->root.library; @@ -516,6 +517,7 @@ goto Exit; /* check whether we have a valid OpenType file */ + FT_TRACE2(( " " )); error = sfnt->init_face( stream, face, face_index, num_params, params ); if ( !error ) { @@ -553,8 +555,18 @@ goto Exit; } - /* now load the CFF part of the file */ - error = face->goto_table( face, TTAG_CFF, stream, 0 ); + /* now load the CFF part of the file; */ + /* give priority to CFF2 */ + error = face->goto_table( face, TTAG_CFF2, stream, 0 ); + if ( !error ) + { + cff2 = 1; + face->isCFF2 = cff2; + } + + if ( FT_ERR_EQ( error, Table_Missing ) ) + error = face->goto_table( face, TTAG_CFF, stream, 0 ); + if ( error ) goto Exit; } @@ -579,14 +591,22 @@ goto Exit; face->extra.data = cff; - error = cff_font_load( library, stream, face_index, cff, pure_cff ); + error = cff_font_load( library, + stream, + face_index, + cff, + pure_cff, + cff2 ); if ( error ) goto Exit; /* if we are performing a simple font format check, exit immediately */ /* (this is here for pure CFF) */ if ( face_index < 0 ) + { + cffface->num_faces = (FT_Long)cff->num_faces; return FT_Err_Ok; + } cff->pshinter = pshinter; cff->psnames = psnames; @@ -622,22 +642,112 @@ FT_TRACE4(( "SIDs\n" )); /* dump string index, including default strings for convenience */ - for ( idx = 0; idx < cff->num_strings + 390; idx++ ) + for ( idx = 0; idx <= 390; idx++ ) { s = cff_index_get_sid_string( cff, idx ); if ( s ) - FT_TRACE4((" %5d %s\n", idx, s )); + FT_TRACE4(( " %5d %s\n", idx, s )); + } + + /* In Multiple Master CFFs, two SIDs hold the Normalize Design */ + /* Vector (NDV) and Convert Design Vector (CDV) charstrings, */ + /* which may contain NULL bytes in the middle of the data, too. */ + /* We thus access `cff->strings' directly. */ + for ( idx = 1; idx < cff->num_strings; idx++ ) + { + FT_Byte* s1 = cff->strings[idx - 1]; + FT_Byte* s2 = cff->strings[idx]; + FT_PtrDist s1len = s2 - s1 - 1; /* without the final NULL byte */ + FT_PtrDist l; + + + FT_TRACE4(( " %5d ", idx + 390 )); + for ( l = 0; l < s1len; l++ ) + FT_TRACE4(( "%c", s1[l] )); + FT_TRACE4(( "\n" )); + } + + /* print last element */ + if ( cff->num_strings ) + { + FT_Byte* s1 = cff->strings[cff->num_strings - 1]; + FT_Byte* s2 = cff->string_pool + cff->string_pool_size; + FT_PtrDist s1len = s2 - s1 - 1; + FT_PtrDist l; + + + FT_TRACE4(( " %5d ", cff->num_strings + 390 )); + for ( l = 0; l < s1len; l++ ) + FT_TRACE4(( "%c", s1[l] )); + FT_TRACE4(( "\n" )); } } #endif /* FT_DEBUG_LEVEL_TRACE */ + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + FT_Int instance_index = face_index >> 16; + + + if ( FT_HAS_MULTIPLE_MASTERS( cffface ) && + mm && + instance_index > 0 ) + { + FT_MM_Var* mm_var; + + + error = mm->get_mm_var( cffface, NULL ); + if ( error ) + goto Exit; + + mm->get_var_blend( cffface, NULL, NULL, &mm_var ); + + if ( mm_var->namedstyle ) + { + FT_Var_Named_Style* named_style; + FT_String* style_name; + + + /* in `face_index', the instance index starts with value 1 */ + named_style = mm_var->namedstyle + instance_index - 1; + error = sfnt->get_name( face, + (FT_UShort)named_style->strid, + &style_name ); + if ( error ) + goto Exit; + + /* set style name; if already set, replace it */ + if ( face->root.style_name ) + FT_FREE( face->root.style_name ); + face->root.style_name = style_name; + + /* finally, select the named instance */ + error = mm->set_var_design( cffface, + mm_var->num_axis, + named_style->coords ); + if ( error ) + goto Exit; + } + } + } + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + + if ( !dict->has_font_matrix ) dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM; - /* Normalize the font matrix so that `matrix->yy' is 1; the */ - /* scaling is done with `units_per_em' then (at this point, */ - /* it already contains the scaling factor, but without */ - /* normalization of the matrix). */ + /* Normalize the font matrix so that `matrix->yy' is 1; if */ + /* it is zero, we use `matrix->yx' instead. The scaling is */ + /* done with `units_per_em' then (at this point, it already */ + /* contains the scaling factor, but without normalization */ + /* of the matrix). */ /* */ /* Note that the offsets must be expressed in integer font */ /* units. */ @@ -646,9 +756,12 @@ FT_Matrix* matrix = &dict->font_matrix; FT_Vector* offset = &dict->font_offset; FT_ULong* upm = &dict->units_per_em; - FT_Fixed temp = FT_ABS( matrix->yy ); + FT_Fixed temp; + temp = matrix->yy ? FT_ABS( matrix->yy ) + : FT_ABS( matrix->yx ); + if ( temp != 0x10000L ) { *upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp ); @@ -716,7 +829,10 @@ matrix = &sub->font_matrix; offset = &sub->font_offset; upm = &sub->units_per_em; - temp = FT_ABS( matrix->yy ); + + temp = matrix->yy ? FT_ABS( matrix->yy ) + : FT_ABS( matrix->yx ); + if ( temp != 0x10000L ) { @@ -968,7 +1084,7 @@ error = FT_Err_Ok; /* if no Unicode charmap was previously selected, select this one */ - if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps ) + if ( !cffface->charmap && nn != (FT_UInt)cffface->num_charmaps ) cffface->charmap = cffface->charmaps[nn]; Skip_Unicode: @@ -1036,6 +1152,11 @@ FT_FREE( face->extra.data ); } } + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + cff_done_blend( face ); + face->blend = NULL; +#endif } @@ -1052,7 +1173,7 @@ driver->hinting_engine = FT_CFF_HINTING_ADOBE; #endif - driver->no_stem_darkening = FALSE; + driver->no_stem_darkening = TRUE; driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; diff --git a/third_party/freetype/src/cff/cffobjs.h b/third_party/freetype/src/cff/cffobjs.h index 3cc953143b..5d26977dc5 100644 --- a/third_party/freetype/src/cff/cffobjs.h +++ b/third_party/freetype/src/cff/cffobjs.h @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFFOBJS_H__ -#define __CFFOBJS_H__ +#ifndef CFFOBJS_H_ +#define CFFOBJS_H_ #include <ft2build.h> @@ -179,7 +179,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFOBJS_H__ */ +#endif /* CFFOBJS_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cffparse.c b/third_party/freetype/src/cff/cffparse.c index 063b3517c5..819332b3e8 100644 --- a/third_party/freetype/src/cff/cffparse.c +++ b/third_party/freetype/src/cff/cffparse.c @@ -4,7 +4,7 @@ /* */ /* CFF token stream parser (body) */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,6 +23,8 @@ #include "cfferrs.h" #include "cffpic.h" +#include "cffgload.h" +#include "cffload.h" /*************************************************************************/ @@ -35,18 +37,52 @@ #define FT_COMPONENT trace_cffparse - FT_LOCAL_DEF( void ) + FT_LOCAL_DEF( FT_Error ) cff_parser_init( CFF_Parser parser, FT_UInt code, void* object, - FT_Library library) + FT_Library library, + FT_UInt stackSize, + FT_UShort num_designs, + FT_UShort num_axes ) { - FT_MEM_ZERO( parser, sizeof ( *parser ) ); + FT_Memory memory = library->memory; /* for FT_NEW_ARRAY */ + FT_Error error; /* for FT_NEW_ARRAY */ + + + FT_ZERO( parser ); +#if 0 parser->top = parser->stack; +#endif parser->object_code = code; parser->object = object; parser->library = library; + parser->num_designs = num_designs; + parser->num_axes = num_axes; + + /* allocate the stack buffer */ + if ( FT_NEW_ARRAY( parser->stack, stackSize ) ) + { + FT_FREE( parser->stack ); + goto Exit; + } + + parser->stackSize = stackSize; + parser->top = parser->stack; /* empty stack */ + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + cff_parser_done( CFF_Parser parser ) + { + FT_Memory memory = parser->library->memory; /* for FT_FREE */ + + + FT_FREE( parser->stack ); } @@ -397,24 +433,54 @@ /* read a number, either integer or real */ - static FT_Long - cff_parse_num( FT_Byte** d ) + FT_LOCAL_DEF( FT_Long ) + cff_parse_num( CFF_Parser parser, + FT_Byte** d ) { - return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 ) - : cff_parse_integer( d[0], d[1] ); + if ( **d == 30 ) + { + /* binary-coded decimal is truncated to integer */ + return cff_parse_real( *d, parser->limit, 0, NULL ) >> 16; + } + + else if ( **d == 255 ) + { + /* 16.16 fixed point is used internally for CFF2 blend results. */ + /* Since these are trusted values, a limit check is not needed. */ + + /* After the 255, 4 bytes give the number. */ + /* The blend value is converted to integer, with rounding; */ + /* due to the right-shift we don't need the lowest byte. */ +#if 0 + return (FT_Short)( + ( ( ( (FT_UInt32)*( d[0] + 1 ) << 24 ) | + ( (FT_UInt32)*( d[0] + 2 ) << 16 ) | + ( (FT_UInt32)*( d[0] + 3 ) << 8 ) | + (FT_UInt32)*( d[0] + 4 ) ) + 0x8000U ) >> 16 ); +#else + return (FT_Short)( + ( ( ( (FT_UInt32)*( d[0] + 1 ) << 16 ) | + ( (FT_UInt32)*( d[0] + 2 ) << 8 ) | + (FT_UInt32)*( d[0] + 3 ) ) + 0x80U ) >> 8 ); +#endif + } + + else + return cff_parse_integer( *d, parser->limit ); } /* read a floating point number, either integer or real */ static FT_Fixed - do_fixed( FT_Byte** d, - FT_Long scaling ) + do_fixed( CFF_Parser parser, + FT_Byte** d, + FT_Long scaling ) { if ( **d == 30 ) - return cff_parse_real( d[0], d[1], scaling, NULL ); + return cff_parse_real( *d, parser->limit, scaling, NULL ); else { - FT_Long val = cff_parse_integer( d[0], d[1] ); + FT_Long val = cff_parse_integer( *d, parser->limit ); if ( scaling ) @@ -442,19 +508,21 @@ /* read a floating point number, either integer or real */ static FT_Fixed - cff_parse_fixed( FT_Byte** d ) + cff_parse_fixed( CFF_Parser parser, + FT_Byte** d ) { - return do_fixed( d, 0 ); + return do_fixed( parser, d, 0 ); } /* read a floating point number, either integer or real, */ /* but return `10^scaling' times the number read in */ static FT_Fixed - cff_parse_fixed_scaled( FT_Byte** d, - FT_Long scaling ) + cff_parse_fixed_scaled( CFF_Parser parser, + FT_Byte** d, + FT_Long scaling ) { - return do_fixed( d, scaling ); + return do_fixed( parser, d, scaling ); } @@ -462,13 +530,14 @@ /* and return it as precise as possible -- `scaling' returns */ /* the scaling factor (as a power of 10) */ static FT_Fixed - cff_parse_fixed_dynamic( FT_Byte** d, - FT_Long* scaling ) + cff_parse_fixed_dynamic( CFF_Parser parser, + FT_Byte** d, + FT_Long* scaling ) { FT_ASSERT( scaling ); if ( **d == 30 ) - return cff_parse_real( d[0], d[1], 0, scaling ); + return cff_parse_real( *d, parser->limit, 0, scaling ); else { FT_Long number; @@ -516,7 +585,11 @@ if ( parser->top >= parser->stack + 6 ) { - FT_Long scaling; + FT_Fixed values[6]; + FT_Long scalings[6]; + + FT_Long min_scaling, max_scaling; + int i; error = FT_Err_Ok; @@ -525,22 +598,36 @@ /* We expect a well-formed font matrix, this is, the matrix elements */ /* `xx' and `yy' are of approximately the same magnitude. To avoid */ - /* loss of precision, we use the magnitude of element `xx' to scale */ - /* all other elements. The scaling factor is then contained in the */ - /* `units_per_em' value. */ + /* loss of precision, we use the magnitude of the largest matrix */ + /* element to scale all other elements. The scaling factor is then */ + /* contained in the `units_per_em' value. */ - matrix->xx = cff_parse_fixed_dynamic( data++, &scaling ); + max_scaling = FT_LONG_MIN; + min_scaling = FT_LONG_MAX; - scaling = -scaling; + for ( i = 0; i < 6; i++ ) + { + values[i] = cff_parse_fixed_dynamic( parser, data++, &scalings[i] ); + if ( values[i] ) + { + if ( scalings[i] > max_scaling ) + max_scaling = scalings[i]; + if ( scalings[i] < min_scaling ) + min_scaling = scalings[i]; + } + } - if ( scaling < 0 || scaling > 9 ) + if ( max_scaling < -9 || + max_scaling > 0 || + ( max_scaling - min_scaling ) < 0 || + ( max_scaling - min_scaling ) > 9 ) { /* Return default matrix in case of unlikely values. */ FT_TRACE1(( "cff_parse_font_matrix:" - " strange scaling value for xx element (%d),\n" + " strange scaling values (minimum %d, maximum %d),\n" " " - " using default matrix\n", scaling )); + " using default matrix\n", min_scaling, max_scaling )); matrix->xx = 0x10000L; matrix->yx = 0; @@ -553,13 +640,42 @@ goto Exit; } - matrix->yx = cff_parse_fixed_scaled( data++, scaling ); - matrix->xy = cff_parse_fixed_scaled( data++, scaling ); - matrix->yy = cff_parse_fixed_scaled( data++, scaling ); - offset->x = cff_parse_fixed_scaled( data++, scaling ); - offset->y = cff_parse_fixed_scaled( data, scaling ); + for ( i = 0; i < 6; i++ ) + { + FT_Fixed value = values[i]; + FT_Long divisor, half_divisor; + + + if ( !value ) + continue; - *upm = (FT_ULong)power_tens[scaling]; + divisor = power_tens[max_scaling - scalings[i]]; + half_divisor = divisor >> 1; + + if ( value < 0 ) + { + if ( FT_LONG_MIN + half_divisor < value ) + values[i] = ( value - half_divisor ) / divisor; + else + values[i] = FT_LONG_MIN / divisor; + } + else + { + if ( FT_LONG_MAX - half_divisor > value ) + values[i] = ( value + half_divisor ) / divisor; + else + values[i] = FT_LONG_MAX / divisor; + } + } + + matrix->xx = values[0]; + matrix->yx = values[1]; + matrix->xy = values[2]; + matrix->yy = values[3]; + offset->x = values[4]; + offset->y = values[5]; + + *upm = (FT_ULong)power_tens[-max_scaling]; FT_TRACE4(( " [%f %f %f %f %f %f]\n", (double)matrix->xx / *upm / 65536, @@ -588,10 +704,10 @@ if ( parser->top >= parser->stack + 4 ) { - bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) ); - bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) ); - bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) ); - bbox->yMax = FT_RoundFix( cff_parse_fixed( data ) ); + bbox->xMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) ); + bbox->yMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) ); + bbox->xMax = FT_RoundFix( cff_parse_fixed( parser, data++ ) ); + bbox->yMax = FT_RoundFix( cff_parse_fixed( parser, data ) ); error = FT_Err_Ok; FT_TRACE4(( " [%d %d %d %d]\n", @@ -620,7 +736,7 @@ FT_Long tmp; - tmp = cff_parse_num( data++ ); + tmp = cff_parse_num( parser, data++ ); if ( tmp < 0 ) { FT_ERROR(( "cff_parse_private_dict: Invalid dictionary size\n" )); @@ -629,7 +745,7 @@ } dict->private_size = (FT_ULong)tmp; - tmp = cff_parse_num( data ); + tmp = cff_parse_num( parser, data ); if ( tmp < 0 ) { FT_ERROR(( "cff_parse_private_dict: Invalid dictionary offset\n" )); @@ -649,6 +765,56 @@ } + /* The `MultipleMaster' operator comes before any */ + /* top DICT operators that contain T2 charstrings. */ + + static FT_Error + cff_parse_multiple_master( CFF_Parser parser ) + { + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_Error error; + + +#ifdef FT_DEBUG_LEVEL_TRACE + /* beautify tracing message */ + if ( ft_trace_levels[FT_COMPONENT] < 4 ) + FT_TRACE1(( "Multiple Master CFFs not supported yet," + " handling first master design only\n" )); + else + FT_TRACE1(( " (not supported yet," + " handling first master design only)\n" )); +#endif + + error = FT_ERR( Stack_Underflow ); + + /* currently, we handle only the first argument */ + if ( parser->top >= parser->stack + 5 ) + { + FT_Long num_designs = cff_parse_num( parser, parser->stack ); + + + if ( num_designs > 16 || num_designs < 2 ) + { + FT_ERROR(( "cff_parse_multiple_master:" + " Invalid number of designs\n" )); + error = FT_THROW( Invalid_File_Format ); + } + else + { + dict->num_designs = (FT_UShort)num_designs; + dict->num_axes = (FT_UShort)( parser->top - parser->stack - 4 ); + + parser->num_designs = dict->num_designs; + parser->num_axes = dict->num_axes; + + error = FT_Err_Ok; + } + } + + return error; + } + + static FT_Error cff_parse_cid_ros( CFF_Parser parser ) { @@ -661,11 +827,11 @@ if ( parser->top >= parser->stack + 3 ) { - dict->cid_registry = (FT_UInt)cff_parse_num( data++ ); - dict->cid_ordering = (FT_UInt)cff_parse_num( data++ ); + dict->cid_registry = (FT_UInt)cff_parse_num( parser, data++ ); + dict->cid_ordering = (FT_UInt)cff_parse_num( parser, data++ ); if ( **data == 30 ) FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" )); - dict->cid_supplement = cff_parse_num( data ); + dict->cid_supplement = cff_parse_num( parser, data ); if ( dict->cid_supplement < 0 ) FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n", dict->cid_supplement )); @@ -681,6 +847,125 @@ } + static FT_Error + cff_parse_vsindex( CFF_Parser parser ) + { + /* vsindex operator can only be used in a Private DICT */ + CFF_Private priv = (CFF_Private)parser->object; + FT_Byte** data = parser->stack; + CFF_Blend blend; + FT_Error error; + + + if ( !priv || !priv->subfont ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + blend = &priv->subfont->blend; + + if ( blend->usedBV ) + { + FT_ERROR(( " cff_parse_vsindex: vsindex not allowed after blend\n" )); + error = FT_THROW( Syntax_Error ); + goto Exit; + } + + priv->vsindex = (FT_UInt)cff_parse_num( parser, data++ ); + + FT_TRACE4(( " %d\n", priv->vsindex )); + + error = FT_Err_Ok; + + Exit: + return error; + } + + + static FT_Error + cff_parse_blend( CFF_Parser parser ) + { + /* blend operator can only be used in a Private DICT */ + CFF_Private priv = (CFF_Private)parser->object; + CFF_SubFont subFont; + CFF_Blend blend; + FT_UInt numBlends; + FT_Error error; + + + error = FT_ERR( Stack_Underflow ); + + if ( !priv || !priv->subfont ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + subFont = priv->subfont; + blend = &subFont->blend; + + if ( cff_blend_check_vector( blend, + priv->vsindex, + subFont->lenNDV, + subFont->NDV ) ) + { + error = cff_blend_build_vector( blend, + priv->vsindex, + subFont->lenNDV, + subFont->NDV ); + if ( error ) + goto Exit; + } + + numBlends = (FT_UInt)cff_parse_num( parser, parser->top - 1 ); + if ( numBlends > parser->stackSize ) + { + FT_ERROR(( "cff_parse_blend: Invalid number of blends\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + FT_TRACE4(( " %d values blended\n", numBlends )); + + error = cff_blend_doBlend( subFont, parser, numBlends ); + + blend->usedBV = TRUE; + + Exit: + return error; + } + + + /* maxstack operator increases parser and operand stacks for CFF2 */ + static FT_Error + cff_parse_maxstack( CFF_Parser parser ) + { + /* maxstack operator can only be used in a Top DICT */ + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_Byte** data = parser->stack; + FT_Error error = FT_Err_Ok; + + + if ( !dict ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + dict->maxstack = (FT_UInt)cff_parse_num( parser, data++ ); + if ( dict->maxstack > CFF2_MAX_STACK ) + dict->maxstack = CFF2_MAX_STACK; + if ( dict->maxstack < CFF2_DEFAULT_STACK ) + dict->maxstack = CFF2_DEFAULT_STACK; + + FT_TRACE4(( " %d\n", dict->maxstack )); + + Exit: + return error; + } + + #define CFF_FIELD_NUM( code, name, id ) \ CFF_FIELD( code, name, id, cff_kind_num ) #define CFF_FIELD_FIXED( code, name, id ) \ @@ -692,9 +977,6 @@ #define CFF_FIELD_BOOL( code, name, id ) \ CFF_FIELD( code, name, id, cff_kind_bool ) -#define CFFCODE_TOPDICT 0x1000 -#define CFFCODE_PRIVATE 0x2000 - #ifndef FT_CONFIG_OPTION_PIC @@ -715,6 +997,15 @@ 0, 0 \ }, +#define CFF_FIELD_BLEND( code, id ) \ + { \ + cff_kind_blend, \ + code | CFFCODE, \ + 0, 0, \ + cff_parse_blend, \ + 0, 0 \ + }, + #define CFF_FIELD( code, name, id, kind ) \ { \ kind, \ @@ -758,6 +1049,16 @@ id \ }, +#define CFF_FIELD_BLEND( code, id ) \ + { \ + cff_kind_blend, \ + code | CFFCODE, \ + 0, 0, \ + cff_parse_blend, \ + 0, 0, \ + id \ + }, + #define CFF_FIELD( code, name, id, kind ) \ { \ kind, \ @@ -965,14 +1266,16 @@ { FT_UInt v = *p; - - if ( v >= 27 && v != 31 ) + /* Opcode 31 is legacy MM T2 operator, not a number. */ + /* Opcode 255 is reserved and should not appear in fonts; */ + /* it is used internally for CFF2 blends. */ + if ( v >= 27 && v != 31 && v != 255 ) { /* it's a number; we will push its position on the stack */ - if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH ) + if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize ) goto Stack_Overflow; - *parser->top ++ = p; + *parser->top++ = p; /* now, skip it */ if ( v == 30 ) @@ -1001,19 +1304,153 @@ else if ( v > 246 ) p += 1; } +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + else if ( v == 31 ) + { + /* a Type 2 charstring */ + + CFF_Decoder decoder; + CFF_FontRec cff_rec; + FT_Byte* charstring_base; + FT_ULong charstring_len; + + FT_Fixed* stack; + FT_Byte* q; + + + charstring_base = ++p; + + /* search `endchar' operator */ + for (;;) + { + if ( p >= limit ) + goto Exit; + if ( *p == 14 ) + break; + p++; + } + + charstring_len = (FT_ULong)( p - charstring_base ) + 1; + + /* construct CFF_Decoder object */ + FT_ZERO( &decoder ); + FT_ZERO( &cff_rec ); + + cff_rec.top_font.font_dict.num_designs = parser->num_designs; + cff_rec.top_font.font_dict.num_axes = parser->num_axes; + decoder.cff = &cff_rec; + + error = cff_decoder_parse_charstrings( &decoder, + charstring_base, + charstring_len, + 1 ); + + /* Now copy the stack data in the temporary decoder object, */ + /* converting it back to charstring number representations */ + /* (this is ugly, I know). */ + /* */ + /* We overwrite the original top DICT charstring under the */ + /* assumption that the charstring representation of the result */ + /* of `cff_decoder_parse_charstrings' is shorter, which should */ + /* be always true. */ + + q = charstring_base - 1; + stack = decoder.stack; + + while ( stack < decoder.top ) + { + FT_ULong num; + FT_Bool neg; + + + if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize ) + goto Stack_Overflow; + + *parser->top++ = q; + + if ( *stack < 0 ) + { + num = (FT_ULong)-*stack; + neg = 1; + } + else + { + num = (FT_ULong)*stack; + neg = 0; + } + + if ( num & 0xFFFFU ) + { + if ( neg ) + num = (FT_ULong)-num; + + *q++ = 255; + *q++ = ( num & 0xFF000000U ) >> 24; + *q++ = ( num & 0x00FF0000U ) >> 16; + *q++ = ( num & 0x0000FF00U ) >> 8; + *q++ = num & 0x000000FFU; + } + else + { + num >>= 16; + + if ( neg ) + { + if ( num <= 107 ) + *q++ = (FT_Byte)( 139 - num ); + else if ( num <= 1131 ) + { + *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 251 ); + *q++ = (FT_Byte)( ( num - 108 ) & 0xFF ); + } + else + { + num = (FT_ULong)-num; + + *q++ = 28; + *q++ = (FT_Byte)( num >> 8 ); + *q++ = (FT_Byte)( num & 0xFF ); + } + } + else + { + if ( num <= 107 ) + *q++ = (FT_Byte)( num + 139 ); + else if ( num <= 1131 ) + { + *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 ); + *q++ = (FT_Byte)( ( num - 108 ) & 0xFF ); + } + else + { + *q++ = 28; + *q++ = (FT_Byte)( num >> 8 ); + *q++ = (FT_Byte)( num & 0xFF ); + } + } + } + + stack++; + } + } +#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ else { /* This is not a number, hence it's an operator. Compute its code */ /* and look for it in our current list. */ FT_UInt code; - FT_UInt num_args = (FT_UInt) - ( parser->top - parser->stack ); + FT_UInt num_args; const CFF_Field_Handler* field; + if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize ) + goto Stack_Overflow; + + num_args = (FT_UInt)( parser->top - parser->stack ); *parser->top = p; - code = v; + code = v; + if ( v == 12 ) { /* two byte operator */ @@ -1048,15 +1485,15 @@ case cff_kind_bool: case cff_kind_string: case cff_kind_num: - val = cff_parse_num( parser->stack ); + val = cff_parse_num( parser, parser->stack ); goto Store_Number; case cff_kind_fixed: - val = cff_parse_fixed( parser->stack ); + val = cff_parse_fixed( parser, parser->stack ); goto Store_Number; case cff_kind_fixed_thousand: - val = cff_parse_fixed_scaled( parser->stack, 3 ); + val = cff_parse_fixed_scaled( parser, parser->stack, 3 ); Store_Number: switch ( field->size ) @@ -1125,7 +1562,7 @@ val = 0; while ( num_args > 0 ) { - val += cff_parse_num( data++ ); + val += cff_parse_num( parser, data++ ); switch ( field->size ) { case (8 / FT_CHAR_BIT): @@ -1154,7 +1591,7 @@ } break; - default: /* callback */ + default: /* callback or blend */ error = field->reader( parser ); if ( error ) goto Exit; @@ -1168,7 +1605,10 @@ Found: /* clear stack */ - parser->top = parser->stack; + /* TODO: could clear blend stack here, */ + /* but we don't have access to subFont */ + if ( field->kind != cff_kind_blend ) + parser->top = parser->stack; } p++; } diff --git a/third_party/freetype/src/cff/cffparse.h b/third_party/freetype/src/cff/cffparse.h index 8ad02ea1e2..9976d42b18 100644 --- a/third_party/freetype/src/cff/cffparse.h +++ b/third_party/freetype/src/cff/cffparse.h @@ -4,7 +4,7 @@ /* */ /* CFF token stream parser (specification) */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFF_PARSE_H__ -#define __CFF_PARSE_H__ +#ifndef CFFPARSE_H_ +#define CFFPARSE_H_ #include <ft2build.h> @@ -28,33 +28,54 @@ FT_BEGIN_HEADER + /* CFF uses constant parser stack size; */ + /* CFF2 can increase from default 193 */ #define CFF_MAX_STACK_DEPTH 96 +#define CFF2_MAX_STACK 513 +#define CFF2_DEFAULT_STACK 193 -#define CFF_CODE_TOPDICT 0x1000 -#define CFF_CODE_PRIVATE 0x2000 +#define CFF_CODE_TOPDICT 0x1000 +#define CFF_CODE_PRIVATE 0x2000 +#define CFF2_CODE_TOPDICT 0x3000 +#define CFF2_CODE_FONTDICT 0x4000 +#define CFF2_CODE_PRIVATE 0x5000 typedef struct CFF_ParserRec_ { - FT_Library library; - FT_Byte* start; - FT_Byte* limit; - FT_Byte* cursor; + FT_Library library; + FT_Byte* start; + FT_Byte* limit; + FT_Byte* cursor; - FT_Byte* stack[CFF_MAX_STACK_DEPTH + 1]; - FT_Byte** top; + FT_Byte** stack; + FT_Byte** top; + FT_UInt stackSize; /* allocated size */ - FT_UInt object_code; - void* object; + FT_UInt object_code; + void* object; + + FT_UShort num_designs; /* a copy of `CFF_FontRecDict->num_designs' */ + FT_UShort num_axes; /* a copy of `CFF_FontRecDict->num_axes' */ } CFF_ParserRec, *CFF_Parser; - FT_LOCAL( void ) + FT_LOCAL( FT_Long ) + cff_parse_num( CFF_Parser parser, + FT_Byte** d ); + + FT_LOCAL( FT_Error ) cff_parser_init( CFF_Parser parser, FT_UInt code, void* object, - FT_Library library); + FT_Library library, + FT_UInt stackSize, + FT_UShort num_designs, + FT_UShort num_axes ); + + FT_LOCAL( void ) + cff_parser_done( CFF_Parser parser ); FT_LOCAL( FT_Error ) cff_parser_run( CFF_Parser parser, @@ -72,6 +93,7 @@ FT_BEGIN_HEADER cff_kind_bool, cff_kind_delta, cff_kind_callback, + cff_kind_blend, cff_kind_max /* do not remove */ }; @@ -100,7 +122,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFF_PARSE_H__ */ +#endif /* CFFPARSE_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cffpic.c b/third_party/freetype/src/cff/cffpic.c index d40dec50e9..4e9ba12b3f 100644 --- a/third_party/freetype/src/cff/cffpic.c +++ b/third_party/freetype/src/cff/cffpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for cff module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/cff/cffpic.h b/third_party/freetype/src/cff/cffpic.h index 9a221a7b7e..0b89fcb5e5 100644 --- a/third_party/freetype/src/cff/cffpic.h +++ b/third_party/freetype/src/cff/cffpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for cff module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFFPIC_H__ -#define __CFFPIC_H__ +#ifndef CFFPIC_H_ +#define CFFPIC_H_ #include FT_INTERNAL_PIC_H @@ -32,6 +32,7 @@ #define CFF_SERVICE_CID_INFO_GET cff_service_cid_info #define CFF_SERVICE_PROPERTIES_GET cff_service_properties #define CFF_SERVICES_GET cff_services +#define CFF_SERVICE_MULTI_MASTERS_GET cff_service_multi_masters #define CFF_CMAP_ENCODING_CLASS_REC_GET cff_cmap_encoding_class_rec #define CFF_CMAP_UNICODE_CLASS_REC_GET cff_cmap_unicode_class_rec #define CFF_FIELD_HANDLERS_GET cff_field_handlers @@ -102,7 +103,7 @@ FT_END_HEADER /* */ -#endif /* __CFFPIC_H__ */ +#endif /* CFFPIC_H_ */ /* END */ diff --git a/third_party/freetype/src/cff/cfftoken.h b/third_party/freetype/src/cff/cfftoken.h index 5b32076ab8..3222e933f1 100644 --- a/third_party/freetype/src/cff/cfftoken.h +++ b/third_party/freetype/src/cff/cfftoken.h @@ -4,7 +4,7 @@ /* */ /* CFF token definitions (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,7 +20,7 @@ #define FT_STRUCTURE CFF_FontRecDictRec #undef CFFCODE -#define CFFCODE CFFCODE_TOPDICT +#define CFFCODE CFF_CODE_TOPDICT CFF_FIELD_STRING ( 0, version, "Version" ) CFF_FIELD_STRING ( 1, notice, "Notice" ) @@ -38,6 +38,9 @@ CFF_FIELD_NUM ( 13, unique_id, "UniqueID" ) CFF_FIELD_CALLBACK( 5, font_bbox, "FontBBox" ) CFF_FIELD_NUM ( 0x108, stroke_width, "StrokeWidth" ) +#if 0 + CFF_FIELD_DELTA ( 14, xuid, 16, "XUID" ) +#endif CFF_FIELD_NUM ( 15, charset_offset, "charset" ) CFF_FIELD_NUM ( 16, encoding_offset, "Encoding" ) CFF_FIELD_NUM ( 17, charstrings_offset, "CharStrings" ) @@ -48,8 +51,13 @@ #if 0 CFF_FIELD_STRING ( 0x116, base_font_name, "BaseFontName" ) CFF_FIELD_DELTA ( 0x117, base_font_blend, 16, "BaseFontBlend" ) +#endif + + /* the next two operators were removed from the Type2 specification */ + /* in version 16-March-2000 */ CFF_FIELD_CALLBACK( 0x118, multiple_master, "MultipleMaster" ) - CFF_FIELD_CALLBACK( 0x119, blend_axis_types, "BlendAxisTypes" ) +#if 0 + CFF_FIELD_CALLBACK( 0x11A, blend_axis_types, "BlendAxisTypes" ) #endif CFF_FIELD_CALLBACK( 0x11E, cid_ros, "ROS" ) @@ -70,7 +78,7 @@ #undef FT_STRUCTURE #define FT_STRUCTURE CFF_PrivateRec #undef CFFCODE -#define CFFCODE CFFCODE_PRIVATE +#define CFFCODE CFF_CODE_PRIVATE CFF_FIELD_DELTA ( 6, blue_values, 14, "BlueValues" ) CFF_FIELD_DELTA ( 7, other_blues, 10, "OtherBlues" ) @@ -94,4 +102,49 @@ CFF_FIELD_NUM ( 21, nominal_width, "nominalWidthX" ) +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_FontRecDictRec +#undef CFFCODE +#define CFFCODE CFF2_CODE_TOPDICT + + CFF_FIELD_CALLBACK( 0x107, font_matrix, "FontMatrix" ) + CFF_FIELD_NUM ( 17, charstrings_offset, "CharStrings" ) + CFF_FIELD_NUM ( 0x124, cid_fd_array_offset, "FDArray" ) + CFF_FIELD_NUM ( 0x125, cid_fd_select_offset, "FDSelect" ) + CFF_FIELD_NUM ( 24, vstore_offset, "vstore" ) + CFF_FIELD_CALLBACK( 25, maxstack, "maxstack" ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_FontRecDictRec +#undef CFFCODE +#define CFFCODE CFF2_CODE_FONTDICT + + CFF_FIELD_CALLBACK( 18, private_dict, "Private" ) + CFF_FIELD_CALLBACK( 0x107, font_matrix, "FontMatrix" ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_PrivateRec +#undef CFFCODE +#define CFFCODE CFF2_CODE_PRIVATE + + CFF_FIELD_DELTA ( 6, blue_values, 14, "BlueValues" ) + CFF_FIELD_DELTA ( 7, other_blues, 10, "OtherBlues" ) + CFF_FIELD_DELTA ( 8, family_blues, 14, "FamilyBlues" ) + CFF_FIELD_DELTA ( 9, family_other_blues, 10, "FamilyOtherBlues" ) + CFF_FIELD_FIXED_1000( 0x109, blue_scale, "BlueScale" ) + CFF_FIELD_NUM ( 0x10A, blue_shift, "BlueShift" ) + CFF_FIELD_NUM ( 0x10B, blue_fuzz, "BlueFuzz" ) + CFF_FIELD_NUM ( 10, standard_width, "StdHW" ) + CFF_FIELD_NUM ( 11, standard_height, "StdVW" ) + CFF_FIELD_DELTA ( 0x10C, snap_widths, 13, "StemSnapH" ) + CFF_FIELD_DELTA ( 0x10D, snap_heights, 13, "StemSnapV" ) + CFF_FIELD_NUM ( 0x111, language_group, "LanguageGroup" ) + CFF_FIELD_FIXED ( 0x112, expansion_factor, "ExpansionFactor" ) + CFF_FIELD_CALLBACK ( 22, vsindex, "vsindex" ) + CFF_FIELD_BLEND ( 23, "blend" ) + CFF_FIELD_NUM ( 19, local_subrs_offset, "Subrs" ) + + /* END */ diff --git a/third_party/freetype/src/cff/cfftypes.h b/third_party/freetype/src/cff/cfftypes.h index de8a5ee9b4..412712c86c 100644 --- a/third_party/freetype/src/cff/cfftypes.h +++ b/third_party/freetype/src/cff/cfftypes.h @@ -5,7 +5,7 @@ /* Basic OpenType/CFF type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __CFFTYPES_H__ -#define __CFFTYPES_H__ +#ifndef CFFTYPES_H_ +#define CFFTYPES_H_ #include <ft2build.h> @@ -64,6 +64,7 @@ FT_BEGIN_HEADER { FT_Stream stream; FT_ULong start; + FT_UInt hdr_size; FT_UInt count; FT_Byte off_size; FT_ULong data_offset; @@ -102,6 +103,79 @@ FT_BEGIN_HEADER } CFF_CharsetRec, *CFF_Charset; + /* cf. similar fields in file `ttgxvar.h' from the `truetype' module */ + + typedef struct CFF_VarData_ + { +#if 0 + FT_UInt itemCount; /* not used; always zero */ + FT_UInt shortDeltaCount; /* not used; always zero */ +#endif + + FT_UInt regionIdxCount; /* number of regions in this var data */ + FT_UInt* regionIndices; /* array of `regionCount' indices; */ + /* these index `varRegionList' */ + } CFF_VarData; + + + /* contribution of one axis to a region */ + typedef struct CFF_AxisCoords_ + { + FT_Fixed startCoord; + FT_Fixed peakCoord; /* zero peak means no effect (factor = 1) */ + FT_Fixed endCoord; + + } CFF_AxisCoords; + + + typedef struct CFF_VarRegion_ + { + CFF_AxisCoords* axisList; /* array of axisCount records */ + + } CFF_VarRegion; + + + typedef struct CFF_VStoreRec_ + { + FT_UInt dataCount; + CFF_VarData* varData; /* array of dataCount records */ + /* vsindex indexes this array */ + FT_UShort axisCount; + FT_UInt regionCount; /* total number of regions defined */ + CFF_VarRegion* varRegionList; + + } CFF_VStoreRec, *CFF_VStore; + + + /* forward reference */ + typedef struct CFF_FontRec_* CFF_Font; + + + /* This object manages one cached blend vector. */ + /* */ + /* There is a BlendRec for Private DICT parsing in each subfont */ + /* and a BlendRec for charstrings in CF2_Font instance data. */ + /* A cached BV may be used across DICTs or Charstrings if inputs */ + /* have not changed. */ + /* */ + /* `usedBV' is reset at the start of each parse or charstring. */ + /* vsindex cannot be changed after a BV is used. */ + /* */ + /* Note: NDV is long (32/64 bit), while BV is 16.16 (FT_Int32). */ + typedef struct CFF_BlendRec_ + { + FT_Bool builtBV; /* blendV has been built */ + FT_Bool usedBV; /* blendV has been used */ + CFF_Font font; /* top level font struct */ + FT_UInt lastVsindex; /* last vsindex used */ + FT_UInt lenNDV; /* normDV length (aka numAxes) */ + FT_Fixed* lastNDV; /* last NDV used */ + FT_UInt lenBV; /* BlendV length (aka numMasters) */ + FT_Int32* BV; /* current blendV (per DICT/glyph) */ + + } CFF_BlendRec, *CFF_Blend; + + typedef struct CFF_FontRecDictRec_ { FT_UInt version; @@ -145,9 +219,23 @@ FT_BEGIN_HEADER FT_ULong cid_fd_select_offset; FT_UInt cid_font_name; + /* the next fields come from the data of the deprecated */ + /* `MultipleMaster' operator; they are needed to parse the (also */ + /* deprecated) `blend' operator in Type 2 charstrings */ + FT_UShort num_designs; + FT_UShort num_axes; + + /* fields for CFF2 */ + FT_ULong vstore_offset; + FT_UInt maxstack; + } CFF_FontRecDictRec, *CFF_FontRecDict; + /* forward reference */ + typedef struct CFF_SubFontRec_* CFF_SubFont; + + typedef struct CFF_PrivateRec_ { FT_Byte num_blue_values; @@ -180,6 +268,10 @@ FT_BEGIN_HEADER FT_Pos default_width; FT_Pos nominal_width; + /* fields for CFF2 */ + FT_UInt vsindex; + CFF_SubFont subfont; + } CFF_PrivateRec, *CFF_Private; @@ -207,10 +299,29 @@ FT_BEGIN_HEADER CFF_FontRecDictRec font_dict; CFF_PrivateRec private_dict; - CFF_IndexRec local_subrs_index; - FT_Byte** local_subrs; /* array of pointers into Local Subrs INDEX data */ + /* fields for CFF2 */ + CFF_BlendRec blend; /* current blend vector */ + FT_UInt lenNDV; /* current length NDV or zero */ + FT_Fixed* NDV; /* ptr to current NDV or NULL */ + + /* `blend_stack' is a writable buffer to hold blend results. */ + /* This buffer is to the side of the normal cff parser stack; */ + /* `cff_parse_blend' and `cff_blend_doBlend' push blend results here. */ + /* The normal stack then points to these values instead of the DICT */ + /* because all other operators in Private DICT clear the stack. */ + /* `blend_stack' could be cleared at each operator other than blend. */ + /* Blended values are stored as 5-byte fixed point values. */ + + FT_Byte* blend_stack; /* base of stack allocation */ + FT_Byte* blend_top; /* first empty slot */ + FT_UInt blend_used; /* number of bytes in use */ + FT_UInt blend_alloc; /* number of bytes allocated */ - } CFF_SubFontRec, *CFF_SubFont; + CFF_IndexRec local_subrs_index; + FT_Byte** local_subrs; /* array of pointers */ + /* into Local Subrs INDEX data */ + + } CFF_SubFontRec; #define CFF_MAX_CID_FONTS 256 @@ -218,16 +329,20 @@ FT_BEGIN_HEADER typedef struct CFF_FontRec_ { + FT_Library library; FT_Stream stream; - FT_Memory memory; + FT_Memory memory; /* TODO: take this from stream->memory? */ + FT_ULong base_offset; /* offset to start of CFF */ FT_UInt num_faces; FT_UInt num_glyphs; FT_Byte version_major; FT_Byte version_minor; FT_Byte header_size; - FT_Byte absolute_offsize; + FT_UInt top_dict_length; /* cff2 only */ + + FT_Bool cff2; CFF_IndexRec name_index; CFF_IndexRec top_dict_index; @@ -250,6 +365,7 @@ FT_BEGIN_HEADER FT_UInt num_strings; FT_Byte** strings; FT_Byte* string_pool; + FT_ULong string_pool_size; CFF_SubFontRec top_font; FT_UInt num_subfonts; @@ -273,12 +389,14 @@ FT_BEGIN_HEADER /* since version 2.4.12 */ FT_Generic cf2_instance; - } CFF_FontRec, *CFF_Font; + CFF_VStoreRec vstore; /* parsed vstore structure */ + + } CFF_FontRec; FT_END_HEADER -#endif /* __CFFTYPES_H__ */ +#endif /* CFFTYPES_H_ */ /* END */ diff --git a/third_party/freetype/src/cid/ciderrs.h b/third_party/freetype/src/cid/ciderrs.h index 5e0e776ee1..709dc8cd1e 100644 --- a/third_party/freetype/src/cid/ciderrs.h +++ b/third_party/freetype/src/cid/ciderrs.h @@ -4,7 +4,7 @@ /* */ /* CID error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __CIDERRS_H__ -#define __CIDERRS_H__ +#ifndef CIDERRS_H_ +#define CIDERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX CID_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __CIDERRS_H__ */ +#endif /* CIDERRS_H_ */ /* END */ diff --git a/third_party/freetype/src/cid/cidgload.c b/third_party/freetype/src/cid/cidgload.c index d00674fe0d..b96c33334d 100644 --- a/third_party/freetype/src/cid/cidgload.c +++ b/third_party/freetype/src/cid/cidgload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -100,7 +100,7 @@ /* and charstring offset from the CIDMap. */ { FT_UInt entry_len = (FT_UInt)( cid->fd_bytes + cid->gd_bytes ); - FT_ULong off1; + FT_ULong off1, off2; if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset + @@ -108,18 +108,23 @@ FT_FRAME_ENTER( 2 * entry_len ) ) goto Exit; - p = (FT_Byte*)stream->cursor; - fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); - off1 = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); - p += cid->fd_bytes; - glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1; + p = (FT_Byte*)stream->cursor; + fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); + off1 = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); + p += cid->fd_bytes; + off2 = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); FT_FRAME_EXIT(); - if ( fd_select >= (FT_ULong)cid->num_dicts ) + if ( fd_select >= (FT_ULong)cid->num_dicts || + off2 > stream->size || + off1 > off2 ) { + FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" )); error = FT_THROW( Invalid_Offset ); goto Exit; } + + glyph_length = off2 - off1; if ( glyph_length == 0 ) goto Exit; if ( FT_ALLOC( charstring, glyph_length ) ) @@ -137,9 +142,10 @@ /* Set up subrs */ - decoder->num_subrs = cid_subrs->num_subrs; - decoder->subrs = cid_subrs->code; - decoder->subrs_len = 0; + decoder->num_subrs = cid_subrs->num_subrs; + decoder->subrs = cid_subrs->code; + decoder->subrs_len = 0; + decoder->subrs_hash = NULL; /* Set up font matrix */ dict = cid->font_dicts + fd_select; @@ -152,6 +158,12 @@ /* Adjustment for seed bytes. */ cs_offset = decoder->lenIV >= 0 ? (FT_UInt)decoder->lenIV : 0; + if ( cs_offset > glyph_length ) + { + FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" )); + error = FT_THROW( Invalid_Offset ); + goto Exit; + } /* Decrypt only if lenIV >= 0. */ if ( decoder->lenIV >= 0 ) @@ -162,8 +174,6 @@ glyph_length - cs_offset ); } - FT_FREE( charstring ); - #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts can optionally override the metrics. */ @@ -188,6 +198,8 @@ #endif /* FT_CONFIG_OPTION_INCREMENTAL */ Exit: + FT_FREE( charstring ); + return error; } diff --git a/third_party/freetype/src/cid/cidgload.h b/third_party/freetype/src/cid/cidgload.h index 4a10ce505c..7f816b5bc7 100644 --- a/third_party/freetype/src/cid/cidgload.h +++ b/third_party/freetype/src/cid/cidgload.h @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDGLOAD_H__ -#define __CIDGLOAD_H__ +#ifndef CIDGLOAD_H_ +#define CIDGLOAD_H_ #include <ft2build.h> @@ -45,7 +45,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDGLOAD_H__ */ +#endif /* CIDGLOAD_H_ */ /* END */ diff --git a/third_party/freetype/src/cid/cidload.c b/third_party/freetype/src/cid/cidload.c index e23b82f673..ff0722110d 100644 --- a/third_party/freetype/src/cid/cidload.c +++ b/third_party/freetype/src/cid/cidload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 font loader (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -215,6 +215,7 @@ { CID_FaceInfo cid = &face->cid; FT_Memory memory = face->root.memory; + FT_Stream stream = parser->stream; FT_Error error = FT_Err_Ok; FT_Long num_dicts; @@ -227,6 +228,31 @@ goto Exit; } + /* + * A single entry in the FDArray must (at least) contain the following + * structure elements. + * + * %ADOBeginFontDict 18 + * X dict begin 13 + * /FontMatrix [X X X X] 22 + * /Private X dict begin 22 + * end 4 + * end 4 + * %ADOEndFontDict 16 + * + * This needs 18+13+22+22+4+4+16=99 bytes or more. Normally, you also + * need a `dup X' at the very beginning and a `put' at the end, so a + * rough guess using 100 bytes as the minimum is justified. + */ + if ( (FT_ULong)num_dicts > stream->size / 100 ) + { + FT_TRACE0(( "parse_fd_array: adjusting FDArray size" + " (from %d to %d)\n", + num_dicts, + stream->size / 100 )); + num_dicts = (FT_Long)( stream->size / 100 ); + } + if ( !cid->font_dicts ) { FT_Int n; @@ -395,7 +421,14 @@ cur = parser->root.cursor; } + + if ( !face->cid.num_dicts ) + { + FT_ERROR(( "cid_parse_dict: No font dictionary found\n" )); + return FT_THROW( Invalid_File_Format ); + } } + return parser->root.error; } @@ -428,12 +461,8 @@ FT_Byte* p; - /* Check for possible overflow. */ - if ( num_subrs == FT_UINT_MAX ) - { - error = FT_THROW( Syntax_Error ); - goto Fail; - } + if ( !num_subrs ) + continue; /* reallocate offsets array if needed */ if ( num_subrs + 1 > max_offsets ) @@ -467,14 +496,25 @@ /* offsets must be ordered */ for ( count = 1; count <= num_subrs; count++ ) if ( offsets[count - 1] > offsets[count] ) + { + FT_ERROR(( "cid_read_subrs: offsets are not ordered\n" )); + error = FT_THROW( Invalid_File_Format ); goto Fail; + } + + if ( offsets[num_subrs] > stream->size - cid->data_offset ) + { + FT_ERROR(( "cid_read_subrs: too large `subrs' offsets\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } /* now, compute the size of subrs charstrings, */ /* allocate, and read them */ data_len = offsets[num_subrs] - offsets[0]; if ( FT_NEW_ARRAY( subr->code, num_subrs + 1 ) || - FT_ALLOC( subr->code[0], data_len ) ) + FT_ALLOC( subr->code[0], data_len ) ) goto Fail; if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) || @@ -533,7 +573,7 @@ { FT_UNUSED( face ); - FT_MEM_ZERO( loader, sizeof ( *loader ) ); + FT_ZERO( loader ); } @@ -654,6 +694,12 @@ CID_Parser* parser; FT_Memory memory = face->root.memory; FT_Error error; + FT_Int n; + + CID_FaceInfo cid = &face->cid; + + FT_ULong binary_length; + FT_ULong entry_len; cid_init_loader( &loader, face ); @@ -678,22 +724,117 @@ if ( parser->binary_length ) { + if ( parser->binary_length > + face->root.stream->size - parser->data_offset ) + { + FT_TRACE0(( "cid_face_open: adjusting length of binary data\n" + " (from %d to %d bytes)\n", + parser->binary_length, + face->root.stream->size - parser->data_offset )); + parser->binary_length = face->root.stream->size - + parser->data_offset; + } + /* we must convert the data section from hexadecimal to binary */ - if ( FT_ALLOC( face->binary_data, parser->binary_length ) || - cid_hex_to_binary( face->binary_data, parser->binary_length, - parser->data_offset, face ) ) + if ( FT_ALLOC( face->binary_data, parser->binary_length ) || + FT_SET_ERROR( cid_hex_to_binary( face->binary_data, + parser->binary_length, + parser->data_offset, + face ) ) ) goto Exit; FT_Stream_OpenMemory( face->cid_stream, face->binary_data, parser->binary_length ); - face->cid.data_offset = 0; + cid->data_offset = 0; } else { - *face->cid_stream = *face->root.stream; - face->cid.data_offset = loader.parser.data_offset; + *face->cid_stream = *face->root.stream; + cid->data_offset = loader.parser.data_offset; + } + + /* sanity tests */ + + if ( cid->fd_bytes < 0 || cid->gd_bytes < 1 ) + { + FT_ERROR(( "cid_parse_dict:" + " Invalid `FDBytes' or `GDBytes' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* allow at most 32bit offsets */ + if ( cid->fd_bytes > 4 || cid->gd_bytes > 4 ) + { + FT_ERROR(( "cid_parse_dict:" + " Values of `FDBytes' or `GDBytes' larger than 4\n" + " " + " are not supported\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + binary_length = face->cid_stream->size - cid->data_offset; + entry_len = (FT_ULong)( cid->fd_bytes + cid->gd_bytes ); + + for ( n = 0; n < cid->num_dicts; n++ ) + { + CID_FaceDict dict = cid->font_dicts + n; + + + if ( dict->sd_bytes < 0 || + ( dict->num_subrs && dict->sd_bytes < 1 ) ) + { + FT_ERROR(( "cid_parse_dict: Invalid `SDBytes' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( dict->sd_bytes > 4 ) + { + FT_ERROR(( "cid_parse_dict:" + " Values of `SDBytes' larger than 4" + " are not supported\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( dict->subrmap_offset > binary_length ) + { + FT_ERROR(( "cid_parse_dict: Invalid `SubrMapOffset' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* `num_subrs' is scanned as a signed integer */ + if ( (FT_Int)dict->num_subrs < 0 || + ( dict->sd_bytes && + dict->num_subrs > ( binary_length - dict->subrmap_offset ) / + (FT_UInt)dict->sd_bytes ) ) + { + FT_ERROR(( "cid_parse_dict: Invalid `SubrCount' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + } + + if ( cid->cidmap_offset > binary_length ) + { + FT_ERROR(( "cid_parse_dict: Invalid `CIDMapOffset' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( entry_len && + cid->cid_count > + ( binary_length - cid->cidmap_offset ) / entry_len ) + { + FT_ERROR(( "cid_parse_dict: Invalid `CIDCount' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; } + /* we can now safely proceed */ error = cid_read_subrs( face ); Exit: diff --git a/third_party/freetype/src/cid/cidload.h b/third_party/freetype/src/cid/cidload.h index d7776d2f88..45a0e6df25 100644 --- a/third_party/freetype/src/cid/cidload.h +++ b/third_party/freetype/src/cid/cidload.h @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 font loader (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDLOAD_H__ -#define __CIDLOAD_H__ +#ifndef CIDLOAD_H_ +#define CIDLOAD_H_ #include <ft2build.h> @@ -47,7 +47,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDLOAD_H__ */ +#endif /* CIDLOAD_H_ */ /* END */ diff --git a/third_party/freetype/src/cid/cidobjs.c b/third_party/freetype/src/cid/cidobjs.c index bf1519bc6e..7830e1f684 100644 --- a/third_party/freetype/src/cid/cidobjs.c +++ b/third_party/freetype/src/cid/cidobjs.c @@ -4,7 +4,7 @@ /* */ /* CID objects manager (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/cid/cidobjs.h b/third_party/freetype/src/cid/cidobjs.h index e9095ca68e..8bcf886e10 100644 --- a/third_party/freetype/src/cid/cidobjs.h +++ b/third_party/freetype/src/cid/cidobjs.h @@ -4,7 +4,7 @@ /* */ /* CID objects manager (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDOBJS_H__ -#define __CIDOBJS_H__ +#ifndef CIDOBJS_H_ +#define CIDOBJS_H_ #include <ft2build.h> @@ -148,7 +148,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDOBJS_H__ */ +#endif /* CIDOBJS_H_ */ /* END */ diff --git a/third_party/freetype/src/cid/cidparse.c b/third_party/freetype/src/cid/cidparse.c index c276949779..007609bbdf 100644 --- a/third_party/freetype/src/cid/cidparse.c +++ b/third_party/freetype/src/cid/cidparse.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 parser (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -47,6 +47,12 @@ /*************************************************************************/ +#define STARTDATA "StartData" +#define STARTDATA_LEN ( sizeof ( STARTDATA ) - 1 ) +#define SFNTS "/sfnts" +#define SFNTS_LEN ( sizeof ( SFNTS ) - 1 ) + + FT_LOCAL_DEF( FT_Error ) cid_parser_new( CID_Parser* parser, FT_Stream stream, @@ -59,7 +65,7 @@ FT_Byte *arg1, *arg2; - FT_MEM_ZERO( parser, sizeof ( *parser ) ); + FT_ZERO( parser ); psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); parser->stream = stream; @@ -85,9 +91,29 @@ /* now, read the rest of the file until we find */ /* `StartData' or `/sfnts' */ { - FT_Byte buffer[256 + 10]; - FT_ULong read_len = 256 + 10; - FT_Byte* p = buffer; + /* + * The algorithm is as follows (omitting the case with less than 256 + * bytes to fill for simplicity). + * + * 1. Fill the buffer with 256 + STARTDATA_LEN bytes. + * + * 2. Search for the STARTDATA and SFNTS strings at positions + * buffer[0], buffer[1], ..., + * buffer[255 + STARTDATA_LEN - SFNTS_LEN]. + * + * 3. Move the last STARTDATA_LEN bytes to buffer[0]. + * + * 4. Fill the buffer with 256 bytes, starting at STARTDATA_LEN. + * + * 5. Repeat with step 2. + * + */ + FT_Byte buffer[256 + STARTDATA_LEN + 1]; + + /* values for the first loop */ + FT_ULong read_len = 256 + STARTDATA_LEN; + FT_ULong read_offset = 0; + FT_Byte* p = buffer; for ( offset = FT_STREAM_POS(); ; offset += 256 ) @@ -96,40 +122,48 @@ stream_len = stream->size - FT_STREAM_POS(); - if ( stream_len == 0 ) - { - FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } read_len = FT_MIN( read_len, stream_len ); if ( FT_STREAM_READ( p, read_len ) ) goto Exit; - if ( read_len < 256 ) - p[read_len] = '\0'; + /* ensure that we do not compare with data beyond the buffer */ + p[read_len] = '\0'; - limit = p + read_len - 10; + limit = p + read_len - SFNTS_LEN; for ( p = buffer; p < limit; p++ ) { - if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 ) + if ( p[0] == 'S' && + ft_strncmp( (char*)p, STARTDATA, STARTDATA_LEN ) == 0 ) { /* save offset of binary data after `StartData' */ - offset += (FT_ULong)( p - buffer + 10 ); + offset += (FT_ULong)( p - buffer ) + STARTDATA_LEN + 1; goto Found; } - else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 ) + else if ( p[1] == 's' && + ft_strncmp( (char*)p, SFNTS, SFNTS_LEN ) == 0 ) { - offset += (FT_ULong)( p - buffer + 7 ); + offset += (FT_ULong)( p - buffer ) + SFNTS_LEN + 1; goto Found; } } - FT_MEM_MOVE( buffer, p, 10 ); - read_len = 256; - p = buffer + 10; + if ( read_offset + read_len < STARTDATA_LEN ) + { + FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + FT_MEM_MOVE( buffer, + buffer + read_offset + read_len - STARTDATA_LEN, + STARTDATA_LEN ); + + /* values for the next loop */ + read_len = 256; + read_offset = STARTDATA_LEN; + p = buffer + read_offset; } } @@ -165,7 +199,7 @@ limit = parser->root.limit; cur = parser->root.cursor; - while ( cur < limit ) + while ( cur <= limit - SFNTS_LEN ) { if ( parser->root.error ) { @@ -173,11 +207,13 @@ goto Exit; } - if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) + if ( cur[0] == 'S' && + cur <= limit - STARTDATA_LEN && + ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 ) { if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) { - FT_Long tmp = ft_atol( (const char *)arg2 ); + FT_Long tmp = ft_strtol( (const char *)arg2, NULL, 10 ); if ( tmp < 0 ) @@ -191,7 +227,8 @@ goto Exit; } - else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 ) + else if ( cur[1] == 's' && + ft_strncmp( (char*)cur, SFNTS, SFNTS_LEN ) == 0 ) { FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" )); error = FT_THROW( Unknown_File_Format ); @@ -216,6 +253,12 @@ } +#undef STARTDATA +#undef STARTDATA_LEN +#undef SFNTS +#undef SFNTS_LEN + + FT_LOCAL_DEF( void ) cid_parser_done( CID_Parser* parser ) { diff --git a/third_party/freetype/src/cid/cidparse.h b/third_party/freetype/src/cid/cidparse.h index f581bb43ff..20bebb942b 100644 --- a/third_party/freetype/src/cid/cidparse.h +++ b/third_party/freetype/src/cid/cidparse.h @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 parser (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDPARSE_H__ -#define __CIDPARSE_H__ +#ifndef CIDPARSE_H_ +#define CIDPARSE_H_ #include <ft2build.h> @@ -117,7 +117,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDPARSE_H__ */ +#endif /* CIDPARSE_H_ */ /* END */ diff --git a/third_party/freetype/src/cid/cidriver.c b/third_party/freetype/src/cid/cidriver.c index 07c4cc410b..bb611a961e 100644 --- a/third_party/freetype/src/cid/cidriver.c +++ b/third_party/freetype/src/cid/cidriver.c @@ -4,7 +4,7 @@ /* */ /* CID driver interface (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -59,7 +59,7 @@ static const FT_Service_PsFontNameRec cid_service_ps_name = { - (FT_PsName_GetFunc) cid_get_postscript_name + (FT_PsName_GetFunc)cid_get_postscript_name /* get_ps_font_name */ }; @@ -88,11 +88,14 @@ static const FT_Service_PsInfoRec cid_service_ps_info = { - (PS_GetFontInfoFunc) cid_ps_get_font_info, - (PS_GetFontExtraFunc) cid_ps_get_font_extra, - (PS_HasGlyphNamesFunc) NULL, /* unsupported with CID fonts */ - (PS_GetFontPrivateFunc)NULL, /* unsupported */ - (PS_GetFontValueFunc) NULL /* not implemented */ + (PS_GetFontInfoFunc) cid_ps_get_font_info, /* ps_get_font_info */ + (PS_GetFontExtraFunc) cid_ps_get_font_extra, /* ps_get_font_extra */ + /* unsupported with CID fonts */ + (PS_HasGlyphNamesFunc) NULL, /* ps_has_glyph_names */ + /* unsupported */ + (PS_GetFontPrivateFunc)NULL, /* ps_get_font_private */ + /* not implemented */ + (PS_GetFontValueFunc) NULL /* ps_get_font_value */ }; @@ -155,9 +158,12 @@ static const FT_Service_CIDRec cid_service_cid_info = { - (FT_CID_GetRegistryOrderingSupplementFunc)cid_get_ros, - (FT_CID_GetIsInternallyCIDKeyedFunc) cid_get_is_cid, - (FT_CID_GetCIDFromGlyphIndexFunc) cid_get_cid_from_glyph_index + (FT_CID_GetRegistryOrderingSupplementFunc) + cid_get_ros, /* get_ros */ + (FT_CID_GetIsInternallyCIDKeyedFunc) + cid_get_is_cid, /* get_is_cid */ + (FT_CID_GetCIDFromGlyphIndexFunc) + cid_get_cid_from_glyph_index /* get_cid_from_glyph_index */ }; @@ -190,46 +196,42 @@ FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec t1cid_driver_class = { - /* first of all, the FT_Module_Class fields */ { FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_SCALABLE | FT_MODULE_DRIVER_HAS_HINTER, - sizeof ( FT_DriverRec ), + "t1cid", /* module name */ 0x10000L, /* version 1.0 of driver */ 0x20000L, /* requires FreeType 2.0 */ - 0, + NULL, /* module-specific interface */ - cid_driver_init, - cid_driver_done, - cid_get_interface + cid_driver_init, /* FT_Module_Constructor module_init */ + cid_driver_done, /* FT_Module_Destructor module_done */ + cid_get_interface /* FT_Module_Requester get_interface */ }, - /* then the other font drivers fields */ sizeof ( CID_FaceRec ), sizeof ( CID_SizeRec ), sizeof ( CID_GlyphSlotRec ), - cid_face_init, - cid_face_done, - - cid_size_init, - cid_size_done, - cid_slot_init, - cid_slot_done, - - cid_slot_load_glyph, + cid_face_init, /* FT_Face_InitFunc init_face */ + cid_face_done, /* FT_Face_DoneFunc done_face */ + cid_size_init, /* FT_Size_InitFunc init_size */ + cid_size_done, /* FT_Size_DoneFunc done_size */ + cid_slot_init, /* FT_Slot_InitFunc init_slot */ + cid_slot_done, /* FT_Slot_DoneFunc done_slot */ - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ + cid_slot_load_glyph, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetAdvancesFunc */ + NULL, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ + NULL, /* FT_Face_GetAdvancesFunc get_advances */ - cid_size_request, - 0 /* FT_Size_SelectFunc */ + cid_size_request, /* FT_Size_RequestFunc request_size */ + NULL /* FT_Size_SelectFunc select_size */ }; diff --git a/third_party/freetype/src/cid/cidriver.h b/third_party/freetype/src/cid/cidriver.h index e5b8678464..76640c57ba 100644 --- a/third_party/freetype/src/cid/cidriver.h +++ b/third_party/freetype/src/cid/cidriver.h @@ -4,7 +4,7 @@ /* */ /* High-level CID driver interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDRIVER_H__ -#define __CIDRIVER_H__ +#ifndef CIDRIVER_H_ +#define CIDRIVER_H_ #include <ft2build.h> @@ -37,7 +37,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDRIVER_H__ */ +#endif /* CIDRIVER_H_ */ /* END */ diff --git a/third_party/freetype/src/cid/cidtoken.h b/third_party/freetype/src/cid/cidtoken.h index 82eae0ca6b..653cc5586e 100644 --- a/third_party/freetype/src/cid/cidtoken.h +++ b/third_party/freetype/src/cid/cidtoken.h @@ -4,7 +4,7 @@ /* */ /* CID token definitions (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/cid/type1cid.c b/third_party/freetype/src/cid/type1cid.c index 0d54ca7f44..aeb9c3eabf 100644 --- a/third_party/freetype/src/cid/type1cid.c +++ b/third_party/freetype/src/cid/type1cid.c @@ -4,7 +4,7 @@ /* */ /* FreeType OpenType driver component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/psaux/afmparse.c b/third_party/freetype/src/psaux/afmparse.c index 3ad44ec724..dbe7ddd705 100644 --- a/third_party/freetype/src/psaux/afmparse.c +++ b/third_party/freetype/src/psaux/afmparse.c @@ -4,7 +4,7 @@ /* */ /* AFM parser (body). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/psaux/afmparse.h b/third_party/freetype/src/psaux/afmparse.h index f922c4ebde..cd2beb7804 100644 --- a/third_party/freetype/src/psaux/afmparse.h +++ b/third_party/freetype/src/psaux/afmparse.h @@ -4,7 +4,7 @@ /* */ /* AFM parser (specification). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFMPARSE_H__ -#define __AFMPARSE_H__ +#ifndef AFMPARSE_H_ +#define AFMPARSE_H_ #include <ft2build.h> @@ -83,7 +83,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFMPARSE_H__ */ +#endif /* AFMPARSE_H_ */ /* END */ diff --git a/third_party/freetype/src/psaux/psaux.c b/third_party/freetype/src/psaux/psaux.c index 7f1d9aa595..f8f19d0f33 100644 --- a/third_party/freetype/src/psaux/psaux.c +++ b/third_party/freetype/src/psaux/psaux.c @@ -4,7 +4,7 @@ /* */ /* FreeType auxiliary PostScript driver component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/psaux/psauxerr.h b/third_party/freetype/src/psaux/psauxerr.h index 97712f0795..1d7ac6001b 100644 --- a/third_party/freetype/src/psaux/psauxerr.h +++ b/third_party/freetype/src/psaux/psauxerr.h @@ -4,7 +4,7 @@ /* */ /* PS auxiliary module error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __PSAUXERR_H__ -#define __PSAUXERR_H__ +#ifndef PSAUXERR_H_ +#define PSAUXERR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PSaux_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __PSAUXERR_H__ */ +#endif /* PSAUXERR_H_ */ /* END */ diff --git a/third_party/freetype/src/psaux/psauxmod.c b/third_party/freetype/src/psaux/psauxmod.c index 06fcab0c4a..1f589cefc2 100644 --- a/third_party/freetype/src/psaux/psauxmod.c +++ b/third_party/freetype/src/psaux/psauxmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType auxiliary PostScript module implementation (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,52 +30,56 @@ FT_CALLBACK_TABLE_DEF const PS_Table_FuncsRec ps_table_funcs = { - ps_table_new, - ps_table_done, - ps_table_add, - ps_table_release + ps_table_new, /* init */ + ps_table_done, /* done */ + ps_table_add, /* add */ + ps_table_release /* release */ }; FT_CALLBACK_TABLE_DEF const PS_Parser_FuncsRec ps_parser_funcs = { - ps_parser_init, - ps_parser_done, - ps_parser_skip_spaces, - ps_parser_skip_PS_token, - ps_parser_to_int, - ps_parser_to_fixed, - ps_parser_to_bytes, - ps_parser_to_coord_array, - ps_parser_to_fixed_array, - ps_parser_to_token, - ps_parser_to_token_array, - ps_parser_load_field, - ps_parser_load_field_table + ps_parser_init, /* init */ + ps_parser_done, /* done */ + + ps_parser_skip_spaces, /* skip_spaces */ + ps_parser_skip_PS_token, /* skip_PS_token */ + + ps_parser_to_int, /* to_int */ + ps_parser_to_fixed, /* to_fixed */ + ps_parser_to_bytes, /* to_bytes */ + ps_parser_to_coord_array, /* to_coord_array */ + ps_parser_to_fixed_array, /* to_fixed_array */ + ps_parser_to_token, /* to_token */ + ps_parser_to_token_array, /* to_token_array */ + + ps_parser_load_field, /* load_field */ + ps_parser_load_field_table /* load_field_table */ }; FT_CALLBACK_TABLE_DEF const T1_Builder_FuncsRec t1_builder_funcs = { - t1_builder_init, - t1_builder_done, - t1_builder_check_points, - t1_builder_add_point, - t1_builder_add_point1, - t1_builder_add_contour, - t1_builder_start_point, - t1_builder_close_contour + t1_builder_init, /* init */ + t1_builder_done, /* done */ + + t1_builder_check_points, /* check_points */ + t1_builder_add_point, /* add_point */ + t1_builder_add_point1, /* add_point1 */ + t1_builder_add_contour, /* add_contour */ + t1_builder_start_point, /* start_point */ + t1_builder_close_contour /* close_contour */ }; FT_CALLBACK_TABLE_DEF const T1_Decoder_FuncsRec t1_decoder_funcs = { - t1_decoder_init, - t1_decoder_done, - t1_decoder_parse_charstrings + t1_decoder_init, /* init */ + t1_decoder_done, /* done */ + t1_decoder_parse_charstrings /* parse_charstrings */ }; @@ -83,9 +87,9 @@ FT_CALLBACK_TABLE_DEF const AFM_Parser_FuncsRec afm_parser_funcs = { - afm_parser_init, - afm_parser_done, - afm_parser_parse + afm_parser_init, /* init */ + afm_parser_done, /* done */ + afm_parser_parse /* parse */ }; #endif @@ -130,9 +134,9 @@ &psaux_interface, /* module-specific interface */ - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 + (FT_Module_Constructor)NULL, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) NULL /* get_interface */ }; diff --git a/third_party/freetype/src/psaux/psauxmod.h b/third_party/freetype/src/psaux/psauxmod.h index ae6a8f9383..926f37eba5 100644 --- a/third_party/freetype/src/psaux/psauxmod.h +++ b/third_party/freetype/src/psaux/psauxmod.h @@ -4,7 +4,7 @@ /* */ /* FreeType auxiliary PostScript module implementation (specification). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSAUXMOD_H__ -#define __PSAUXMOD_H__ +#ifndef PSAUXMOD_H_ +#define PSAUXMOD_H_ #include <ft2build.h> @@ -36,7 +36,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSAUXMOD_H__ */ +#endif /* PSAUXMOD_H_ */ /* END */ diff --git a/third_party/freetype/src/psaux/psconv.c b/third_party/freetype/src/psaux/psconv.c index aca741204f..b092482194 100644 --- a/third_party/freetype/src/psaux/psconv.c +++ b/third_party/freetype/src/psaux/psconv.c @@ -4,7 +4,7 @@ /* */ /* Some convenience conversions (body). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/psaux/psconv.h b/third_party/freetype/src/psaux/psconv.h index 10f1ff7fb1..cab254ac5a 100644 --- a/third_party/freetype/src/psaux/psconv.h +++ b/third_party/freetype/src/psaux/psconv.h @@ -4,7 +4,7 @@ /* */ /* Some convenience conversions (specification). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSCONV_H__ -#define __PSCONV_H__ +#ifndef PSCONV_H_ +#define PSCONV_H_ #include <ft2build.h> @@ -65,7 +65,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSCONV_H__ */ +#endif /* PSCONV_H_ */ /* END */ diff --git a/third_party/freetype/src/psaux/psobjs.c b/third_party/freetype/src/psaux/psobjs.c index 1d3c7e662c..d18e821a9f 100644 --- a/third_party/freetype/src/psaux/psobjs.c +++ b/third_party/freetype/src/psaux/psobjs.c @@ -4,7 +4,7 @@ /* */ /* Auxiliary functions for PostScript fonts (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -344,7 +344,7 @@ FT_Byte c = *cur; - ++cur; + cur++; if ( c == '\\' ) { @@ -370,17 +370,17 @@ case '\\': case '(': case ')': - ++cur; + cur++; break; default: /* skip octal escape or ignore backslash */ - for ( i = 0; i < 3 && cur < limit; ++i ) + for ( i = 0; i < 3 && cur < limit; i++ ) { if ( !IS_OCTAL_DIGIT( *cur ) ) break; - ++cur; + cur++; } } } @@ -455,19 +455,19 @@ FT_ASSERT( **acur == '{' ); - for ( cur = *acur; cur < limit && error == FT_Err_Ok; ++cur ) + for ( cur = *acur; cur < limit && error == FT_Err_Ok; cur++ ) { switch ( *cur ) { case '{': - ++embed; + embed++; break; case '}': - --embed; + embed--; if ( embed == 0 ) { - ++cur; + cur++; goto end; } break; @@ -695,7 +695,7 @@ /* ************ otherwise, it is any token **************/ default: token->start = cur; - token->type = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : 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 ) @@ -750,7 +750,7 @@ if ( !token.type ) break; - if ( tokens != NULL && cur < limit ) + if ( tokens && cur < limit ) *cur = token; cur++; @@ -815,12 +815,12 @@ old_cur = cur; - if ( coords != NULL && count >= max_coords ) + if ( coords && count >= max_coords ) break; /* call PS_Conv_ToFixed() even if coords == NULL */ /* to properly parse number at `cur' */ - *( coords != NULL ? &coords[count] : &dummy ) = + *( coords ? &coords[count] : &dummy ) = (FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 ); if ( old_cur == cur ) @@ -895,12 +895,12 @@ old_cur = cur; - if ( values != NULL && count >= max_values ) + if ( values && count >= max_values ) break; /* call PS_Conv_ToFixed() even if coords == NULL */ /* to properly parse number at `cur' */ - *( values != NULL ? &values[count] : &dummy ) = + *( values ? &values[count] : &dummy ) = PS_Conv_ToFixed( &cur, limit, power_ten ); if ( old_cur == cur ) @@ -1087,9 +1087,9 @@ for ( ; count > 0; count--, idx++ ) { - FT_Byte* q = (FT_Byte*)objects[idx] + field->offset; + FT_Byte* q = (FT_Byte*)objects[idx] + field->offset; FT_Long val; - FT_String* string; + FT_String* string = NULL; skip_spaces( &cur, limit ); @@ -1172,7 +1172,7 @@ /* for this to work (FT_String**)q must have been */ /* initialized to NULL */ - if ( *(FT_String**)q != NULL ) + if ( *(FT_String**)q ) { FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n", field->ident )); @@ -1217,7 +1217,7 @@ case T1_FIELD_TYPE_MM_BBOX: { FT_Memory memory = parser->memory; - FT_Fixed* temp; + FT_Fixed* temp = NULL; FT_Int result; FT_UInt i; diff --git a/third_party/freetype/src/psaux/psobjs.h b/third_party/freetype/src/psaux/psobjs.h index bf879c1faf..202e5b2416 100644 --- a/third_party/freetype/src/psaux/psobjs.h +++ b/third_party/freetype/src/psaux/psobjs.h @@ -4,7 +4,7 @@ /* */ /* Auxiliary functions for PostScript fonts (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSOBJS_H__ -#define __PSOBJS_H__ +#ifndef PSOBJS_H_ +#define PSOBJS_H_ #include <ft2build.h> @@ -206,7 +206,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSOBJS_H__ */ +#endif /* PSOBJS_H_ */ /* END */ diff --git a/third_party/freetype/src/psaux/t1cmap.c b/third_party/freetype/src/psaux/t1cmap.c index 2e2d433fc4..45b713eb7b 100644 --- a/third_party/freetype/src/psaux/t1cmap.c +++ b/third_party/freetype/src/psaux/t1cmap.c @@ -4,7 +4,7 @@ /* */ /* Type 1 character map support (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 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 @@ cmap->code_to_sid = is_expert ? psnames->adobe_expert_encoding : psnames->adobe_std_encoding; - FT_ASSERT( cmap->code_to_sid != NULL ); + FT_ASSERT( cmap->code_to_sid ); } @@ -136,12 +136,16 @@ { sizeof ( T1_CMapStdRec ), - (FT_CMap_InitFunc) t1_cmap_standard_init, - (FT_CMap_DoneFunc) t1_cmap_std_done, - (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, - (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + (FT_CMap_InitFunc) t1_cmap_standard_init, /* init */ + (FT_CMap_DoneFunc) t1_cmap_std_done, /* done */ + (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, /* char_index */ + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ }; @@ -161,12 +165,16 @@ { sizeof ( T1_CMapStdRec ), - (FT_CMap_InitFunc) t1_cmap_expert_init, - (FT_CMap_DoneFunc) t1_cmap_std_done, - (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, - (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + (FT_CMap_InitFunc) t1_cmap_expert_init, /* init */ + (FT_CMap_DoneFunc) t1_cmap_std_done, /* done */ + (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, /* char_index */ + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ }; @@ -193,7 +201,7 @@ cmap->count = (FT_UInt)encoding->code_last - cmap->first; cmap->indices = encoding->char_index; - FT_ASSERT( cmap->indices != NULL ); + FT_ASSERT( cmap->indices ); FT_ASSERT( encoding->code_first <= encoding->code_last ); return 0; @@ -232,7 +240,7 @@ FT_UInt32 char_code = *pchar_code; - ++char_code; + char_code++; if ( char_code < cmap->first ) char_code = cmap->first; @@ -257,12 +265,16 @@ { sizeof ( T1_CMapCustomRec ), - (FT_CMap_InitFunc) t1_cmap_custom_init, - (FT_CMap_DoneFunc) t1_cmap_custom_done, - (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, - (FT_CMap_CharNextFunc) t1_cmap_custom_char_next, + (FT_CMap_InitFunc) t1_cmap_custom_init, /* init */ + (FT_CMap_DoneFunc) t1_cmap_custom_done, /* done */ + (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, /* char_index */ + (FT_CMap_CharNextFunc) t1_cmap_custom_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ }; @@ -343,12 +355,16 @@ { sizeof ( PS_UnicodesRec ), - (FT_CMap_InitFunc) t1_cmap_unicode_init, - (FT_CMap_DoneFunc) t1_cmap_unicode_done, - (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, - (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next, + (FT_CMap_InitFunc) t1_cmap_unicode_init, /* init */ + (FT_CMap_DoneFunc) t1_cmap_unicode_done, /* done */ + (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, /* char_index */ + (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ }; diff --git a/third_party/freetype/src/psaux/t1cmap.h b/third_party/freetype/src/psaux/t1cmap.h index b8ba06cc3b..7870245a3a 100644 --- a/third_party/freetype/src/psaux/t1cmap.h +++ b/third_party/freetype/src/psaux/t1cmap.h @@ -4,7 +4,7 @@ /* */ /* Type 1 character map support (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1CMAP_H__ -#define __T1CMAP_H__ +#ifndef T1CMAP_H_ +#define T1CMAP_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H @@ -99,7 +99,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1CMAP_H__ */ +#endif /* T1CMAP_H_ */ /* END */ diff --git a/third_party/freetype/src/psaux/t1decode.c b/third_party/freetype/src/psaux/t1decode.c index 2e199286f6..af7b465eda 100644 --- a/third_party/freetype/src/psaux/t1decode.c +++ b/third_party/freetype/src/psaux/t1decode.c @@ -4,7 +4,7 @@ /* */ /* PostScript Type 1 decoding routines (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,7 @@ #include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include FT_INTERNAL_HASH_H #include FT_OUTLINE_H #include "t1decode.h" @@ -404,9 +405,7 @@ ( decoder->buildchar == NULL ) ); if ( decoder->buildchar && decoder->len_buildchar > 0 ) - ft_memset( &decoder->buildchar[0], - 0, - sizeof ( decoder->buildchar[0] ) * decoder->len_buildchar ); + FT_ARRAY_ZERO( decoder->buildchar, decoder->len_buildchar ); FT_TRACE4(( "\n" "Start charstring\n" )); @@ -512,7 +511,7 @@ break; case 12: - if ( ip > limit ) + if ( ip >= limit ) { FT_ERROR(( "t1_decoder_parse_charstrings:" " invalid escape (12+EOF)\n" )); @@ -667,9 +666,9 @@ #ifdef FT_DEBUG_LEVEL_TRACE if ( large_int ) - FT_TRACE4(( " %ld", value )); + FT_TRACE4(( " %d", value )); else - FT_TRACE4(( " %ld", Fix2Int( value ) )); + FT_TRACE4(( " %d", value / 65536 )); #endif *top++ = value; @@ -735,7 +734,7 @@ if ( arg_cnt != 3 ) goto Unexpected_OtherSubr; - if ( decoder->flex_state == 0 || + if ( !decoder->flex_state || decoder->num_flex_vectors != 7 ) { FT_ERROR(( "t1_decoder_parse_charstrings:" @@ -753,13 +752,12 @@ if ( arg_cnt != 0 ) goto Unexpected_OtherSubr; + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) || + FT_SET_ERROR( t1_builder_check_points( builder, 6 ) ) ) + goto Fail; + decoder->flex_state = 1; decoder->num_flex_vectors = 0; - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok || - ( error = t1_builder_check_points( builder, 6 ) ) - != FT_Err_Ok ) - goto Fail; break; case 2: /* add flex vectors */ @@ -770,7 +768,7 @@ if ( arg_cnt != 0 ) goto Unexpected_OtherSubr; - if ( decoder->flex_state == 0 ) + if ( !decoder->flex_state ) { FT_ERROR(( "t1_decoder_parse_charstrings:" " missing flex start\n" )); @@ -875,7 +873,7 @@ PS_Blend blend = decoder->blend; - if ( arg_cnt != 1 || blend == NULL ) + if ( arg_cnt != 1 || !blend ) goto Unexpected_OtherSubr; idx = Fix2Int( top[0] ); @@ -943,7 +941,7 @@ PS_Blend blend = decoder->blend; - if ( arg_cnt != 2 || blend == NULL ) + if ( arg_cnt != 2 || !blend ) goto Unexpected_OtherSubr; idx = Fix2Int( top[1] ); @@ -964,7 +962,7 @@ PS_Blend blend = decoder->blend; - if ( arg_cnt != 1 || blend == NULL ) + if ( arg_cnt != 1 || !blend ) goto Unexpected_OtherSubr; idx = Fix2Int( top[0] ); @@ -1122,7 +1120,7 @@ FT_TRACE4(( "BuildCharArray = [ " )); - for ( i = 0; i < decoder->len_buildchar; ++i ) + for ( i = 0; i < decoder->len_buildchar; i++ ) FT_TRACE4(( "%d ", decoder->buildchar[i] )); FT_TRACE4(( "]\n" )); @@ -1200,8 +1198,7 @@ case op_hlineto: FT_TRACE4(( " hlineto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) goto Fail; x += top[0]; @@ -1222,10 +1219,8 @@ case op_hvcurveto: FT_TRACE4(( " hvcurveto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok || - ( error = t1_builder_check_points( builder, 3 ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) || + FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) goto Fail; x += top[0]; @@ -1240,16 +1235,14 @@ case op_rlineto: FT_TRACE4(( " rlineto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) goto Fail; x += top[0]; y += top[1]; Add_Line: - if ( ( error = t1_builder_add_point1( builder, x, y ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_add_point1( builder, x, y ) ) ) goto Fail; break; @@ -1269,10 +1262,8 @@ case op_rrcurveto: FT_TRACE4(( " rrcurveto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok || - ( error = t1_builder_check_points( builder, 3 ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) || + FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) goto Fail; x += top[0]; @@ -1291,10 +1282,8 @@ case op_vhcurveto: FT_TRACE4(( " vhcurveto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok || - ( error = t1_builder_check_points( builder, 3 ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) || + FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) goto Fail; y += top[0]; @@ -1309,8 +1298,7 @@ case op_vlineto: FT_TRACE4(( " vlineto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) goto Fail; y += top[0]; @@ -1335,7 +1323,7 @@ /* otherwise, we divide numbers in 16.16 format -- */ /* in both cases, it is the same operation */ *top = FT_DivFix( top[0], top[1] ); - ++top; + top++; large_int = FALSE; break; @@ -1348,6 +1336,19 @@ FT_TRACE4(( " callsubr" )); idx = Fix2Int( top[0] ); + + if ( decoder->subrs_hash ) + { + size_t* val = ft_hash_num_lookup( idx, + decoder->subrs_hash ); + + + if ( val ) + idx = *val; + else + idx = -1; + } + if ( idx < 0 || idx >= decoder->num_subrs ) { FT_ERROR(( "t1_decoder_parse_charstrings:" @@ -1577,7 +1578,7 @@ FT_Render_Mode hint_mode, T1_Decoder_Callback parse_callback ) { - FT_MEM_ZERO( decoder, sizeof ( *decoder ) ); + FT_ZERO( decoder ); /* retrieve PSNames interface from list of current modules */ { diff --git a/third_party/freetype/src/psaux/t1decode.h b/third_party/freetype/src/psaux/t1decode.h index e83078f719..12c27de775 100644 --- a/third_party/freetype/src/psaux/t1decode.h +++ b/third_party/freetype/src/psaux/t1decode.h @@ -4,7 +4,7 @@ /* */ /* PostScript Type 1 decoding routines (specification). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1DECODE_H__ -#define __T1DECODE_H__ +#ifndef T1DECODE_H_ +#define T1DECODE_H_ #include <ft2build.h> @@ -58,7 +58,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1DECODE_H__ */ +#endif /* T1DECODE_H_ */ /* END */ diff --git a/third_party/freetype/src/pshinter/pshalgo.c b/third_party/freetype/src/pshinter/pshalgo.c index 6e654cb1ef..9ad1a3a02a 100644 --- a/third_party/freetype/src/pshinter/pshalgo.c +++ b/third_party/freetype/src/pshinter/pshalgo.c @@ -4,7 +4,7 @@ /* */ /* PostScript hinting algorithm (body). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -779,7 +779,7 @@ * It turns out though that minimizing the total number of lit * pixels is also important, so position C), with one edge * aligned with a pixel boundary is actually preferable - * to A). There are also more possibile positions for C) than + * to A). There are also more possible positions for C) than * for A) or B), so it involves less distortion of the overall * character shape. */ @@ -802,7 +802,7 @@ } /* We choose between B) and C) above based on the amount - * of fractinal stem width; for small amounts, choose + * of fractional stem width; for small amounts, choose * C) always, for large amounts, B) always, and inbetween, * pick whichever one involves less stem movement. */ @@ -898,7 +898,7 @@ static void psh_print_zone( PSH_Zone zone ) { - printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n", + printf( "zone [scale,delta,min,max] = [%.5f,%.2f,%d,%d]\n", zone->scale / 65536.0, zone->delta / 64.0, zone->min, @@ -1162,7 +1162,7 @@ /* clear all fields */ - FT_MEM_ZERO( glyph, sizeof ( *glyph ) ); + FT_ZERO( glyph ); memory = glyph->memory = globals->memory; @@ -1531,7 +1531,7 @@ } } - if ( point->hint == NULL ) + if ( !point->hint ) { for ( nn = 0; nn < num_hints; nn++ ) { @@ -1572,8 +1572,8 @@ PS_Mask mask = table->hint_masks->masks; FT_UInt num_masks = table->hint_masks->num_masks; FT_UInt first = 0; - FT_Int major_dir = dimension == 0 ? PSH_DIR_VERTICAL - : PSH_DIR_HORIZONTAL; + FT_Int major_dir = ( dimension == 0 ) ? PSH_DIR_VERTICAL + : PSH_DIR_HORIZONTAL; PSH_Dimension dim = &glyph->globals->dimension[dimension]; FT_Fixed scale = dim->scale_mult; FT_Int threshold; diff --git a/third_party/freetype/src/pshinter/pshalgo.h b/third_party/freetype/src/pshinter/pshalgo.h index 8373e5ec29..62e97d152b 100644 --- a/third_party/freetype/src/pshinter/pshalgo.h +++ b/third_party/freetype/src/pshinter/pshalgo.h @@ -4,7 +4,7 @@ /* */ /* PostScript hinting algorithm (specification). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSHALGO_H__ -#define __PSHALGO_H__ +#ifndef PSHALGO_H_ +#define PSHALGO_H_ #include "pshrec.h" @@ -235,7 +235,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSHALGO_H__ */ +#endif /* PSHALGO_H_ */ /* END */ diff --git a/third_party/freetype/src/pshinter/pshglob.c b/third_party/freetype/src/pshinter/pshglob.c index 4616bdc6cf..c68770c73a 100644 --- a/third_party/freetype/src/pshinter/pshglob.c +++ b/third_party/freetype/src/pshinter/pshglob.c @@ -5,7 +5,7 @@ /* PostScript hinter global hinting management (body). */ /* Inspired by the new auto-hinter module. */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -80,7 +80,7 @@ #if 0 - /* org_width is is font units, result in device pixels, 26.6 format */ + /* org_width is in font units, result in device pixels, 26.6 format */ FT_LOCAL_DEF( FT_Pos ) psh_dimension_snap_width( PSH_Dimension dimension, FT_Int org_width ) diff --git a/third_party/freetype/src/pshinter/pshglob.h b/third_party/freetype/src/pshinter/pshglob.h index c376df7b9f..8801cbada4 100644 --- a/third_party/freetype/src/pshinter/pshglob.h +++ b/third_party/freetype/src/pshinter/pshglob.h @@ -4,7 +4,7 @@ /* */ /* PostScript hinter global hinting management. */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSHGLOB_H__ -#define __PSHGLOB_H__ +#ifndef PSHGLOB_H_ +#define PSHGLOB_H_ #include FT_FREETYPE_H @@ -190,7 +190,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSHGLOB_H__ */ +#endif /* PSHGLOB_H_ */ /* END */ diff --git a/third_party/freetype/src/pshinter/pshinter.c b/third_party/freetype/src/pshinter/pshinter.c index 9e65fe2a42..e6727aea1c 100644 --- a/third_party/freetype/src/pshinter/pshinter.c +++ b/third_party/freetype/src/pshinter/pshinter.c @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript Hinting module */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/pshinter/pshmod.c b/third_party/freetype/src/pshinter/pshmod.c index 961b468506..860dc0ae82 100644 --- a/third_party/freetype/src/pshinter/pshmod.c +++ b/third_party/freetype/src/pshinter/pshmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript hinter module implementation (body). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -95,9 +95,11 @@ FT_DEFINE_PSHINTER_INTERFACE( pshinter_interface, + pshinter_get_globals_funcs, pshinter_get_t1_funcs, - pshinter_get_t2_funcs ) + pshinter_get_t2_funcs + ) FT_DEFINE_MODULE( @@ -111,9 +113,9 @@ &PSHINTER_INTERFACE_GET, /* module-specific interface */ - (FT_Module_Constructor)ps_hinter_init, - (FT_Module_Destructor) ps_hinter_done, - (FT_Module_Requester) NULL ) /* no additional interface for now */ - + (FT_Module_Constructor)ps_hinter_init, /* module_init */ + (FT_Module_Destructor) ps_hinter_done, /* module_done */ + (FT_Module_Requester) NULL /* get_interface */ + ) /* END */ diff --git a/third_party/freetype/src/pshinter/pshmod.h b/third_party/freetype/src/pshinter/pshmod.h index a58d856533..1d2b40fa13 100644 --- a/third_party/freetype/src/pshinter/pshmod.h +++ b/third_party/freetype/src/pshinter/pshmod.h @@ -4,7 +4,7 @@ /* */ /* PostScript hinter module interface (specification). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSHMOD_H__ -#define __PSHMOD_H__ +#ifndef PSHMOD_H_ +#define PSHMOD_H_ #include <ft2build.h> @@ -33,7 +33,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSHMOD_H__ */ +#endif /* PSHMOD_H_ */ /* END */ diff --git a/third_party/freetype/src/pshinter/pshnterr.h b/third_party/freetype/src/pshinter/pshnterr.h index ce790a8ef5..73d144e34c 100644 --- a/third_party/freetype/src/pshinter/pshnterr.h +++ b/third_party/freetype/src/pshinter/pshnterr.h @@ -4,7 +4,7 @@ /* */ /* PS Hinter error codes (specification only). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __PSHNTERR_H__ -#define __PSHNTERR_H__ +#ifndef PSHNTERR_H_ +#define PSHNTERR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PSH_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __PSHNTERR_H__ */ +#endif /* PSHNTERR_H_ */ /* END */ diff --git a/third_party/freetype/src/pshinter/pshpic.c b/third_party/freetype/src/pshinter/pshpic.c index afd8fb9678..c0d3a64f29 100644 --- a/third_party/freetype/src/pshinter/pshpic.c +++ b/third_party/freetype/src/pshinter/pshpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for pshinter module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/pshinter/pshpic.h b/third_party/freetype/src/pshinter/pshpic.h index ca35cd6fa9..8d9a01c9c5 100644 --- a/third_party/freetype/src/pshinter/pshpic.h +++ b/third_party/freetype/src/pshinter/pshpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for pshinter module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSHPIC_H__ -#define __PSHPIC_H__ +#ifndef PSHPIC_H_ +#define PSHPIC_H_ #include FT_INTERNAL_PIC_H @@ -57,7 +57,7 @@ FT_END_HEADER /* */ -#endif /* __PSHPIC_H__ */ +#endif /* PSHPIC_H_ */ /* END */ diff --git a/third_party/freetype/src/pshinter/pshrec.c b/third_party/freetype/src/pshinter/pshrec.c index f8895fc8d6..fff6d34250 100644 --- a/third_party/freetype/src/pshinter/pshrec.c +++ b/third_party/freetype/src/pshinter/pshrec.c @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript hints recorder (body). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -818,7 +818,7 @@ ps_hints_init( PS_Hints hints, FT_Memory memory ) { - FT_MEM_ZERO( hints, sizeof ( *hints ) ); + FT_ZERO( hints ); hints->memory = memory; } @@ -1140,7 +1140,7 @@ FT_LOCAL_DEF( void ) t1_hints_funcs_init( T1_Hints_FuncsRec* funcs ) { - FT_MEM_ZERO( (char*)funcs, sizeof ( *funcs ) ); + FT_ZERO( funcs ); funcs->open = (T1_Hints_OpenFunc) t1_hints_open; funcs->close = (T1_Hints_CloseFunc) ps_hints_close; @@ -1206,7 +1206,7 @@ FT_LOCAL_DEF( void ) t2_hints_funcs_init( T2_Hints_FuncsRec* funcs ) { - FT_MEM_ZERO( funcs, sizeof ( *funcs ) ); + FT_ZERO( funcs ); funcs->open = (T2_Hints_OpenFunc) t2_hints_open; funcs->close = (T2_Hints_CloseFunc) ps_hints_close; diff --git a/third_party/freetype/src/pshinter/pshrec.h b/third_party/freetype/src/pshinter/pshrec.h index 2b1ad94936..e10bc2b120 100644 --- a/third_party/freetype/src/pshinter/pshrec.h +++ b/third_party/freetype/src/pshinter/pshrec.h @@ -4,7 +4,7 @@ /* */ /* Postscript (Type1/Type2) hints recorder (specification). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -28,8 +28,8 @@ /**************************************************************************/ -#ifndef __PSHREC_H__ -#define __PSHREC_H__ +#ifndef PSHREC_H_ +#define PSHREC_H_ #include <ft2build.h> @@ -166,7 +166,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PS_HINTER_RECORD_H__ */ +#endif /* PSHREC_H_ */ /* END */ diff --git a/third_party/freetype/src/psnames/psmodule.c b/third_party/freetype/src/psnames/psmodule.c index 0f04c2fa7d..3ff8cb911b 100644 --- a/third_party/freetype/src/psnames/psmodule.c +++ b/third_party/freetype/src/psnames/psmodule.c @@ -4,7 +4,7 @@ /* */ /* PSNames module implementation (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,6 +22,9 @@ #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include "psmodule.h" + +#include "pstables.h" +#define DEFINE_PS_TABLES #include "pstables.h" #include "psnamerr.h" @@ -525,37 +528,42 @@ FT_DEFINE_SERVICE_PSCMAPSREC( pscmaps_interface, - (PS_Unicode_ValueFunc) ps_unicode_value, - (PS_Unicodes_InitFunc) ps_unicodes_init, - (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, - (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, - (PS_Macintosh_NameFunc) ps_get_macintosh_name, - (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, + (PS_Unicode_ValueFunc) ps_unicode_value, /* unicode_value */ + (PS_Unicodes_InitFunc) ps_unicodes_init, /* unicodes_init */ + (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, /* unicodes_char_index */ + (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, /* unicodes_char_next */ + + (PS_Macintosh_NameFunc) ps_get_macintosh_name, /* macintosh_name */ + (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings */ - t1_standard_encoding, - t1_expert_encoding ) + t1_standard_encoding, /* adobe_std_encoding */ + t1_expert_encoding /* adobe_expert_encoding */ + ) #else FT_DEFINE_SERVICE_PSCMAPSREC( pscmaps_interface, - NULL, - NULL, - NULL, - NULL, - (PS_Macintosh_NameFunc) ps_get_macintosh_name, - (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, + NULL, /* unicode_value */ + NULL, /* unicodes_init */ + NULL, /* unicodes_char_index */ + NULL, /* unicodes_char_next */ - t1_standard_encoding, - t1_expert_encoding ) + (PS_Macintosh_NameFunc) ps_get_macintosh_name, /* macintosh_name */ + (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings */ + + t1_standard_encoding, /* adobe_std_encoding */ + t1_expert_encoding /* adobe_expert_encoding */ + ) #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ FT_DEFINE_SERVICEDESCREC1( pscmaps_services, + FT_SERVICE_ID_POSTSCRIPT_CMAPS, &PSCMAPS_INTERFACE_GET ) @@ -601,9 +609,11 @@ PUT_PS_NAMES_SERVICE( (void*)&PSCMAPS_INTERFACE_GET ), /* module specific interface */ - (FT_Module_Constructor)NULL, - (FT_Module_Destructor) NULL, - (FT_Module_Requester) PUT_PS_NAMES_SERVICE( psnames_get_service ) ) + + (FT_Module_Constructor)NULL, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) PUT_PS_NAMES_SERVICE( psnames_get_service ) /* get_interface */ + ) /* END */ diff --git a/third_party/freetype/src/psnames/psmodule.h b/third_party/freetype/src/psnames/psmodule.h index f85f322193..6983b79234 100644 --- a/third_party/freetype/src/psnames/psmodule.h +++ b/third_party/freetype/src/psnames/psmodule.h @@ -4,7 +4,7 @@ /* */ /* High-level PSNames module interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSMODULE_H__ -#define __PSMODULE_H__ +#ifndef PSMODULE_H_ +#define PSMODULE_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSMODULE_H__ */ +#endif /* PSMODULE_H_ */ /* END */ diff --git a/third_party/freetype/src/psnames/psnamerr.h b/third_party/freetype/src/psnames/psnamerr.h index 09cc247b7d..f90bf5ea43 100644 --- a/third_party/freetype/src/psnames/psnamerr.h +++ b/third_party/freetype/src/psnames/psnamerr.h @@ -4,7 +4,7 @@ /* */ /* PS names module error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __PSNAMERR_H__ -#define __PSNAMERR_H__ +#ifndef PSNAMERR_H_ +#define PSNAMERR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PSnames_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __PSNAMERR_H__ */ +#endif /* PSNAMERR_H_ */ /* END */ diff --git a/third_party/freetype/src/psnames/pspic.c b/third_party/freetype/src/psnames/pspic.c index 1394f977e0..8b9003439b 100644 --- a/third_party/freetype/src/psnames/pspic.c +++ b/third_party/freetype/src/psnames/pspic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for psnames module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/psnames/pspic.h b/third_party/freetype/src/psnames/pspic.h index 443225af61..14497e73fa 100644 --- a/third_party/freetype/src/psnames/pspic.h +++ b/third_party/freetype/src/psnames/pspic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for psnames module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSPIC_H__ -#define __PSPIC_H__ +#ifndef PSPIC_H_ +#define PSPIC_H_ #include FT_INTERNAL_PIC_H @@ -62,7 +62,7 @@ FT_END_HEADER /* */ -#endif /* __PSPIC_H__ */ +#endif /* PSPIC_H_ */ /* END */ diff --git a/third_party/freetype/src/psnames/pstables.h b/third_party/freetype/src/psnames/pstables.h index 3f31c31b18..e0f5e30804 100644 --- a/third_party/freetype/src/psnames/pstables.h +++ b/third_party/freetype/src/psnames/pstables.h @@ -4,7 +4,7 @@ /* */ /* PostScript glyph names. */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,7 +19,16 @@ /* This file has been generated automatically -- do not edit! */ - static const char ft_standard_glyph_names[3696] = +#ifndef DEFINE_PS_TABLES +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const char ft_standard_glyph_names[3696] +#ifdef DEFINE_PS_TABLES + = { '.','n','u','l','l', 0, 'n','o','n','m','a','r','k','i','n','g','r','e','t','u','r','n', 0, @@ -441,14 +450,25 @@ 'R','e','g','u','l','a','r', 0, 'R','o','m','a','n', 0, 'S','e','m','i','b','o','l','d', 0, - }; + } +#endif /* DEFINE_PS_TABLES */ + ; #define FT_NUM_MAC_NAMES 258 /* Values are offsets into the `ft_standard_glyph_names' table */ - static const short ft_mac_names[FT_NUM_MAC_NAMES] = +#ifndef DEFINE_PS_TABLES +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const short ft_mac_names[FT_NUM_MAC_NAMES] +#ifdef DEFINE_PS_TABLES + = { 253, 0, 6, 261, 267, 274, 283, 294, 301, 309, 758, 330, 340, 351, 360, 365, 371, 378, 385, 391, 396, 400, 404, 410, 415, 420, 424, 430, @@ -469,14 +489,25 @@ 1066,1073,1101,1143,1536,1783,1596,1843,1253,1207,1319,1579,1826,1229, 1270,1313,1323,1171,1290,1332,1211,1235,1276, 169, 175, 182, 189, 200, 209, 218, 225, 232, 239, 246 - }; + } +#endif /* DEFINE_PS_TABLES */ + ; #define FT_NUM_SID_NAMES 391 /* Values are offsets into the `ft_standard_glyph_names' table */ - static const short ft_sid_names[FT_NUM_SID_NAMES] = +#ifndef DEFINE_PS_TABLES +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const short ft_sid_names[FT_NUM_SID_NAMES] +#ifdef DEFINE_PS_TABLES + = { 253, 261, 267, 274, 283, 294, 301, 309, 319, 330, 340, 351, 360, 365, 371, 378, 385, 391, 396, 400, 404, 410, 415, 420, 424, 430, 436, 441, @@ -506,11 +537,22 @@ 3237,3249,3264,3275,3283,3297,3309,3321,3338,3353,3365,3377,3394,3409, 3418,3430,3442,3454,3471,3483,3498,3506,3518,3530,3542,3559,3574,3586, 3597,3612,3620,3628,3636,3644,3650,3655,3660,3666,3673,3681,3687 - }; + } +#endif /* DEFINE_PS_TABLES */ + ; /* the following are indices into the SID name table */ - static const unsigned short t1_standard_encoding[256] = +#ifndef DEFINE_PS_TABLES +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const unsigned short t1_standard_encoding[256] +#ifdef DEFINE_PS_TABLES + = { 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, @@ -528,11 +570,22 @@ 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 - }; + } +#endif /* DEFINE_PS_TABLES */ + ; /* the following are indices into the SID name table */ - static const unsigned short t1_expert_encoding[256] = +#ifndef DEFINE_PS_TABLES +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const unsigned short t1_expert_encoding[256] +#ifdef DEFINE_PS_TABLES + = { 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, @@ -550,7 +603,9 @@ 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 /* DEFINE_PS_TABLES */ + ; /* @@ -564,7 +619,16 @@ #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - static const unsigned char ft_adobe_glyph_list[55997L] = +#ifndef DEFINE_PS_TABLES +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const unsigned char ft_adobe_glyph_list[55997L] +#ifdef DEFINE_PS_TABLES + = { 0, 52, 0,106, 2,167, 3, 63, 4,220, 6,125, 9,143, 10, 23, 11,137, 12,199, 14,246, 15, 87, 16,233, 17,219, 18,104, 19, 88, @@ -4066,9 +4130,12 @@ 248,232,239,239,107,128, 2,144,243,244,242,239,235,101,128, 1, 182,117, 2,218,167,218,178,232,233,242,225,231,225,238, 97,128, 48, 90,235,225,244,225,235,225,238, 97,128, 48,186 - }; + } +#endif /* DEFINE_PS_TABLES */ + ; +#ifdef DEFINE_PS_TABLES /* * This function searches the compressed table efficiently. */ @@ -4163,6 +4230,7 @@ NotFound: return 0; } +#endif /* DEFINE_PS_TABLES */ #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ diff --git a/third_party/freetype/src/raster/ftraster.c b/third_party/freetype/src/raster/ftraster.c index e4bab98728..c5643f6334 100644 --- a/third_party/freetype/src/raster/ftraster.c +++ b/third_party/freetype/src/raster/ftraster.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,7 +18,7 @@ /*************************************************************************/ /* */ /* This file can be compiled without the rest of the FreeType engine, by */ - /* defining the _STANDALONE_ macro when compiling it. You also need to */ + /* defining the STANDALONE_ macro when compiling it. You also need to */ /* put the files `ftimage.h' and `ftmisc.h' into the $(incdir) */ /* directory. Typically, you should do something like */ /* */ @@ -27,9 +27,9 @@ /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' to your */ /* current directory */ /* */ - /* - compile `ftraster' with the _STANDALONE_ macro defined, as in */ + /* - compile `ftraster' with the STANDALONE_ macro defined, as in */ /* */ - /* cc -c -D_STANDALONE_ ftraster.c */ + /* cc -c -DSTANDALONE_ ftraster.c */ /* */ /* The renderer can be initialized with a call to */ /* `ft_standard_raster.raster_new'; a bitmap can be generated */ @@ -47,7 +47,7 @@ /* */ /*************************************************************************/ -#ifdef _STANDALONE_ +#ifdef STANDALONE_ /* The size in bytes of the render pool used by the scan-line converter */ /* to do all of its work. */ @@ -60,7 +60,7 @@ #include "ftmisc.h" #include "ftimage.h" -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ #include <ft2build.h> #include "ftraster.h" @@ -68,7 +68,7 @@ #include "rastpic.h" -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ /*************************************************************************/ @@ -173,14 +173,12 @@ #define FT_COMPONENT trace_raster -#ifdef _STANDALONE_ +#ifdef STANDALONE_ /* Auxiliary macros for token concatenation. */ #define FT_ERR_XCAT( x, y ) x ## y #define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) - /* This macro is used to indicate that a function parameter is unused. */ /* Its purpose is simply to reduce compiler warnings. Note also that */ /* simply defining it as `(void)x' doesn't avoid warnings with certain */ @@ -226,7 +224,7 @@ raster_done_ \ }; -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ #include FT_INTERNAL_OBJECTS_H @@ -242,7 +240,7 @@ #define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ #ifndef FT_MEM_SET @@ -253,6 +251,10 @@ #define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) #endif +#ifndef FT_ZERO +#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) +#endif + /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is */ /* typically a small value and the result of a*b is known to fit into */ /* 32 bits. */ @@ -459,6 +461,12 @@ #define IS_TOP_OVERSHOOT( x ) \ (Bool)( x - FLOOR( x ) >= ras.precision_half ) +#if FT_RENDER_POOL_SIZE > 2048 +#define FT_MAX_BLACK_POOL ( FT_RENDER_POOL_SIZE / sizeof ( Long ) ) +#else +#define FT_MAX_BLACK_POOL ( 2048 / sizeof ( Long ) ) +#endif + /* The most used variables are positioned at the top of the structure. */ /* Thus, their offset can be coded with less opcodes, resulting in a */ /* smaller executable. */ @@ -1512,8 +1520,9 @@ state_bez = y1 < y3 ? Ascending_State : Descending_State; if ( ras.state != state_bez ) { - Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) - : IS_TOP_OVERSHOOT( y1 ); + Bool o = ( state_bez == Ascending_State ) + ? IS_BOTTOM_OVERSHOOT( y1 ) + : IS_TOP_OVERSHOOT( y1 ); /* finalize current profile if any */ @@ -1648,8 +1657,9 @@ /* detect a change of direction */ if ( ras.state != state_bez ) { - Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) - : IS_TOP_OVERSHOOT( y1 ); + Bool o = ( state_bez == Ascending_State ) + ? IS_BOTTOM_OVERSHOOT( y1 ) + : IS_TOP_OVERSHOOT( y1 ); /* finalize current profile if any */ @@ -2382,7 +2392,7 @@ pxl = e2; /* check that the other pixel isn't set */ - e1 = pxl == e1 ? e2 : e1; + e1 = ( pxl == e1 ) ? e2 : e1; e1 = TRUNC( e1 ); @@ -2583,7 +2593,7 @@ pxl = e2; /* check that the other pixel isn't set */ - e1 = pxl == e1 ? e2 : e1; + e1 = ( pxl == e1 ) ? e2 : e1; e1 = TRUNC( e1 ); @@ -3041,7 +3051,7 @@ /**** a static object. *****/ -#ifdef _STANDALONE_ +#ifdef STANDALONE_ static int @@ -3053,7 +3063,7 @@ *araster = (FT_Raster)&the_raster; - FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); + FT_ZERO( &the_raster ); ft_black_init( &the_raster ); return 0; @@ -3068,7 +3078,7 @@ } -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ static int @@ -3102,13 +3112,13 @@ } -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ static void - ft_black_reset( black_PRaster raster, - char* pool_base, - Long pool_size ) + ft_black_reset( FT_Raster raster, + PByte pool_base, + ULong pool_size ) { FT_UNUSED( raster ); FT_UNUSED( pool_base ); @@ -3117,20 +3127,20 @@ static int - ft_black_set_mode( black_PRaster raster, - ULong mode, - const char* palette ) + ft_black_set_mode( FT_Raster raster, + ULong mode, + void* args ) { FT_UNUSED( raster ); FT_UNUSED( mode ); - FT_UNUSED( palette ); + FT_UNUSED( args ); return 0; } static int - ft_black_render( black_PRaster raster, + ft_black_render( FT_Raster raster, const FT_Raster_Params* params ) { const FT_Outline* outline = (const FT_Outline*)params->source; @@ -3138,7 +3148,7 @@ black_TWorker worker[1]; - Long buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( Long )]; + Long buffer[FT_MAX_BLACK_POOL]; if ( !raster ) @@ -3175,6 +3185,20 @@ if ( !target_map->buffer ) return FT_THROW( Invalid ); + /* reject too large outline coordinates */ + { + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + + for ( ; vec < limit; vec++ ) + { + if ( vec->x < -0x1000000L || vec->x > 0x1000000L || + vec->y < -0x1000000L || vec->y > 0x1000000L ) + return FT_THROW( Invalid ); + } + } + ras.outline = *outline; ras.target = *target_map; @@ -3190,11 +3214,12 @@ FT_GLYPH_FORMAT_OUTLINE, - (FT_Raster_New_Func) ft_black_new, - (FT_Raster_Reset_Func) ft_black_reset, - (FT_Raster_Set_Mode_Func)ft_black_set_mode, - (FT_Raster_Render_Func) ft_black_render, - (FT_Raster_Done_Func) ft_black_done ) + (FT_Raster_New_Func) ft_black_new, /* raster_new */ + (FT_Raster_Reset_Func) ft_black_reset, /* raster_reset */ + (FT_Raster_Set_Mode_Func)ft_black_set_mode, /* raster_set_mode */ + (FT_Raster_Render_Func) ft_black_render, /* raster_render */ + (FT_Raster_Done_Func) ft_black_done /* raster_done */ + ) /* END */ diff --git a/third_party/freetype/src/raster/ftraster.h b/third_party/freetype/src/raster/ftraster.h index a270d487b9..6b3050cb3d 100644 --- a/third_party/freetype/src/raster/ftraster.h +++ b/third_party/freetype/src/raster/ftraster.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTRASTER_H__ -#define __FTRASTER_H__ +#ifndef FTRASTER_H_ +#define FTRASTER_H_ #include <ft2build.h> @@ -33,14 +33,14 @@ FT_BEGIN_HEADER /* Uncomment the following line if you are using ftraster.c as a */ /* standalone module, fully independent of FreeType. */ /* */ -/* #define _STANDALONE_ */ +/* #define STANDALONE_ */ FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_standard_raster; FT_END_HEADER -#endif /* __FTRASTER_H__ */ +#endif /* FTRASTER_H_ */ /* END */ diff --git a/third_party/freetype/src/raster/ftrend1.c b/third_party/freetype/src/raster/ftrend1.c index f314392839..1a83e9e477 100644 --- a/third_party/freetype/src/raster/ftrend1.c +++ b/third_party/freetype/src/raster/ftrend1.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer interface (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 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 @@ FT_GlyphSlot slot, FT_BBox* cbox ) { - FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); + FT_ZERO( cbox ); if ( slot->format == render->glyph_format ) FT_Outline_Get_CBox( &slot->outline, cbox ); @@ -224,7 +224,8 @@ } - FT_DEFINE_RENDERER( ft_raster1_renderer_class, + FT_DEFINE_RENDERER( + ft_raster1_renderer_class, FT_MODULE_RENDERER, sizeof ( FT_RendererRec ), @@ -233,21 +234,20 @@ 0x10000L, 0x20000L, - 0, /* module specific interface */ + NULL, /* module specific interface */ - (FT_Module_Constructor)ft_raster1_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , + (FT_Module_Constructor)ft_raster1_init, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) NULL, /* get_interface */ FT_GLYPH_FORMAT_OUTLINE, - (FT_Renderer_RenderFunc) ft_raster1_render, - (FT_Renderer_TransformFunc)ft_raster1_transform, - (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, - (FT_Renderer_SetModeFunc) ft_raster1_set_mode, + (FT_Renderer_RenderFunc) ft_raster1_render, /* render_glyph */ + (FT_Renderer_TransformFunc)ft_raster1_transform, /* transform_glyph */ + (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, /* get_glyph_cbox */ + (FT_Renderer_SetModeFunc) ft_raster1_set_mode, /* set_mode */ - (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET + (FT_Raster_Funcs*)&FT_STANDARD_RASTER_GET /* raster_class */ ) diff --git a/third_party/freetype/src/raster/ftrend1.h b/third_party/freetype/src/raster/ftrend1.h index edc5d13f4c..cff702d140 100644 --- a/third_party/freetype/src/raster/ftrend1.h +++ b/third_party/freetype/src/raster/ftrend1.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTREND1_H__ -#define __FTREND1_H__ +#ifndef FTREND1_H_ +#define FTREND1_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTREND1_H__ */ +#endif /* FTREND1_H_ */ /* END */ diff --git a/third_party/freetype/src/raster/raster.c b/third_party/freetype/src/raster/raster.c index 21bb16de1e..ee54ae19fe 100644 --- a/third_party/freetype/src/raster/raster.c +++ b/third_party/freetype/src/raster/raster.c @@ -4,7 +4,7 @@ /* */ /* FreeType monochrome rasterer module component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/raster/rasterrs.h b/third_party/freetype/src/raster/rasterrs.h index e7f00bcace..0d646908ad 100644 --- a/third_party/freetype/src/raster/rasterrs.h +++ b/third_party/freetype/src/raster/rasterrs.h @@ -4,7 +4,7 @@ /* */ /* monochrome renderer error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __RASTERRS_H__ -#define __RASTERRS_H__ +#ifndef RASTERRS_H_ +#define RASTERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX Raster_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __RASTERRS_H__ */ +#endif /* RASTERRS_H_ */ /* END */ diff --git a/third_party/freetype/src/raster/rastpic.c b/third_party/freetype/src/raster/rastpic.c index 77e7ec3f90..7085339b7b 100644 --- a/third_party/freetype/src/raster/rastpic.c +++ b/third_party/freetype/src/raster/rastpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for raster module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/raster/rastpic.h b/third_party/freetype/src/raster/rastpic.h index 408996a908..dcd691310d 100644 --- a/third_party/freetype/src/raster/rastpic.h +++ b/third_party/freetype/src/raster/rastpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for raster module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __RASTPIC_H__ -#define __RASTPIC_H__ +#ifndef RASTPIC_H_ +#define RASTPIC_H_ #include FT_INTERNAL_PIC_H @@ -57,7 +57,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __RASTPIC_H__ */ +#endif /* RASTPIC_H_ */ /* END */ diff --git a/third_party/freetype/src/sfnt/sfdriver.c b/third_party/freetype/src/sfnt/sfdriver.c index 6a3f0d9933..0b9867aa1a 100644 --- a/third_party/freetype/src/sfnt/sfdriver.c +++ b/third_party/freetype/src/sfnt/sfdriver.c @@ -4,7 +4,7 @@ /* */ /* High-level SFNT driver interface (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 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 @@ break; case FT_SFNT_OS2: - table = face->os2.version == 0xFFFFU ? NULL : &face->os2; + table = ( face->os2.version == 0xFFFFU ) ? NULL : &face->os2; break; case FT_SFNT_POST: @@ -139,9 +139,11 @@ FT_DEFINE_SERVICE_SFNT_TABLEREC( sfnt_service_sfnt_table, - (FT_SFNT_TableLoadFunc)tt_face_load_any, - (FT_SFNT_TableGetFunc) get_sfnt_table, - (FT_SFNT_TableInfoFunc)sfnt_table_info ) + + (FT_SFNT_TableLoadFunc)tt_face_load_any, /* load_table */ + (FT_SFNT_TableGetFunc) get_sfnt_table, /* get_table */ + (FT_SFNT_TableInfoFunc)sfnt_table_info /* table_info */ + ) #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES @@ -152,7 +154,7 @@ */ static FT_Error - sfnt_get_glyph_name( TT_Face face, + sfnt_get_glyph_name( FT_Face face, FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max ) @@ -161,7 +163,7 @@ FT_Error error; - error = tt_face_get_ps_name( face, glyph_index, &gname ); + error = tt_face_get_ps_name( (TT_Face)face, glyph_index, &gname ); if ( !error ) FT_STRCPYN( buffer, gname, buffer_max ); @@ -170,26 +172,26 @@ static FT_UInt - sfnt_get_name_index( TT_Face face, + sfnt_get_name_index( FT_Face face, FT_String* glyph_name ) { - FT_Face root = &face->root; + TT_Face ttface = (TT_Face)face; FT_UInt i, max_gid = FT_UINT_MAX; - if ( root->num_glyphs < 0 ) + if ( face->num_glyphs < 0 ) return 0; - else if ( (FT_ULong)root->num_glyphs < FT_UINT_MAX ) - max_gid = (FT_UInt)root->num_glyphs; + else if ( (FT_ULong)face->num_glyphs < FT_UINT_MAX ) + max_gid = (FT_UInt)face->num_glyphs; else FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n", - FT_UINT_MAX, root->num_glyphs )); + FT_UINT_MAX, face->num_glyphs )); for ( i = 0; i < max_gid; i++ ) { FT_String* gname; - FT_Error error = tt_face_get_ps_name( face, i, &gname ); + FT_Error error = tt_face_get_ps_name( ttface, i, &gname ); if ( error ) @@ -205,9 +207,10 @@ FT_DEFINE_SERVICE_GLYPHDICTREC( sfnt_service_glyph_dict, - (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index ) + (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, /* get_name */ + (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index /* name_index */ + ) #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ @@ -330,7 +333,9 @@ FT_DEFINE_SERVICE_PSFONTNAMEREC( sfnt_service_ps_name, - (FT_PsName_GetFunc)sfnt_get_ps_name ) + + (FT_PsName_GetFunc)sfnt_get_ps_name /* get_ps_font_name */ + ) /* @@ -338,7 +343,9 @@ */ FT_DEFINE_SERVICE_TTCMAPSREC( tt_service_get_cmap_info, - (TT_CMap_Info_GetFunc)tt_get_cmap_info ) + + (TT_CMap_Info_GetFunc)tt_get_cmap_info /* get_cmap_info */ + ) #ifdef TT_CONFIG_OPTION_BDF @@ -381,8 +388,10 @@ FT_DEFINE_SERVICE_BDFRec( sfnt_service_bdf, - (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id, - (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop ) + + (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id, /* get_charset_id */ + (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop /* get_property */ + ) #endif /* TT_CONFIG_OPTION_BDF */ @@ -395,6 +404,7 @@ #if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF FT_DEFINE_SERVICEDESCREC5( sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, FT_SERVICE_ID_GLYPH_DICT, &SFNT_SERVICE_GLYPH_DICT_GET, @@ -403,6 +413,7 @@ #elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES FT_DEFINE_SERVICEDESCREC4( sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, FT_SERVICE_ID_GLYPH_DICT, &SFNT_SERVICE_GLYPH_DICT_GET, @@ -410,6 +421,7 @@ #elif defined TT_CONFIG_OPTION_BDF FT_DEFINE_SERVICEDESCREC4( sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, FT_SERVICE_ID_BDF, &SFNT_SERVICE_BDF_GET, @@ -417,6 +429,7 @@ #else FT_DEFINE_SERVICEDESCREC3( sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET ) @@ -459,55 +472,63 @@ FT_DEFINE_SFNT_INTERFACE( sfnt_interface, - tt_face_goto_table, - sfnt_init_face, - sfnt_load_face, - sfnt_done_face, - sfnt_get_interface, + tt_face_goto_table, /* TT_Loader_GotoTableFunc goto_table */ + + sfnt_init_face, /* TT_Init_Face_Func init_face */ + sfnt_load_face, /* TT_Load_Face_Func load_face */ + sfnt_done_face, /* TT_Done_Face_Func done_face */ + sfnt_get_interface, /* FT_Module_Requester get_interface */ - tt_face_load_any, + tt_face_load_any, /* TT_Load_Any_Func load_any */ - tt_face_load_head, - tt_face_load_hhea, - tt_face_load_cmap, - tt_face_load_maxp, - tt_face_load_os2, - tt_face_load_post, + tt_face_load_head, /* TT_Load_Table_Func load_head */ + tt_face_load_hhea, /* TT_Load_Metrics_Func load_hhea */ + tt_face_load_cmap, /* TT_Load_Table_Func load_cmap */ + tt_face_load_maxp, /* TT_Load_Table_Func load_maxp */ + tt_face_load_os2, /* TT_Load_Table_Func load_os2 */ + tt_face_load_post, /* TT_Load_Table_Func load_post */ - tt_face_load_name, - tt_face_free_name, + tt_face_load_name, /* TT_Load_Table_Func load_name */ + tt_face_free_name, /* TT_Free_Table_Func free_name */ - tt_face_load_kern, - tt_face_load_gasp, - tt_face_load_pclt, + tt_face_load_kern, /* TT_Load_Table_Func load_kern */ + tt_face_load_gasp, /* TT_Load_Table_Func load_gasp */ + tt_face_load_pclt, /* TT_Load_Table_Func load_init */ /* see `ttload.h' */ PUT_EMBEDDED_BITMAPS( tt_face_load_bhed ), - + /* TT_Load_Table_Func load_bhed */ PUT_EMBEDDED_BITMAPS( tt_face_load_sbit_image ), + /* TT_Load_SBit_Image_Func load_sbit_image */ /* see `ttpost.h' */ PUT_PS_NAMES( tt_face_get_ps_name ), + /* TT_Get_PS_Name_Func get_psname */ PUT_PS_NAMES( tt_face_free_ps_names ), + /* TT_Free_Table_Func free_psnames */ /* since version 2.1.8 */ - tt_face_get_kerning, + tt_face_get_kerning, /* TT_Face_GetKerningFunc get_kerning */ /* since version 2.2 */ - tt_face_load_font_dir, - tt_face_load_hmtx, + tt_face_load_font_dir, /* TT_Load_Table_Func load_font_dir */ + tt_face_load_hmtx, /* TT_Load_Metrics_Func load_hmtx */ /* see `ttsbit.h' and `sfnt.h' */ PUT_EMBEDDED_BITMAPS( tt_face_load_sbit ), + /* TT_Load_Table_Func load_eblc */ PUT_EMBEDDED_BITMAPS( tt_face_free_sbit ), + /* TT_Free_Table_Func free_eblc */ PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike ), + /* TT_Set_SBit_Strike_Func set_sbit_strike */ PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ), + /* TT_Load_Strike_Metrics_Func load_strike_metrics */ - tt_face_get_metrics, + tt_face_get_metrics, /* TT_Get_Metrics_Func get_metrics */ - tt_face_get_name + tt_face_get_name /* TT_Get_Name_Func get_name */ ) @@ -523,9 +544,10 @@ (const void*)&SFNT_INTERFACE_GET, /* module specific interface */ - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) sfnt_get_interface ) + (FT_Module_Constructor)NULL, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) sfnt_get_interface /* get_interface */ + ) /* END */ diff --git a/third_party/freetype/src/sfnt/sfdriver.h b/third_party/freetype/src/sfnt/sfdriver.h index 944119cc22..38710b60f2 100644 --- a/third_party/freetype/src/sfnt/sfdriver.h +++ b/third_party/freetype/src/sfnt/sfdriver.h @@ -4,7 +4,7 @@ /* */ /* High-level SFNT driver interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SFDRIVER_H__ -#define __SFDRIVER_H__ +#ifndef SFDRIVER_H_ +#define SFDRIVER_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SFDRIVER_H__ */ +#endif /* SFDRIVER_H_ */ /* END */ diff --git a/third_party/freetype/src/sfnt/sferrors.h b/third_party/freetype/src/sfnt/sferrors.h index e3bef3f743..3cf73d725d 100644 --- a/third_party/freetype/src/sfnt/sferrors.h +++ b/third_party/freetype/src/sfnt/sferrors.h @@ -4,7 +4,7 @@ /* */ /* SFNT error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __SFERRORS_H__ -#define __SFERRORS_H__ +#ifndef SFERRORS_H_ +#define SFERRORS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX SFNT_Err_ @@ -35,6 +35,7 @@ #include FT_ERRORS_H -#endif /* __SFERRORS_H__ */ +#endif /* SFERRORS_H_ */ + /* END */ diff --git a/third_party/freetype/src/sfnt/sfnt.c b/third_party/freetype/src/sfnt/sfnt.c index 0b8b5f4578..cffda6e6db 100644 --- a/third_party/freetype/src/sfnt/sfnt.c +++ b/third_party/freetype/src/sfnt/sfnt.c @@ -4,7 +4,7 @@ /* */ /* Single object library component. */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/sfntpic.c b/third_party/freetype/src/sfnt/sfntpic.c index 2aaf4bcc40..8eadd601fd 100644 --- a/third_party/freetype/src/sfnt/sfntpic.c +++ b/third_party/freetype/src/sfnt/sfntpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for sfnt module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/sfntpic.h b/third_party/freetype/src/sfnt/sfntpic.h index d99be6a824..3afb668db0 100644 --- a/third_party/freetype/src/sfnt/sfntpic.h +++ b/third_party/freetype/src/sfnt/sfntpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for sfnt module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SFNTPIC_H__ -#define __SFNTPIC_H__ +#ifndef SFNTPIC_H_ +#define SFNTPIC_H_ #include FT_INTERNAL_PIC_H @@ -106,7 +106,7 @@ FT_END_HEADER /* */ -#endif /* __SFNTPIC_H__ */ +#endif /* SFNTPIC_H_ */ /* END */ diff --git a/third_party/freetype/src/sfnt/sfobjs.c b/third_party/freetype/src/sfnt/sfobjs.c index 14d3adef21..8ac868dd71 100644 --- a/third_party/freetype/src/sfnt/sfobjs.c +++ b/third_party/freetype/src/sfnt/sfobjs.c @@ -4,7 +4,7 @@ /* */ /* SFNT object management (base). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -28,6 +28,12 @@ #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_SFNT_NAMES_H #include FT_GZIP_H + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_METRICS_VARIATIONS_H +#endif + #include "sferrors.h" #ifdef TT_CONFIG_OPTION_BDF @@ -254,7 +260,7 @@ if ( rec && convert ) { - if ( rec->string == NULL ) + if ( !rec->string ) { FT_Stream stream = face->name_table.stream; @@ -451,10 +457,14 @@ woff.metaOrigLength != 0 ) ) || ( woff.metaLength != 0 && woff.metaOrigLength == 0 ) || ( woff.privOffset == 0 && woff.privLength != 0 ) ) + { + FT_ERROR(( "woff_font_open: invalid WOFF header\n" )); return FT_THROW( Invalid_Table ); + } - if ( FT_ALLOC( sfnt, woff.totalSfntSize ) || - FT_NEW( sfnt_stream ) ) + /* Don't trust `totalSfntSize' before thorough checks. */ + if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) || + FT_NEW( sfnt_stream ) ) goto Exit; sfnt_header = sfnt; @@ -521,6 +531,8 @@ if ( table->Tag <= old_tag ) { FT_FRAME_EXIT(); + + FT_ERROR(( "woff_font_open: table tags are not sorted\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } @@ -555,6 +567,7 @@ sfnt_offset > woff.totalSfntSize - table->OrigLength || table->CompLength > table->OrigLength ) { + FT_ERROR(( "woff_font_open: invalid table offsets\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } @@ -580,6 +593,8 @@ if ( woff.metaOffset != woff_offset || woff.metaOffset + woff.metaLength > woff.length ) { + FT_ERROR(( "woff_font_open:" + " invalid `metadata' offset or length\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } @@ -596,6 +611,7 @@ if ( woff.privOffset != woff_offset || woff.privOffset + woff.privLength > woff.length ) { + FT_ERROR(( "woff_font_open: invalid `private' offset or length\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } @@ -607,10 +623,19 @@ if ( sfnt_offset != woff.totalSfntSize || woff_offset != woff.length ) { + FT_ERROR(( "woff_font_open: invalid `sfnt' table structure\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } + /* Now use `totalSfntSize'. */ + if ( FT_REALLOC( sfnt, + 12 + woff.num_tables * 16UL, + woff.totalSfntSize ) ) + goto Exit; + + sfnt_header = sfnt + 12; + /* Write the tables. */ for ( nn = 0; nn < woff.num_tables; nn++ ) @@ -651,6 +676,7 @@ goto Exit; if ( output_len != table->OrigLength ) { + FT_ERROR(( "woff_font_open: compressed table length mismatch\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } @@ -778,6 +804,9 @@ if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) ) return error; + FT_TRACE3(( " with %ld subfonts\n", + face->ttc_header.count )); + if ( face->ttc_header.count == 0 ) return FT_THROW( Invalid_Table ); @@ -852,6 +881,21 @@ FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS ); +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + if ( !face->mm ) + { + /* we want the MM interface from the `truetype' module only */ + FT_Module tt_module = FT_Get_Module( library, "truetype" ); + + + face->mm = ft_module_get_service( tt_module, + FT_SERVICE_ID_MULTI_MASTERS, + 0 ); + } + + FT_FACE_FIND_GLOBAL_SERVICE( face, face->var, METRICS_VARIATIONS ); +#endif + FT_TRACE2(( "SFNT driver\n" )); error = sfnt_open_font( stream, face ); @@ -861,10 +905,14 @@ /* Stream may have changed in sfnt_open_font. */ stream = face->root.stream; - FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_instance_index )); + FT_TRACE2(( "sfnt_init_face: %08p, %d\n", face, face_instance_index )); face_index = FT_ABS( face_instance_index ) & 0xFFFF; + /* value -(N+1) requests information on index N */ + if ( face_instance_index < 0 ) + face_index--; + if ( face_index >= face->ttc_header.count ) { if ( face_instance_index >= 0 ) @@ -883,18 +931,66 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT { - FT_ULong fvar_len; + FT_ULong fvar_len; + + FT_ULong version; + FT_ULong offset; + + FT_UShort num_axes; + FT_UShort axis_size; FT_UShort num_instances; - FT_Int instance_index; + FT_UShort instance_size; + + FT_Int instance_index; + face->is_default_instance = 1; + instance_index = FT_ABS( face_instance_index ) >> 16; /* test whether current face is a GX font with named instances */ if ( face->goto_table( face, TTAG_fvar, stream, &fvar_len ) || fvar_len < 20 || - FT_STREAM_SKIP( 12 ) || - FT_READ_USHORT( num_instances ) ) + FT_READ_ULONG( version ) || + FT_READ_USHORT( offset ) || + FT_STREAM_SKIP( 2 ) /* count_size_pairs */ || + FT_READ_USHORT( num_axes ) || + FT_READ_USHORT( axis_size ) || + FT_READ_USHORT( num_instances ) || + FT_READ_USHORT( instance_size ) ) + { + version = 0; + offset = 0; + num_axes = 0; + axis_size = 0; + num_instances = 0; + instance_size = 0; + } + + /* check that the data is bound by the table length */ + if ( version != 0x00010000UL || +#if 0 + /* fonts like `JamRegular.ttf' have an incorrect value for */ + /* `count_size_pairs'; since value 2 is hard-coded in `fvar' */ + /* version 1.0, we simply ignore it */ + count_size_pairs != 2 || +#endif + axis_size != 20 || + num_axes == 0 || + /* `num_axes' limit implied by 16-bit `instance_size' */ + num_axes > 0x3FFE || + !( instance_size == 4 + 4 * num_axes || + instance_size == 6 + 4 * num_axes ) || + num_instances > 0x7EFF || + offset + + axis_size * num_axes + + instance_size * num_instances > fvar_len ) + num_instances = 0; + else + face->variation_support |= TT_FACE_FLAG_VAR_FVAR; + + /* we don't support Multiple Master CFFs yet */ + if ( !face->goto_table( face, TTAG_CFF, stream, 0 ) ) num_instances = 0; /* we support at most 2^15 - 1 instances */ @@ -921,7 +1017,7 @@ #endif face->root.num_faces = face->ttc_header.count; - face->root.face_index = face_index; + face->root.face_index = face_instance_index; return error; } @@ -1027,12 +1123,14 @@ /* do we have outlines in there? */ #ifdef FT_CONFIG_OPTION_INCREMENTAL - has_outline = FT_BOOL( face->root.internal->incremental_interface != 0 || - tt_face_lookup_table( face, TTAG_glyf ) != 0 || - tt_face_lookup_table( face, TTAG_CFF ) != 0 ); + has_outline = FT_BOOL( face->root.internal->incremental_interface || + tt_face_lookup_table( face, TTAG_glyf ) || + tt_face_lookup_table( face, TTAG_CFF ) || + tt_face_lookup_table( face, TTAG_CFF2 ) ); #else - has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 || - tt_face_lookup_table( face, TTAG_CFF ) != 0 ); + has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) || + tt_face_lookup_table( face, TTAG_CFF ) || + tt_face_lookup_table( face, TTAG_CFF2 ) ); #endif is_apple_sbit = 0; @@ -1164,30 +1262,10 @@ /* embedded bitmap support */ if ( sfnt->load_eblc ) - { LOAD_( eblc ); - if ( error ) - { - /* a font which contains neither bitmaps nor outlines is */ - /* still valid (although rather useless in most cases); */ - /* however, you can find such stripped fonts in PDFs */ - if ( FT_ERR_EQ( error, Table_Missing ) ) - error = FT_Err_Ok; - else - goto Exit; - } - } + /* consider the pclt, kerning, and gasp tables as optional */ LOAD_( pclt ); - if ( error ) - { - if ( FT_ERR_NEQ( error, Table_Missing ) ) - goto Exit; - - face->pclt.Version = 0; - } - - /* consider the kerning and gasp tables as optional */ LOAD_( gasp ); LOAD_( kern ); @@ -1271,10 +1349,14 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT /* Don't bother to load the tables unless somebody asks for them. */ /* No need to do work which will (probably) not be used. */ - if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 && - tt_face_lookup_table( face, TTAG_fvar ) != 0 && - tt_face_lookup_table( face, TTAG_gvar ) != 0 ) - flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; + if ( face->variation_support & TT_FACE_FLAG_VAR_FVAR ) + { + if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 && + tt_face_lookup_table( face, TTAG_gvar ) != 0 ) + flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; + if ( tt_face_lookup_table( face, TTAG_CFF2 ) != 0 ) + flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; + } #endif root->face_flags = flags; @@ -1337,7 +1419,7 @@ charmap->encoding_id ); #if 0 - if ( root->charmap == NULL && + if ( !root->charmap && charmap->encoding == FT_ENCODING_UNICODE ) { /* set 'root->charmap' to the first Unicode encoding we find */ @@ -1355,7 +1437,7 @@ * depths in the FT_Bitmap_Size record. This is a design error. */ { - FT_UInt i, count; + FT_UInt count; count = face->sbit_num_strikes; @@ -1367,6 +1449,9 @@ FT_Short avgwidth = face->os2.xAvgCharWidth; FT_Size_Metrics metrics; + FT_UInt* sbit_strike_map = NULL; + FT_UInt strike_idx, bsize_idx; + if ( em_size == 0 || face->os2.version == 0xFFFFU ) { @@ -1374,31 +1459,50 @@ em_size = 1; } - if ( FT_NEW_ARRAY( root->available_sizes, count ) ) + /* to avoid invalid strike data in the `available_sizes' field */ + /* of `FT_Face', we map `available_sizes' indices to strike */ + /* indices */ + if ( FT_NEW_ARRAY( root->available_sizes, count ) || + FT_NEW_ARRAY( sbit_strike_map, count ) ) goto Exit; - for ( i = 0; i < count; i++ ) + bsize_idx = 0; + for ( strike_idx = 0; strike_idx < count; strike_idx++ ) { - FT_Bitmap_Size* bsize = root->available_sizes + i; + FT_Bitmap_Size* bsize = root->available_sizes + bsize_idx; - error = sfnt->load_strike_metrics( face, i, &metrics ); + error = sfnt->load_strike_metrics( face, strike_idx, &metrics ); if ( error ) - goto Exit; + continue; bsize->height = (FT_Short)( metrics.height >> 6 ); - bsize->width = (FT_Short)( - ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size ); + bsize->width = (FT_Short)( + ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size ); bsize->x_ppem = metrics.x_ppem << 6; bsize->y_ppem = metrics.y_ppem << 6; /* assume 72dpi */ bsize->size = metrics.y_ppem << 6; + + /* only use strikes with valid PPEM values */ + if ( bsize->x_ppem && bsize->y_ppem ) + sbit_strike_map[bsize_idx++] = strike_idx; } - root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; - root->num_fixed_sizes = (FT_Int)count; + /* reduce array size to the actually used elements */ + (void)FT_RENEW_ARRAY( sbit_strike_map, count, bsize_idx ); + + /* from now on, all strike indices are mapped */ + /* using `sbit_strike_map' */ + if ( bsize_idx ) + { + face->sbit_strike_map = sbit_strike_map; + + root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; + root->num_fixed_sizes = (FT_Int)bsize_idx; + } } } @@ -1559,18 +1663,10 @@ face->cmap_size = 0; } - /* freeing the horizontal metrics */ - { - FT_Stream stream = FT_FACE_STREAM( face ); - - - FT_FRAME_RELEASE( face->horz_metrics ); - FT_FRAME_RELEASE( face->vert_metrics ); - face->horz_metrics_size = 0; - face->vert_metrics_size = 0; - } + face->horz_metrics_size = 0; + face->vert_metrics_size = 0; - /* freeing the vertical ones, if any */ + /* freeing vertical metrics, if any */ if ( face->vertical_info ) { FT_FREE( face->vertical.long_metrics ); @@ -1592,6 +1688,7 @@ /* freeing sbit size table */ FT_FREE( face->root.available_sizes ); + FT_FREE( face->sbit_strike_map ); face->root.num_fixed_sizes = 0; FT_FREE( face->postscript_name ); diff --git a/third_party/freetype/src/sfnt/sfobjs.h b/third_party/freetype/src/sfnt/sfobjs.h index 455f86772f..705381459a 100644 --- a/third_party/freetype/src/sfnt/sfobjs.h +++ b/third_party/freetype/src/sfnt/sfobjs.h @@ -4,7 +4,7 @@ /* */ /* SFNT object management (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SFOBJS_H__ -#define __SFOBJS_H__ +#ifndef SFOBJS_H_ +#define SFOBJS_H_ #include <ft2build.h> @@ -53,7 +53,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SFDRIVER_H__ */ +#endif /* SFDRIVER_H_ */ /* END */ diff --git a/third_party/freetype/src/sfnt/ttcmap.c b/third_party/freetype/src/sfnt/ttcmap.c index c4d9abdfe6..5afa6ae4b7 100644 --- a/third_party/freetype/src/sfnt/ttcmap.c +++ b/third_party/freetype/src/sfnt/ttcmap.c @@ -4,7 +4,7 @@ /* */ /* TrueType character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -180,22 +180,24 @@ FT_DEFINE_TT_CMAP( tt_cmap0_class_rec, - sizeof ( TT_CMapRec ), - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap0_char_index, - (FT_CMap_CharNextFunc) tt_cmap0_char_next, + sizeof ( TT_CMapRec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap0_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap0_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 0, - (TT_CMap_ValidateFunc)tt_cmap0_validate, - (TT_CMap_Info_GetFunc)tt_cmap0_get_info ) + (TT_CMap_ValidateFunc)tt_cmap0_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap0_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_0 */ @@ -571,22 +573,24 @@ FT_DEFINE_TT_CMAP( tt_cmap2_class_rec, - sizeof ( TT_CMapRec ), - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap2_char_index, - (FT_CMap_CharNextFunc) tt_cmap2_char_next, + sizeof ( TT_CMapRec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap2_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap2_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 2, - (TT_CMap_ValidateFunc)tt_cmap2_validate, - (TT_CMap_Info_GetFunc)tt_cmap2_get_info ) + (TT_CMap_ValidateFunc)tt_cmap2_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap2_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_2 */ @@ -763,6 +767,9 @@ static void tt_cmap4_next( TT_CMap4 cmap ) { + TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + FT_UInt charcode; @@ -774,7 +781,7 @@ if ( charcode < cmap->cur_start ) charcode = cmap->cur_start; - for ( ;; ) + for (;;) { FT_Byte* values = cmap->cur_values; FT_UInt end = cmap->cur_end; @@ -788,15 +795,19 @@ FT_Byte* p = values + 2 * ( charcode - cmap->cur_start ); + /* if p > limit, the whole segment is invalid */ + if ( p > limit ) + goto Next_Segment; + do { FT_UInt gindex = FT_NEXT_USHORT( p ); - if ( gindex != 0 ) + if ( gindex ) { gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; - if ( gindex != 0 ) + if ( gindex ) { cmap->cur_charcode = charcode; cmap->cur_gindex = gindex; @@ -812,7 +823,26 @@ FT_UInt gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; - if ( gindex != 0 ) + if ( gindex >= (FT_UInt)face->root.num_glyphs ) + { + /* we have an invalid glyph index; if there is an overflow, */ + /* we can adjust `charcode', otherwise the whole segment is */ + /* invalid */ + gindex = 0; + + if ( (FT_Int)charcode + delta < 0 && + (FT_Int)end + delta >= 0 ) + charcode = (FT_UInt)( -delta ); + + else if ( (FT_Int)charcode + delta < 0x10000L && + (FT_Int)end + delta >= 0x10000L ) + charcode = (FT_UInt)( 0x10000L - delta ); + + else + goto Next_Segment; + } + + if ( gindex ) { cmap->cur_charcode = charcode; cmap->cur_gindex = gindex; @@ -822,6 +852,7 @@ } } + Next_Segment: /* we need to find another range */ if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 ) break; @@ -1170,6 +1201,9 @@ FT_UInt32* pcharcode, FT_Bool next ) { + TT_Face face = (TT_Face)cmap->cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + FT_UInt num_segs2, start, end, offset; FT_Int delta; FT_UInt max, min, mid, num_segs; @@ -1221,10 +1255,6 @@ if ( mid >= num_segs - 1 && start == 0xFFFFU && end == 0xFFFFU ) { - TT_Face face = (TT_Face)cmap->cmap.charmap.face; - FT_Byte* limit = face->cmap_table + face->cmap_size; - - if ( offset && p + offset + 2 > limit ) { delta = 1; @@ -1245,7 +1275,7 @@ mid = max + 1; /* search in segments before the current segment */ - for ( i = max ; i > 0; i-- ) + for ( i = max; i > 0; i-- ) { FT_UInt prev_end; FT_Byte* old_p; @@ -1347,13 +1377,40 @@ if ( offset ) { p += offset + ( charcode - start ) * 2; + + /* if p > limit, the whole segment is invalid */ + if ( next && p > limit ) + break; + gindex = TT_PEEK_USHORT( p ); - if ( gindex != 0 ) + if ( gindex ) + { gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; + if ( gindex >= (FT_UInt)face->root.num_glyphs ) + gindex = 0; + } } else + { gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; + if ( next && gindex >= (FT_UInt)face->root.num_glyphs ) + { + /* we have an invalid glyph index; if there is an overflow, */ + /* we can adjust `charcode', otherwise the whole segment is */ + /* invalid */ + gindex = 0; + + if ( (FT_Int)charcode + delta < 0 && + (FT_Int)end + delta >= 0 ) + charcode = (FT_UInt)( -delta ); + + else if ( (FT_Int)charcode + delta < 0x10000L && + (FT_Int)end + delta >= 0x10000L ) + charcode = (FT_UInt)( 0x10000L - delta ); + } + } + break; } } @@ -1463,21 +1520,24 @@ FT_DEFINE_TT_CMAP( tt_cmap4_class_rec, - sizeof ( TT_CMap4Rec ), - (FT_CMap_InitFunc) tt_cmap4_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap4_char_index, - (FT_CMap_CharNextFunc) tt_cmap4_char_next, - NULL, - NULL, - NULL, - NULL, - NULL, + sizeof ( TT_CMap4Rec ), + + (FT_CMap_InitFunc) tt_cmap4_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap4_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap4_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 4, - (TT_CMap_ValidateFunc)tt_cmap4_validate, - (TT_CMap_Info_GetFunc)tt_cmap4_get_info ) + (TT_CMap_ValidateFunc)tt_cmap4_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap4_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_4 */ @@ -1630,22 +1690,24 @@ FT_DEFINE_TT_CMAP( tt_cmap6_class_rec, - sizeof ( TT_CMapRec ), - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap6_char_index, - (FT_CMap_CharNextFunc) tt_cmap6_char_next, + sizeof ( TT_CMapRec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap6_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap6_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 6, - (TT_CMap_ValidateFunc)tt_cmap6_validate, - (TT_CMap_Info_GetFunc)tt_cmap6_get_info ) + (TT_CMap_ValidateFunc)tt_cmap6_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap6_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_6 */ @@ -1891,7 +1953,10 @@ /* if `gindex' is invalid, the remaining values */ /* in this group are invalid, too */ if ( gindex >= (FT_UInt)face->num_glyphs ) + { + gindex = 0; continue; + } result = char_code; break; @@ -1919,22 +1984,24 @@ FT_DEFINE_TT_CMAP( tt_cmap8_class_rec, - sizeof ( TT_CMapRec ), - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap8_char_index, - (FT_CMap_CharNextFunc) tt_cmap8_char_next, + sizeof ( TT_CMapRec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap8_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap8_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 8, - (TT_CMap_ValidateFunc)tt_cmap8_validate, - (TT_CMap_Info_GetFunc)tt_cmap8_get_info ) + (TT_CMap_ValidateFunc)tt_cmap8_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap8_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_8 */ @@ -2089,22 +2156,24 @@ FT_DEFINE_TT_CMAP( tt_cmap10_class_rec, - sizeof ( TT_CMapRec ), - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap10_char_index, - (FT_CMap_CharNextFunc) tt_cmap10_char_next, + sizeof ( TT_CMapRec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap10_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap10_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 10, - (TT_CMap_ValidateFunc)tt_cmap10_validate, - (TT_CMap_Info_GetFunc)tt_cmap10_get_info ) + (TT_CMap_ValidateFunc)tt_cmap10_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap10_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_10 */ @@ -2277,7 +2346,10 @@ /* if `gindex' is invalid, the remaining values */ /* in this group are invalid, too */ if ( gindex >= (FT_UInt)face->num_glyphs ) + { + gindex = 0; continue; + } cmap->cur_charcode = char_code; cmap->cur_gindex = gindex; @@ -2440,22 +2512,24 @@ FT_DEFINE_TT_CMAP( tt_cmap12_class_rec, - sizeof ( TT_CMap12Rec ), - (FT_CMap_InitFunc) tt_cmap12_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap12_char_index, - (FT_CMap_CharNextFunc) tt_cmap12_char_next, + sizeof ( TT_CMap12Rec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap12_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap12_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap12_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 12, - (TT_CMap_ValidateFunc)tt_cmap12_validate, - (TT_CMap_Info_GetFunc)tt_cmap12_get_info ) + (TT_CMap_ValidateFunc)tt_cmap12_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap12_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_12 */ @@ -2764,22 +2838,24 @@ FT_DEFINE_TT_CMAP( tt_cmap13_class_rec, - sizeof ( TT_CMap13Rec ), - (FT_CMap_InitFunc) tt_cmap13_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap13_char_index, - (FT_CMap_CharNextFunc) tt_cmap13_char_next, + sizeof ( TT_CMap13Rec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap13_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap13_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap13_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 13, - (TT_CMap_ValidateFunc)tt_cmap13_validate, - (TT_CMap_Info_GetFunc)tt_cmap13_get_info ) + (TT_CMap_ValidateFunc)tt_cmap13_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap13_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_13 */ @@ -2870,7 +2946,7 @@ cmap->max_results = 0; - if ( memory != NULL && cmap->results != NULL ) + if ( memory && cmap->results ) FT_FREE( cmap->results ); } @@ -2962,17 +3038,22 @@ /* through the normal Unicode cmap, no GIDs, just check order) */ if ( defOff != 0 ) { - FT_Byte* defp = table + defOff; - FT_ULong numRanges = TT_NEXT_ULONG( defp ); + FT_Byte* defp = table + defOff; + FT_ULong numRanges; FT_ULong i; - FT_ULong lastBase = 0; + FT_ULong lastBase = 0; + if ( defp + 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + numRanges = TT_NEXT_ULONG( defp ); + /* defp + numRanges * 4 > valid->limit ? */ if ( numRanges > (FT_ULong)( valid->limit - defp ) / 4 ) FT_INVALID_TOO_SHORT; - for ( i = 0; i < numRanges; ++i ) + for ( i = 0; i < numRanges; i++ ) { FT_ULong base = TT_NEXT_UINT24( defp ); FT_ULong cnt = FT_NEXT_BYTE( defp ); @@ -2991,16 +3072,21 @@ /* and the non-default table (these glyphs are specified here) */ if ( nondefOff != 0 ) { - FT_Byte* ndp = table + nondefOff; - FT_ULong numMappings = TT_NEXT_ULONG( ndp ); - FT_ULong i, lastUni = 0; + FT_Byte* ndp = table + nondefOff; + FT_ULong numMappings; + FT_ULong i, lastUni = 0; + + if ( ndp + 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + numMappings = TT_NEXT_ULONG( ndp ); - /* numMappings * 4 > (FT_ULong)( valid->limit - ndp ) ? */ - if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 4 ) + /* numMappings * 5 > (FT_ULong)( valid->limit - ndp ) ? */ + if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 5 ) FT_INVALID_TOO_SHORT; - for ( i = 0; i < numMappings; ++i ) + for ( i = 0; i < numMappings; i++ ) { FT_ULong uni = TT_NEXT_UINT24( ndp ); FT_ULong gid = TT_NEXT_USHORT( ndp ); @@ -3088,7 +3174,7 @@ if ( char_code < start ) max = mid; - else if ( char_code > start+cnt ) + else if ( char_code > start + cnt ) min = mid + 1; else return TRUE; @@ -3241,7 +3327,7 @@ return NULL; result = cmap14->results; - for ( i = 0; i < count; ++i ) + for ( i = 0; i < count; i++ ) { result[i] = (FT_UInt32)TT_NEXT_UINT24( p ); p += 8; @@ -3266,7 +3352,7 @@ if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) return NULL; - for ( q = cmap14->results; count > 0; --count ) + for ( q = cmap14->results; count > 0; count-- ) { FT_UInt32 varSel = TT_NEXT_UINT24( p ); FT_ULong defOff = TT_NEXT_ULONG( p ); @@ -3325,7 +3411,7 @@ if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) ) return NULL; - for ( q = cmap14->results; numRanges > 0; --numRanges ) + for ( q = cmap14->results; numRanges > 0; numRanges-- ) { FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); @@ -3362,7 +3448,7 @@ return NULL; ret = cmap14->results; - for ( i = 0; i < numMappings; ++i ) + for ( i = 0; i < numMappings; i++ ) { ret[i] = (FT_UInt32)TT_NEXT_UINT24( p ); p += 2; @@ -3442,14 +3528,14 @@ ni = 1; i = 0; - for ( ;; ) + for (;;) { if ( nuni > duni + dcnt ) { - for ( k = 0; k <= dcnt; ++k ) + for ( k = 0; k <= dcnt; k++ ) ret[i++] = duni + k; - ++di; + di++; if ( di > numRanges ) break; @@ -3463,7 +3549,7 @@ ret[i++] = nuni; /* If it is within the default range then ignore it -- */ /* that should not have happened */ - ++ni; + ni++; if ( ni > numMappings ) break; @@ -3482,7 +3568,7 @@ { ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p ); p += 2; - ++ni; + ni++; } } else if ( di <= numRanges ) @@ -3490,7 +3576,7 @@ /* If we get here then we have run out of all non-default */ /* mappings. We have read one default range which we haven't */ /* stored and there may be others that need to be read. */ - for ( k = 0; k <= dcnt; ++k ) + for ( k = 0; k <= dcnt; k++ ) ret[i++] = duni + k; while ( di < numRanges ) @@ -3498,9 +3584,9 @@ duni = (FT_UInt32)TT_NEXT_UINT24( dp ); dcnt = FT_NEXT_BYTE( dp ); - for ( k = 0; k <= dcnt; ++k ) + for ( k = 0; k <= dcnt; k++ ) ret[i++] = duni + k; - ++di; + di++; } } @@ -3513,23 +3599,25 @@ FT_DEFINE_TT_CMAP( tt_cmap14_class_rec, - sizeof ( TT_CMap14Rec ), - (FT_CMap_InitFunc) tt_cmap14_init, - (FT_CMap_DoneFunc) tt_cmap14_done, - (FT_CMap_CharIndexFunc)tt_cmap14_char_index, - (FT_CMap_CharNextFunc) tt_cmap14_char_next, + sizeof ( TT_CMap14Rec ), + + (FT_CMap_InitFunc) tt_cmap14_init, /* init */ + (FT_CMap_DoneFunc) tt_cmap14_done, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap14_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap14_char_next, /* char_next */ - /* Format 14 extension functions */ - (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index, - (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault, - (FT_CMap_VariantListFunc) tt_cmap14_variants, - (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants, - (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars, + /* Format 14 extension functions */ + (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index, + (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault, + (FT_CMap_VariantListFunc) tt_cmap14_variants, + (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants, + (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars, 14, - (TT_CMap_ValidateFunc)tt_cmap14_validate, - (TT_CMap_Info_GetFunc)tt_cmap14_get_info ) + (TT_CMap_ValidateFunc)tt_cmap14_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap14_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_14 */ @@ -3668,7 +3756,7 @@ error = clazz->validate( cmap, FT_VALIDATOR( &valid ) ); } - if ( valid.validator.error == 0 ) + if ( !valid.validator.error ) { FT_CMap ttcmap; @@ -3694,7 +3782,7 @@ } } - if ( *pclazz == NULL ) + if ( !*pclazz ) { FT_TRACE0(( "tt_face_build_cmaps:" " unsupported cmap sub-table ignored\n" )); diff --git a/third_party/freetype/src/sfnt/ttcmap.h b/third_party/freetype/src/sfnt/ttcmap.h index b7ea8ee377..83f12df241 100644 --- a/third_party/freetype/src/sfnt/ttcmap.h +++ b/third_party/freetype/src/sfnt/ttcmap.h @@ -4,7 +4,7 @@ /* */ /* TrueType character mapping table (cmap) support (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTCMAP_H__ -#define __TTCMAP_H__ +#ifndef TTCMAP_H_ +#define TTCMAP_H_ #include <ft2build.h> @@ -152,7 +152,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTCMAP_H__ */ +#endif /* TTCMAP_H_ */ /* END */ diff --git a/third_party/freetype/src/sfnt/ttcmapc.h b/third_party/freetype/src/sfnt/ttcmapc.h index 4a489402cf..9a5e70825e 100644 --- a/third_party/freetype/src/sfnt/ttcmapc.h +++ b/third_party/freetype/src/sfnt/ttcmapc.h @@ -4,7 +4,7 @@ /* */ /* TT CMAP classes definitions (specification only). */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/ttkern.c b/third_party/freetype/src/sfnt/ttkern.c index 4fccc535ce..78dc5eb87a 100644 --- a/third_party/freetype/src/sfnt/ttkern.c +++ b/third_party/freetype/src/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-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/ttkern.h b/third_party/freetype/src/sfnt/ttkern.h index 89cb24f07c..db1a30bdb0 100644 --- a/third_party/freetype/src/sfnt/ttkern.h +++ b/third_party/freetype/src/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-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTKERN_H__ -#define __TTKERN_H__ +#ifndef TTKERN_H_ +#define TTKERN_H_ #include <ft2build.h> @@ -46,7 +46,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTKERN_H__ */ +#endif /* TTKERN_H_ */ /* END */ diff --git a/third_party/freetype/src/sfnt/ttload.c b/third_party/freetype/src/sfnt/ttload.c index c1bd7f0c82..53837c7c10 100644 --- a/third_party/freetype/src/sfnt/ttload.c +++ b/third_party/freetype/src/sfnt/ttload.c @@ -5,7 +5,7 @@ /* Load the basic TrueType tables, i.e., tables that can be either in */ /* TTF or OTF fonts (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -679,7 +679,7 @@ /*************************************************************************/ /* */ /* <Function> */ - /* tt_face_load_max_profile */ + /* tt_face_load_maxp */ /* */ /* <Description> */ /* Loads the maximum profile into a face object. */ @@ -775,15 +775,6 @@ maxProfile->maxTwilightPoints = 0xFFFFU - 4; } - - /* we arbitrarily limit recursion to avoid stack exhaustion */ - if ( maxProfile->maxComponentDepth > 100 ) - { - FT_TRACE0(( "tt_face_load_maxp:" - " abnormally large component depth (%d) set to 100\n", - maxProfile->maxComponentDepth )); - maxProfile->maxComponentDepth = 100; - } } FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs )); @@ -1193,8 +1184,8 @@ #define FT_STRUCTURE TT_Postscript FT_FRAME_START( 32 ), - FT_FRAME_ULONG( FormatType ), - FT_FRAME_ULONG( italicAngle ), + FT_FRAME_LONG ( FormatType ), + FT_FRAME_LONG ( italicAngle ), FT_FRAME_SHORT( underlinePosition ), FT_FRAME_SHORT( underlineThickness ), FT_FRAME_ULONG( isFixedPitch ), diff --git a/third_party/freetype/src/sfnt/ttload.h b/third_party/freetype/src/sfnt/ttload.h index a6d91c5b70..296da86ed3 100644 --- a/third_party/freetype/src/sfnt/ttload.h +++ b/third_party/freetype/src/sfnt/ttload.h @@ -5,7 +5,7 @@ /* Load the basic TrueType tables, i.e., tables that can be either in */ /* TTF or OTF fonts (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTLOAD_H__ -#define __TTLOAD_H__ +#ifndef TTLOAD_H_ +#define TTLOAD_H_ #include <ft2build.h> @@ -106,7 +106,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTLOAD_H__ */ +#endif /* TTLOAD_H_ */ /* END */ diff --git a/third_party/freetype/src/sfnt/ttmtx.c b/third_party/freetype/src/sfnt/ttmtx.c index 58309aa496..f2e5541783 100644 --- a/third_party/freetype/src/sfnt/ttmtx.c +++ b/third_party/freetype/src/sfnt/ttmtx.c @@ -4,7 +4,7 @@ /* */ /* Load the metrics tables common to TTF and OTF fonts (body). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,11 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_SERVICE_METRICS_VARIATIONS_H +#endif + #include "ttmtx.h" #include "sferrors.h" @@ -214,6 +219,11 @@ FT_ULong table_pos, table_size, table_end; FT_UShort k; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Service_MetricsVariations var = + (FT_Service_MetricsVariations)face->var; +#endif + if ( vertical ) { @@ -274,6 +284,34 @@ *abearing = 0; *aadvance = 0; } + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + if ( var ) + { + FT_Face f = FT_FACE( face ); + FT_Int a = (FT_Int)*aadvance; + FT_Int b = (FT_Int)*abearing; + + + if ( vertical ) + { + if ( var->vadvance_adjust ) + var->vadvance_adjust( f, gindex, &a ); + if ( var->tsb_adjust ) + var->tsb_adjust( f, gindex, &b ); + } + else + { + if ( var->hadvance_adjust ) + var->hadvance_adjust( f, gindex, &a ); + if ( var->lsb_adjust ) + var->lsb_adjust( f, gindex, &b ); + } + + *aadvance = (FT_UShort)a; + *abearing = (FT_Short)b; + } +#endif } diff --git a/third_party/freetype/src/sfnt/ttmtx.h b/third_party/freetype/src/sfnt/ttmtx.h index 096ee062cf..2b93ab2f0e 100644 --- a/third_party/freetype/src/sfnt/ttmtx.h +++ b/third_party/freetype/src/sfnt/ttmtx.h @@ -4,7 +4,7 @@ /* */ /* Load the metrics tables common to TTF and OTF fonts (specification). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTMTX_H__ -#define __TTMTX_H__ +#ifndef TTMTX_H_ +#define TTMTX_H_ #include <ft2build.h> @@ -49,7 +49,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTMTX_H__ */ +#endif /* TTMTX_H_ */ /* END */ diff --git a/third_party/freetype/src/sfnt/ttpost.c b/third_party/freetype/src/sfnt/ttpost.c index 8d29d1e9f6..6548e85130 100644 --- a/third_party/freetype/src/sfnt/ttpost.c +++ b/third_party/freetype/src/sfnt/ttpost.c @@ -2,10 +2,10 @@ /* */ /* ttpost.c */ /* */ -/* Postcript name table processing for TrueType and OpenType fonts */ +/* PostScript name table processing for TrueType and OpenType fonts */ /* (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -326,7 +326,9 @@ goto Exit; /* check the number of glyphs */ - if ( num_glyphs > face->max_profile.numGlyphs || num_glyphs > 258 ) + if ( num_glyphs > face->max_profile.numGlyphs || + num_glyphs > 258 || + num_glyphs < 1 ) { error = FT_THROW( Invalid_File_Format ); goto Exit; diff --git a/third_party/freetype/src/sfnt/ttpost.h b/third_party/freetype/src/sfnt/ttpost.h index e3eca02c62..722485e32d 100644 --- a/third_party/freetype/src/sfnt/ttpost.h +++ b/third_party/freetype/src/sfnt/ttpost.h @@ -2,10 +2,10 @@ /* */ /* ttpost.h */ /* */ -/* Postcript name table processing for TrueType and OpenType fonts */ +/* PostScript name table processing for TrueType and OpenType fonts */ /* (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTPOST_H__ -#define __TTPOST_H__ +#ifndef TTPOST_H_ +#define TTPOST_H_ #include <ft2build.h> @@ -40,7 +40,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTPOST_H__ */ +#endif /* TTPOST_H_ */ /* END */ diff --git a/third_party/freetype/src/smooth/ftgrays.c b/third_party/freetype/src/smooth/ftgrays.c index ba2944559c..9982f72a42 100644 --- a/third_party/freetype/src/smooth/ftgrays.c +++ b/third_party/freetype/src/smooth/ftgrays.c @@ -4,7 +4,7 @@ /* */ /* A new `perfect' anti-aliasing renderer (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,7 +18,7 @@ /*************************************************************************/ /* */ /* This file can be compiled without the rest of the FreeType engine, by */ - /* defining the _STANDALONE_ macro when compiling it. You also need to */ + /* defining the STANDALONE_ macro when compiling it. You also need to */ /* put the files `ftgrays.h' and `ftimage.h' into the current */ /* compilation directory. Typically, you could do something like */ /* */ @@ -27,9 +27,9 @@ /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */ /* same directory */ /* */ - /* - compile `ftgrays' with the _STANDALONE_ macro defined, as in */ + /* - compile `ftgrays' with the STANDALONE_ macro defined, as in */ /* */ - /* cc -c -D_STANDALONE_ ftgrays.c */ + /* cc -c -DSTANDALONE_ ftgrays.c */ /* */ /* The renderer can be initialized with a call to */ /* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated */ @@ -91,7 +91,7 @@ #define FT_COMPONENT trace_smooth -#ifdef _STANDALONE_ +#ifdef STANDALONE_ /* The size in bytes of the render pool used by the scan-line converter */ @@ -106,6 +106,7 @@ #define FT_BEGIN_STMNT do { #define FT_END_STMNT } while ( 0 ) +#define FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) ) #define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) #define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) ) @@ -135,8 +136,10 @@ #include <string.h> #include <setjmp.h> #include <limits.h> -#define FT_UINT_MAX UINT_MAX -#define FT_INT_MAX INT_MAX +#define FT_CHAR_BIT CHAR_BIT +#define FT_UINT_MAX UINT_MAX +#define FT_INT_MAX INT_MAX +#define FT_ULONG_MAX ULONG_MAX #define ft_memset memset @@ -254,7 +257,7 @@ typedef ptrdiff_t FT_PtrDist; }; -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ #include <ft2build.h> @@ -272,7 +275,7 @@ typedef ptrdiff_t FT_PtrDist; #define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ #ifndef FT_MEM_SET @@ -283,6 +286,10 @@ typedef ptrdiff_t FT_PtrDist; #define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) #endif +#ifndef FT_ZERO +#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) +#endif + /* as usual, for the speed hungry :-) */ #undef RAS_ARG @@ -300,7 +307,7 @@ typedef ptrdiff_t FT_PtrDist; #else /* FT_STATIC_RASTER */ -#define RAS_ARG /* empty */ +#define RAS_ARG void #define RAS_ARG_ /* empty */ #define RAS_VAR /* empty */ #define RAS_VAR_ /* empty */ @@ -316,19 +323,19 @@ typedef ptrdiff_t FT_PtrDist; #undef TRUNC #undef SCALED -#define ONE_PIXEL ( 1L << PIXEL_BITS ) +#define ONE_PIXEL ( 1 << PIXEL_BITS ) #define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) ) -#define SUBPIXELS( x ) ( (TPos)(x) << PIXEL_BITS ) +#define SUBPIXELS( x ) ( (TPos)(x) * ONE_PIXEL ) #define FLOOR( x ) ( (x) & -ONE_PIXEL ) #define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) #define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL ) #if PIXEL_BITS >= 6 -#define UPSCALE( x ) ( (x) << ( PIXEL_BITS - 6 ) ) +#define UPSCALE( x ) ( (x) * ( ONE_PIXEL >> 6 ) ) #define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) ) #else #define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) ) -#define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) ) +#define DOWNSCALE( x ) ( (x) * ( 64 >> PIXEL_BITS ) ) #endif @@ -366,6 +373,16 @@ typedef ptrdiff_t FT_PtrDist; #endif /* __arm__ */ + /* These macros speed up repetitive divisions by replacing them */ + /* with multiplications and right shifts. */ +#define FT_UDIVPREP( c, b ) \ + long b ## _r = c ? (long)( FT_ULONG_MAX >> PIXEL_BITS ) / ( b ) \ + : 0 +#define FT_UDIV( a, b ) \ + ( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >> \ + ( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) ) + + /*************************************************************************/ /* */ /* TYPE DEFINITIONS */ @@ -375,44 +392,36 @@ typedef ptrdiff_t FT_PtrDist; /* need to define them to "float" or "double" when experimenting with */ /* new algorithms */ - typedef long TCoord; /* integer scanline/pixel coordinate */ typedef long TPos; /* sub-pixel coordinate */ - - /* determine the type used to store cell areas. This normally takes at */ - /* least PIXEL_BITS*2 + 1 bits. On 16-bit systems, we need to use */ - /* `long' instead of `int', otherwise bad things happen */ - -#if PIXEL_BITS <= 7 - - typedef int TArea; - -#else /* PIXEL_BITS >= 8 */ - - /* approximately determine the size of integers using an ANSI-C header */ -#if FT_UINT_MAX == 0xFFFFU - typedef long TArea; -#else - typedef int TArea; -#endif - -#endif /* PIXEL_BITS >= 8 */ - - - /* maximum number of gray spans in a call to the span callback */ -#define FT_MAX_GRAY_SPANS 32 + typedef int TCoord; /* integer scanline/pixel coordinate */ + typedef int TArea; /* cell areas, coordinate products */ typedef struct TCell_* PCell; typedef struct TCell_ { - TPos x; /* same with gray_TWorker.ex */ + TCoord x; /* same with gray_TWorker.ex */ TCoord cover; /* same with gray_TWorker.cover */ TArea area; PCell next; } TCell; + typedef struct TPixmap_ + { + unsigned char* origin; /* pixmap origin at the bottom-left */ + int pitch; /* pitch to go down one row */ + + } TPixmap; + + /* maximum number of gray cells in the buffer */ +#if FT_RENDER_POOL_SIZE > 2048 +#define FT_MAX_GRAY_POOL ( FT_RENDER_POOL_SIZE / sizeof ( TCell ) ) +#else +#define FT_MAX_GRAY_POOL ( 2048 / sizeof ( TCell ) ) +#endif + #if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ /* We disable the warning `structure was padded due to */ @@ -427,42 +436,25 @@ typedef ptrdiff_t FT_PtrDist; ft_jmp_buf jump_buffer; TCoord ex, ey; - TPos min_ex, max_ex; - TPos min_ey, max_ey; - TPos count_ex, count_ey; + TCoord min_ex, max_ex; + TCoord min_ey, max_ey; TArea area; TCoord cover; int invalid; + PCell* ycells; PCell cells; FT_PtrDist max_cells; FT_PtrDist num_cells; TPos x, y; - FT_Vector bez_stack[32 * 3 + 1]; - int lev_stack[32]; - FT_Outline outline; - FT_Bitmap target; - FT_BBox clip_box; - - FT_Span gray_spans[FT_MAX_GRAY_SPANS]; - int num_gray_spans; + TPixmap target; FT_Raster_Span_Func render_span; void* render_span_data; - int span_y; - - int band_size; - int band_shoot; - - void* buffer; - long buffer_size; - - PCell* ycells; - TPos ycount; } gray_TWorker, *gray_PWorker; @@ -485,95 +477,53 @@ typedef ptrdiff_t FT_PtrDist; } gray_TRaster, *gray_PRaster; +#ifdef FT_DEBUG_LEVEL_TRACE - /*************************************************************************/ - /* */ - /* Initialize the cells table. */ - /* */ - static void - gray_init_cells( RAS_ARG_ void* buffer, - long byte_size ) - { - 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; - } - - - /*************************************************************************/ - /* */ - /* Compute the outline bounding box. */ - /* */ + /* to be called while in the debugger -- */ + /* this function causes a compiler warning since it is unused otherwise */ static void - gray_compute_cbox( RAS_ARG ) + gray_dump_cells( RAS_ARG ) { - FT_Outline* outline = &ras.outline; - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + outline->n_points; + int y; - if ( outline->n_points <= 0 ) + for ( y = ras.min_ey; y < ras.max_ey; y++ ) { - ras.min_ex = ras.max_ex = 0; - ras.min_ey = ras.max_ey = 0; - return; - } + PCell cell = ras.ycells[y - ras.min_ey]; - ras.min_ex = ras.max_ex = vec->x; - ras.min_ey = ras.max_ey = vec->y; - vec++; + printf( "%3d:", y ); - for ( ; vec < limit; vec++ ) - { - TPos x = vec->x; - TPos y = vec->y; - - - if ( x < ras.min_ex ) ras.min_ex = x; - if ( x > ras.max_ex ) ras.max_ex = x; - if ( y < ras.min_ey ) ras.min_ey = y; - if ( y > ras.max_ey ) ras.max_ey = y; + for ( ; cell != NULL; cell = cell->next ) + printf( " (%3d, c:%4d, a:%6d)", + cell->x, cell->cover, cell->area ); + printf( "\n" ); } - - /* truncate the bounding box to integer pixels */ - ras.min_ex = ras.min_ex >> 6; - ras.min_ey = ras.min_ey >> 6; - ras.max_ex = ( ras.max_ex + 63 ) >> 6; - ras.max_ey = ( ras.max_ey + 63 ) >> 6; } +#endif /* FT_DEBUG_LEVEL_TRACE */ + /*************************************************************************/ /* */ /* Record the current cell in the table. */ /* */ - static PCell - gray_find_cell( RAS_ARG ) + static void + gray_record_cell( RAS_ARG ) { PCell *pcell, cell; - TPos x = ras.ex; - + TCoord x = ras.ex; - if ( x > ras.count_ex ) - x = ras.count_ex; - pcell = &ras.ycells[ras.ey]; + pcell = &ras.ycells[ras.ey - ras.min_ey]; for (;;) { cell = *pcell; - if ( cell == NULL || cell->x > x ) + if ( !cell || cell->x > x ) break; if ( cell->x == x ) - goto Exit; + goto Found; pcell = &cell->next; } @@ -581,30 +531,21 @@ typedef ptrdiff_t FT_PtrDist; if ( ras.num_cells >= ras.max_cells ) ft_longjmp( ras.jump_buffer, 1 ); + /* insert new cell */ cell = ras.cells + ras.num_cells++; cell->x = x; - cell->area = 0; - cell->cover = 0; + cell->area = ras.area; + cell->cover = ras.cover; cell->next = *pcell; *pcell = cell; - Exit: - return cell; - } - - - static void - gray_record_cell( RAS_ARG ) - { - if ( ras.area | ras.cover ) - { - PCell cell = gray_find_cell( RAS_VAR ); - + return; - cell->area += ras.area; - cell->cover += ras.cover; - } + Found: + /* update old cell */ + cell->area += ras.area; + cell->cover += ras.cover; } @@ -628,56 +569,25 @@ typedef ptrdiff_t FT_PtrDist; /* All cells that are on the left of the clipping region go to the */ /* min_ex - 1 horizontal position. */ - ey -= ras.min_ey; - - if ( ex > ras.max_ex ) - ex = ras.max_ex; - ex -= ras.min_ex; - if ( ex < 0 ) - ex = -1; + if ( ex < ras.min_ex ) + ex = ras.min_ex - 1; - /* are we moving to a different cell ? */ - if ( ex != ras.ex || ey != ras.ey ) - { - /* record the current one if it is valid */ - if ( !ras.invalid ) - gray_record_cell( RAS_VAR ); + /* record the current one if it is valid */ + if ( !ras.invalid ) + gray_record_cell( RAS_VAR ); - ras.area = 0; - ras.cover = 0; - ras.ex = ex; - ras.ey = ey; - } + ras.area = 0; + ras.cover = 0; + ras.ex = ex; + ras.ey = ey; - ras.invalid = ( (unsigned int)ey >= (unsigned int)ras.count_ey || - ex >= ras.count_ex ); + ras.invalid = ( ey >= ras.max_ey || ey < ras.min_ey || + ex >= ras.max_ex ); } - /*************************************************************************/ - /* */ - /* Start a new contour at a given cell. */ - /* */ - static void - gray_start_cell( RAS_ARG_ TCoord ex, - TCoord ey ) - { - if ( ex > ras.max_ex ) - ex = (TCoord)( ras.max_ex ); - - if ( ex < ras.min_ex ) - ex = (TCoord)( ras.min_ex - 1 ); - - ras.area = 0; - ras.cover = 0; - ras.ex = ex - ras.min_ex; - ras.ey = ey - ras.min_ey; - ras.invalid = 0; - - gray_set_cell( RAS_VAR_ ex, ey ); - } - +#ifndef FT_LONG64 /*************************************************************************/ /* */ @@ -690,17 +600,13 @@ typedef ptrdiff_t FT_PtrDist; TPos x2, TCoord y2 ) { - TCoord ex1, ex2, fx1, fx2, delta, mod; - long p, first, dx; + TCoord ex1, ex2, fx1, fx2, first, delta, mod; + TPos p, dx; int incr; - dx = x2 - x1; - ex1 = TRUNC( x1 ); ex2 = TRUNC( x2 ); - fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) ); - fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) ); /* trivial case. Happens often */ if ( y1 == y2 ) @@ -709,11 +615,14 @@ typedef ptrdiff_t FT_PtrDist; return; } + fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) ); + fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) ); + delta = y2 - y1; + /* everything is located in a single cell. That is easy! */ /* */ if ( ex1 == ex2 ) { - delta = y2 - y1; ras.area += (TArea)(( fx1 + fx2 ) * delta); ras.cover += delta; return; @@ -722,13 +631,17 @@ typedef ptrdiff_t FT_PtrDist; /* ok, we'll have to render a run of adjacent cells on the same */ /* scanline... */ /* */ - p = ( ONE_PIXEL - fx1 ) * ( y2 - y1 ); - first = ONE_PIXEL; - incr = 1; + dx = x2 - x1; - if ( dx < 0 ) + if ( dx > 0 ) + { + p = ( ONE_PIXEL - fx1 ) * delta; + first = ONE_PIXEL; + incr = 1; + } + else { - p = fx1 * ( y2 - y1 ); + p = fx1 * delta; first = 0; incr = -1; dx = -dx; @@ -785,25 +698,22 @@ typedef ptrdiff_t FT_PtrDist; gray_render_line( RAS_ARG_ TPos to_x, TPos to_y ) { - TCoord ey1, ey2, fy1, fy2, mod; - TPos dx, dy, x, x2; - long p, first; - int delta, rem, lift, incr; + TCoord ey1, ey2, fy1, fy2, first, delta, mod; + TPos p, dx, dy, x, x2; + int incr; ey1 = TRUNC( ras.y ); ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */ - fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) ); - fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); - - dx = to_x - ras.x; - dy = to_y - ras.y; /* perform vertical clipping */ if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) || ( ey1 < ras.min_ey && ey2 < ras.min_ey ) ) goto End; + fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) ); + fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); + /* everything is on a single scanline */ if ( ey1 == ey2 ) { @@ -811,9 +721,10 @@ typedef ptrdiff_t FT_PtrDist; goto End; } - /* vertical line - avoid calling gray_render_scanline */ - incr = 1; + dx = to_x - ras.x; + dy = to_y - ras.y; + /* vertical line - avoid calling gray_render_scanline */ if ( dx == 0 ) { TCoord ex = TRUNC( ras.x ); @@ -821,21 +732,25 @@ typedef ptrdiff_t FT_PtrDist; TArea area; - first = ONE_PIXEL; - if ( dy < 0 ) + if ( dy > 0) + { + first = ONE_PIXEL; + incr = 1; + } + else { first = 0; incr = -1; } - delta = (int)( first - fy1 ); + delta = first - fy1; ras.area += (TArea)two_fx * delta; ras.cover += delta; ey1 += incr; gray_set_cell( RAS_VAR_ ex, ey1 ); - delta = (int)( first + first - ONE_PIXEL ); + delta = first + first - ONE_PIXEL; area = (TArea)two_fx * delta; while ( ey1 != ey2 ) { @@ -846,7 +761,7 @@ typedef ptrdiff_t FT_PtrDist; gray_set_cell( RAS_VAR_ ex, ey1 ); } - delta = (int)( fy2 - ONE_PIXEL + first ); + delta = fy2 - ONE_PIXEL + first; ras.area += (TArea)two_fx * delta; ras.cover += delta; @@ -854,11 +769,13 @@ typedef ptrdiff_t FT_PtrDist; } /* ok, we have to render several scanlines */ - p = ( ONE_PIXEL - fy1 ) * dx; - first = ONE_PIXEL; - incr = 1; - - if ( dy < 0 ) + if ( dy > 0) + { + p = ( ONE_PIXEL - fy1 ) * dx; + first = ONE_PIXEL; + incr = 1; + } + else { p = fy1 * dx; first = 0; @@ -866,19 +783,22 @@ typedef ptrdiff_t FT_PtrDist; dy = -dy; } - FT_DIV_MOD( int, p, dy, delta, mod ); + FT_DIV_MOD( TCoord, p, dy, delta, mod ); x = ras.x + delta; - gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, (TCoord)first ); + gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, first ); ey1 += incr; gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); if ( ey1 != ey2 ) { - p = ONE_PIXEL * dx; - FT_DIV_MOD( int, p, dy, lift, rem ); - mod -= (int)dy; + TCoord lift, rem; + + + p = ONE_PIXEL * dx; + FT_DIV_MOD( TCoord, p, dy, lift, rem ); + mod -= (TCoord)dy; do { @@ -886,14 +806,14 @@ typedef ptrdiff_t FT_PtrDist; mod += rem; if ( mod >= 0 ) { - mod -= (int)dy; + mod -= (TCoord)dy; delta++; } x2 = x + delta; - gray_render_scanline( RAS_VAR_ ey1, x, - (TCoord)( ONE_PIXEL - first ), x2, - (TCoord)first ); + gray_render_scanline( RAS_VAR_ ey1, + x, ONE_PIXEL - first, + x2, first ); x = x2; ey1 += incr; @@ -901,15 +821,153 @@ typedef ptrdiff_t FT_PtrDist; } while ( ey1 != ey2 ); } - gray_render_scanline( RAS_VAR_ ey1, x, - (TCoord)( ONE_PIXEL - first ), to_x, - fy2 ); + gray_render_scanline( RAS_VAR_ ey1, + x, ONE_PIXEL - first, + to_x, fy2 ); End: ras.x = to_x; ras.y = to_y; } +#else + + /*************************************************************************/ + /* */ + /* Render a straight line across multiple cells in any direction. */ + /* */ + static void + gray_render_line( RAS_ARG_ TPos to_x, + TPos to_y ) + { + TPos dx, dy, fx1, fy1, fx2, fy2; + TCoord ex1, ex2, ey1, ey2; + + + ey1 = TRUNC( ras.y ); + ey2 = TRUNC( to_y ); + + /* perform vertical clipping */ + if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) || + ( ey1 < ras.min_ey && ey2 < ras.min_ey ) ) + goto End; + + ex1 = TRUNC( ras.x ); + ex2 = TRUNC( to_x ); + + fx1 = ras.x - SUBPIXELS( ex1 ); + fy1 = ras.y - SUBPIXELS( ey1 ); + + dx = to_x - ras.x; + dy = to_y - ras.y; + + if ( ex1 == ex2 && ey1 == ey2 ) /* inside one cell */ + ; + else if ( dy == 0 ) /* ex1 != ex2 */ /* any horizontal line */ + { + ex1 = ex2; + gray_set_cell( RAS_VAR_ ex1, ey1 ); + } + else if ( dx == 0 ) + { + if ( dy > 0 ) /* vertical line up */ + do + { + fy2 = ONE_PIXEL; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * fx1 * 2; + fy1 = 0; + ey1++; + gray_set_cell( RAS_VAR_ ex1, ey1 ); + } while ( ey1 != ey2 ); + else /* vertical line down */ + do + { + fy2 = 0; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * fx1 * 2; + fy1 = ONE_PIXEL; + ey1--; + gray_set_cell( RAS_VAR_ ex1, ey1 ); + } while ( ey1 != ey2 ); + } + else /* any other line */ + { + TPos prod = dx * fy1 - dy * fx1; + FT_UDIVPREP( ex1 != ex2, dx ); + FT_UDIVPREP( ey1 != ey2, dy ); + + + /* The fundamental value `prod' determines which side and the */ + /* exact coordinate where the line exits current cell. It is */ + /* also easily updated when moving from one cell to the next. */ + do + { + if ( prod <= 0 && + prod - dx * ONE_PIXEL > 0 ) /* left */ + { + fx2 = 0; + fy2 = (TPos)FT_UDIV( -prod, -dx ); + prod -= dy * ONE_PIXEL; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + fx1 = ONE_PIXEL; + fy1 = fy2; + ex1--; + } + else if ( prod - dx * ONE_PIXEL <= 0 && + prod - dx * ONE_PIXEL + dy * ONE_PIXEL > 0 ) /* up */ + { + prod -= dx * ONE_PIXEL; + fx2 = (TPos)FT_UDIV( -prod, dy ); + fy2 = ONE_PIXEL; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + fx1 = fx2; + fy1 = 0; + ey1++; + } + else if ( prod - dx * ONE_PIXEL + dy * ONE_PIXEL <= 0 && + prod + dy * ONE_PIXEL >= 0 ) /* right */ + { + prod += dy * ONE_PIXEL; + fx2 = ONE_PIXEL; + fy2 = (TPos)FT_UDIV( prod, dx ); + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + fx1 = 0; + fy1 = fy2; + ex1++; + } + else /* ( prod + dy * ONE_PIXEL < 0 && + prod > 0 ) down */ + { + fx2 = (TPos)FT_UDIV( prod, -dy ); + fy2 = 0; + prod += dx * ONE_PIXEL; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + fx1 = fx2; + fy1 = ONE_PIXEL; + ey1--; + } + + gray_set_cell( RAS_VAR_ ex1, ey1 ); + } while ( ex1 != ex2 || ey1 != ey2 ); + } + + fx2 = to_x - SUBPIXELS( ex2 ); + fy2 = to_y - SUBPIXELS( ey2 ); + + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + + End: + ras.x = to_x; + ras.y = to_y; + } + +#endif static void gray_split_conic( FT_Vector* base ) @@ -935,73 +993,64 @@ typedef ptrdiff_t FT_PtrDist; gray_render_conic( RAS_ARG_ const FT_Vector* control, const FT_Vector* to ) { + FT_Vector bez_stack[16 * 2 + 1]; /* enough to accommodate bisections */ + FT_Vector* arc = bez_stack; TPos dx, dy; - TPos min, max, y; - int top, level; - int* levels; - FT_Vector* arc; - + int draw, split; - levels = ras.lev_stack; - arc = ras.bez_stack; arc[0].x = UPSCALE( to->x ); arc[0].y = UPSCALE( to->y ); arc[1].x = UPSCALE( control->x ); arc[1].y = UPSCALE( control->y ); arc[2].x = ras.x; arc[2].y = ras.y; - top = 0; + + /* short-cut the arc that crosses the current band */ + if ( ( TRUNC( arc[0].y ) >= ras.max_ey && + TRUNC( arc[1].y ) >= ras.max_ey && + TRUNC( arc[2].y ) >= ras.max_ey ) || + ( TRUNC( arc[0].y ) < ras.min_ey && + TRUNC( arc[1].y ) < ras.min_ey && + TRUNC( arc[2].y ) < ras.min_ey ) ) + { + ras.x = arc[0].x; + ras.y = arc[0].y; + return; + } dx = FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x ); dy = FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y ); if ( dx < dy ) dx = dy; - if ( dx < ONE_PIXEL / 4 ) - goto Draw; - - /* short-cut the arc that crosses the current band */ - min = max = arc[0].y; - - y = arc[1].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - - y = arc[2].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - - if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey ) - goto Draw; - - level = 0; - do + /* We can calculate the number of necessary bisections because */ + /* each bisection predictably reduces deviation exactly 4-fold. */ + /* Even 32-bit deviation would vanish after 16 bisections. */ + draw = 1; + while ( dx > ONE_PIXEL / 4 ) { - dx >>= 2; - level++; - } while ( dx > ONE_PIXEL / 4 ); - - levels[0] = level; + dx >>= 2; + draw <<= 1; + } + /* We use decrement counter to count the total number of segments */ + /* to draw starting from 2^level. Before each draw we split as */ + /* many times as there are trailing zeros in the counter. */ do { - level = levels[top]; - if ( level > 0 ) + split = 1; + while ( ( draw & split ) == 0 ) { gray_split_conic( arc ); arc += 2; - top++; - levels[top] = levels[top - 1] = level - 1; - continue; + split <<= 1; } - Draw: gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); - top--; arc -= 2; - } while ( top >= 0 ); + } while ( --draw ); } @@ -1038,11 +1087,13 @@ typedef ptrdiff_t FT_PtrDist; const FT_Vector* control2, const FT_Vector* to ) { - FT_Vector* arc; - TPos min, max, y; + FT_Vector bez_stack[16 * 3 + 1]; /* enough to accommodate bisections */ + FT_Vector* arc = bez_stack; + TPos dx, dy, dx_, dy_; + TPos dx1, dy1, dx2, dy2; + TPos L, s, s_limit; - arc = ras.bez_stack; arc[0].x = UPSCALE( to->x ); arc[0].y = UPSCALE( to->y ); arc[1].x = UPSCALE( control2->x ); @@ -1052,29 +1103,20 @@ typedef ptrdiff_t FT_PtrDist; arc[3].x = ras.x; arc[3].y = ras.y; - /* Short-cut the arc that crosses the current band. */ - min = max = arc[0].y; - - y = arc[1].y; - if ( y < min ) - min = y; - if ( y > max ) - max = y; - - y = arc[2].y; - if ( y < min ) - min = y; - if ( y > max ) - max = y; - - y = arc[3].y; - if ( y < min ) - min = y; - if ( y > max ) - max = y; - - if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey ) - goto Draw; + /* short-cut the arc that crosses the current band */ + if ( ( TRUNC( arc[0].y ) >= ras.max_ey && + TRUNC( arc[1].y ) >= ras.max_ey && + TRUNC( arc[2].y ) >= ras.max_ey && + TRUNC( arc[3].y ) >= ras.max_ey ) || + ( TRUNC( arc[0].y ) < ras.min_ey && + TRUNC( arc[1].y ) < ras.min_ey && + TRUNC( arc[2].y ) < ras.min_ey && + TRUNC( arc[3].y ) < ras.min_ey ) ) + { + ras.x = arc[0].x; + ras.y = arc[0].y; + return; + } for (;;) { @@ -1083,64 +1125,53 @@ typedef ptrdiff_t FT_PtrDist; /* F. Hain, at */ /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */ - { - TPos dx, dy, dx_, dy_; - TPos dx1, dy1, dx2, dy2; - TPos L, s, s_limit; + /* dx and dy are x and y components of the P0-P3 chord vector. */ + dx = dx_ = arc[3].x - arc[0].x; + dy = dy_ = arc[3].y - arc[0].y; + L = FT_HYPOT( dx_, dy_ ); - /* dx and dy are x and y components of the P0-P3 chord vector. */ - dx = dx_ = arc[3].x - arc[0].x; - dy = dy_ = arc[3].y - arc[0].y; + /* Avoid possible arithmetic overflow below by splitting. */ + if ( L > 32767 ) + goto Split; - L = FT_HYPOT( dx_, dy_ ); + /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */ + s_limit = L * (TPos)( ONE_PIXEL / 6 ); - /* Avoid possible arithmetic overflow below by splitting. */ - if ( L > 32767 ) - goto Split; + /* s is L * the perpendicular distance from P1 to the line P0-P3. */ + dx1 = arc[1].x - arc[0].x; + dy1 = arc[1].y - arc[0].y; + s = FT_ABS( dy * dx1 - dx * dy1 ); - /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */ - s_limit = L * (TPos)( ONE_PIXEL / 6 ); + if ( s > s_limit ) + goto Split; - /* s is L * the perpendicular distance from P1 to the line P0-P3. */ - dx1 = arc[1].x - arc[0].x; - dy1 = arc[1].y - arc[0].y; - s = FT_ABS( dy * dx1 - dx * dy1 ); + /* s is L * the perpendicular distance from P2 to the line P0-P3. */ + dx2 = arc[2].x - arc[0].x; + dy2 = arc[2].y - arc[0].y; + s = FT_ABS( dy * dx2 - dx * dy2 ); - if ( s > s_limit ) - goto Split; + if ( s > s_limit ) + goto Split; - /* s is L * the perpendicular distance from P2 to the line P0-P3. */ - dx2 = arc[2].x - arc[0].x; - dy2 = arc[2].y - arc[0].y; - s = FT_ABS( dy * dx2 - dx * dy2 ); + /* Split super curvy segments where the off points are so far + from the chord that the angles P0-P1-P3 or P0-P2-P3 become + acute as detected by appropriate dot products. */ + if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 || + dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 ) + goto Split; - if ( s > s_limit ) - goto Split; + gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); - /* Split super curvy segments where the off points are so far - from the chord that the angles P0-P1-P3 or P0-P2-P3 become - acute as detected by appropriate dot products. */ - if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 || - dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 ) - goto Split; + if ( arc == bez_stack ) + return; - /* No reason to split. */ - goto Draw; - } + arc -= 3; + continue; Split: gray_split_cubic( arc ); arc += 3; - continue; - - Draw: - gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); - - if ( arc == ras.bez_stack ) - return; - - arc -= 3; } } @@ -1152,18 +1183,14 @@ typedef ptrdiff_t FT_PtrDist; TPos x, y; - /* record current cell, if any */ - if ( !ras.invalid ) - gray_record_cell( RAS_VAR ); - /* start to a new position */ x = UPSCALE( to->x ); y = UPSCALE( to->y ); - gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) ); + gray_set_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) ); - worker->x = x; - worker->y = y; + ras.x = x; + ras.y = y; return 0; } @@ -1199,63 +1226,13 @@ typedef ptrdiff_t FT_PtrDist; static void - gray_render_span( int y, - int count, - const FT_Span* spans, - gray_PWorker worker ) - { - unsigned char* p; - FT_Bitmap* map = &worker->target; - - - /* first of all, compute the scanline offset */ - p = (unsigned char*)map->buffer - y * map->pitch; - if ( map->pitch >= 0 ) - p += ( map->rows - 1 ) * (unsigned int)map->pitch; - - for ( ; count > 0; count--, spans++ ) - { - unsigned char coverage = spans->coverage; - - - if ( 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: - ; - } - } - } - } - } - - - static void gray_hline( RAS_ARG_ TCoord x, TCoord y, - TPos area, + TArea area, TCoord acount ) { - int coverage; + int coverage; + FT_Span span; /* compute the coverage line's coverage, depending on the */ @@ -1284,179 +1261,88 @@ typedef ptrdiff_t FT_PtrDist; coverage = 255; } - y += (TCoord)ras.min_ey; - x += (TCoord)ras.min_ex; - - /* FT_Span.x is a 16-bit short, so limit our coordinates appropriately */ - if ( x >= 32767 ) - x = 32767; - - /* FT_Span.y is an integer, so limit our coordinates appropriately */ - if ( y >= FT_INT_MAX ) - y = FT_INT_MAX; - - if ( coverage ) + if ( ras.render_span ) /* for FT_RASTER_FLAG_DIRECT only */ { - FT_Span* span; - int count; + span.x = (short)x; + span.len = (unsigned short)acount; + span.coverage = (unsigned char)coverage; - - /* 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->len = (unsigned short)( span->len + acount ); - return; - } - - if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS ) - { - if ( ras.render_span && count > 0 ) - ras.render_span( ras.span_y, count, ras.gray_spans, - ras.render_span_data ); - -#ifdef FT_DEBUG_LEVEL_TRACE - - if ( count > 0 ) - { - int n; - - - FT_TRACE7(( "y = %3d ", ras.span_y )); - span = ras.gray_spans; - for ( n = 0; n < count; n++, span++ ) - FT_TRACE7(( "[%d..%d]:%02x ", - span->x, span->x + span->len - 1, span->coverage )); - FT_TRACE7(( "\n" )); - } - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - ras.num_gray_spans = 0; - ras.span_y = (int)y; - - span = ras.gray_spans; - } - else - span++; - - /* add a gray span to the current list */ - span->x = (short)x; - span->len = (unsigned short)acount; - span->coverage = (unsigned char)coverage; - - ras.num_gray_spans++; + ras.render_span( y, 1, &span, ras.render_span_data ); } - } - - -#ifdef FT_DEBUG_LEVEL_TRACE - - /* to be called while in the debugger -- */ - /* this function causes a compiler warning since it is unused otherwise */ - static void - gray_dump_cells( RAS_ARG ) - { - int yindex; - - - for ( yindex = 0; yindex < ras.ycount; yindex++ ) + else { - PCell cell; - + unsigned char* q = ras.target.origin - ras.target.pitch * y + x; + unsigned char c = (unsigned char)coverage; - printf( "%3d:", yindex ); - for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next ) - printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area ); - printf( "\n" ); + /* 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. + */ + switch ( acount ) + { + case 7: *q++ = c; + case 6: *q++ = c; + case 5: *q++ = c; + case 4: *q++ = c; + case 3: *q++ = c; + case 2: *q++ = c; + case 1: *q = c; + case 0: break; + default: + FT_MEM_SET( q, c, acount ); + } } } -#endif /* FT_DEBUG_LEVEL_TRACE */ - static void - gray_sweep( RAS_ARG_ const FT_Bitmap* target ) + gray_sweep( RAS_ARG ) { - int yindex; - - FT_UNUSED( target ); + int y; - if ( ras.num_cells == 0 ) - return; - - ras.num_gray_spans = 0; - FT_TRACE7(( "gray_sweep: start\n" )); - for ( yindex = 0; yindex < ras.ycount; yindex++ ) + for ( y = ras.min_ey; y < ras.max_ey; y++ ) { - PCell cell = ras.ycells[yindex]; + PCell cell = ras.ycells[y - ras.min_ey]; TCoord cover = 0; - TCoord x = 0; + TCoord x = ras.min_ex; for ( ; cell != NULL; cell = cell->next ) { - TPos area; + TArea area; - if ( cell->x > x && cover != 0 ) - gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), + if ( cover != 0 && cell->x > x ) + gray_hline( RAS_VAR_ x, y, (TArea)cover * ( ONE_PIXEL * 2 ), cell->x - x ); cover += cell->cover; - area = cover * ( ONE_PIXEL * 2 ) - cell->area; + area = (TArea)cover * ( ONE_PIXEL * 2 ) - cell->area; - if ( area != 0 && cell->x >= 0 ) - gray_hline( RAS_VAR_ cell->x, yindex, area, 1 ); + if ( area != 0 && cell->x >= ras.min_ex ) + gray_hline( RAS_VAR_ cell->x, y, area, 1 ); x = cell->x + 1; } 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 FT_DEBUG_LEVEL_TRACE - - if ( ras.num_gray_spans > 0 ) - { - FT_Span* span; - int n; - - - FT_TRACE7(( "y = %3d ", ras.span_y )); - span = ras.gray_spans; - for ( n = 0; n < ras.num_gray_spans; n++, span++ ) - FT_TRACE7(( "[%d..%d]:%02x ", - span->x, span->x + span->len - 1, span->coverage )); - FT_TRACE7(( "\n" )); + gray_hline( RAS_VAR_ x, y, (TArea)cover * ( ONE_PIXEL * 2 ), + ras.max_ex - x ); } FT_TRACE7(( "gray_sweep: end\n" )); - -#endif /* FT_DEBUG_LEVEL_TRACE */ - } -#ifdef _STANDALONE_ +#ifdef STANDALONE_ /*************************************************************************/ /* */ - /* The following function should only compile in stand-alone mode, */ + /* The following functions should only compile in stand-alone mode, */ /* i.e., when building this component without the rest of FreeType. */ /* */ /*************************************************************************/ @@ -1727,32 +1613,102 @@ typedef ptrdiff_t FT_PtrDist; return 0; Exit: - FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); + FT_TRACE5(( "FT_Outline_Decompose: Error 0x%x\n", error )); return error; Invalid_Outline: return FT_THROW( Invalid_Outline ); } -#endif /* _STANDALONE_ */ + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_CBox */ + /* */ + /* <Description> */ + /* Return an outline's `control box'. The control box encloses all */ + /* the outline's points, including Bézier control points. Though it */ + /* coincides with the exact bounding box for most glyphs, it can be */ + /* slightly larger in some situations (like when rotating an outline */ + /* that contains Bézier outside arcs). */ + /* */ + /* Computing the control box is very fast, while getting the bounding */ + /* box can take much more time as it needs to walk over all segments */ + /* and arcs in the outline. To get the latter, you can use the */ + /* `ftbbox' component, which is dedicated to this single task. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <Output> */ + /* acbox :: The outline's control box. */ + /* */ + /* <Note> */ + /* See @FT_Glyph_Get_CBox for a discussion of tricky fonts. */ + /* */ - typedef struct gray_TBand_ + static void + FT_Outline_Get_CBox( const FT_Outline* outline, + FT_BBox *acbox ) { - TPos min, max; + TPos xMin, yMin, xMax, yMax; + + + if ( outline && acbox ) + { + if ( outline->n_points == 0 ) + { + xMin = 0; + yMin = 0; + xMax = 0; + yMax = 0; + } + else + { + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + + xMin = xMax = vec->x; + yMin = yMax = vec->y; + vec++; + + for ( ; vec < limit; vec++ ) + { + TPos x, y; + + + x = vec->x; + if ( x < xMin ) xMin = x; + if ( x > xMax ) xMax = x; + + y = vec->y; + if ( y < yMin ) yMin = y; + if ( y > yMax ) yMax = y; + } + } + acbox->xMin = xMin; + acbox->xMax = xMax; + acbox->yMin = yMin; + acbox->yMax = yMax; + } + } - } gray_TBand; +#endif /* STANDALONE_ */ FT_DEFINE_OUTLINE_FUNCS( func_interface, - (FT_Outline_MoveTo_Func) gray_move_to, - (FT_Outline_LineTo_Func) gray_line_to, - (FT_Outline_ConicTo_Func)gray_conic_to, - (FT_Outline_CubicTo_Func)gray_cubic_to, - 0, - 0 ) + (FT_Outline_MoveTo_Func) gray_move_to, /* move_to */ + (FT_Outline_LineTo_Func) gray_line_to, /* line_to */ + (FT_Outline_ConicTo_Func)gray_conic_to, /* conic_to */ + (FT_Outline_CubicTo_Func)gray_cubic_to, /* cubic_to */ + + 0, /* shift */ + 0 /* delta */ + ) static int @@ -1771,10 +1727,18 @@ typedef ptrdiff_t FT_PtrDist; error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras ); if ( !ras.invalid ) gray_record_cell( RAS_VAR ); + + FT_TRACE7(( "band [%d..%d]: %d cells\n", + ras.min_ey, ras.max_ey, ras.num_cells )); } else + { error = FT_THROW( Memory_Overflow ); + FT_TRACE7(( "band [%d..%d]: to be bisected\n", + ras.min_ey, ras.max_ey )); + } + return error; } @@ -1782,158 +1746,116 @@ typedef ptrdiff_t FT_PtrDist; static int gray_convert_glyph( RAS_ARG ) { - gray_TBand bands[40]; - gray_TBand* volatile band; - int volatile n, num_bands; - TPos volatile min, max, max_y; - FT_BBox* clip; - - - /* Set up state in the raster object */ - gray_compute_cbox( RAS_VAR ); - - /* clip to target bitmap, exit if nothing to do */ - clip = &ras.clip_box; - - if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax || - ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax ) - return 0; - - if ( ras.min_ex < clip->xMin ) ras.min_ex = clip->xMin; - if ( ras.min_ey < clip->yMin ) ras.min_ey = clip->yMin; - - if ( ras.max_ex > clip->xMax ) ras.max_ex = clip->xMax; - if ( ras.max_ey > clip->yMax ) ras.max_ey = clip->yMax; + TCell buffer[FT_MAX_GRAY_POOL]; + TCoord band_size = FT_MAX_GRAY_POOL / 8; + TCoord count = ras.max_ey - ras.min_ey; + int num_bands; + TCoord min, max, max_y; + TCoord bands[32]; /* enough to accommodate bisections */ + TCoord* band; - ras.count_ex = ras.max_ex - ras.min_ex; - ras.count_ey = ras.max_ey - ras.min_ey; /* set up vertical bands */ - num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size ); - if ( num_bands == 0 ) - num_bands = 1; - if ( num_bands >= 39 ) - num_bands = 39; - - ras.band_shoot = 0; + if ( count > band_size ) + { + /* two divisions rounded up */ + num_bands = (int)( ( count + band_size - 1) / band_size ); + band_size = ( count + num_bands - 1 ) / num_bands; + } min = ras.min_ey; max_y = ras.max_ey; - for ( n = 0; n < num_bands; n++, min = max ) + for ( ; min < max_y; min = max ) { - max = min + ras.band_size; - if ( n == num_bands - 1 || max > max_y ) + max = min + band_size; + if ( max > max_y ) max = max_y; - bands[0].min = min; - bands[0].max = max; - band = bands; + band = bands; + band[1] = min; + band[0] = max; do { - TPos bottom, top, middle; - int error; + TCoord width = band[0] - band[1]; + 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 = (long)sizeof ( PCell ) * ras.ycount; - cell_mod = cell_start % (long)sizeof ( TCell ); - if ( cell_mod > 0 ) - cell_start += (long)sizeof ( TCell ) - cell_mod; + /* memory management */ + { + size_t ycount = (size_t)width; + size_t cell_start; - cell_end = ras.buffer_size; - cell_end -= cell_end % (long)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; + cell_start = ( ycount * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) / + sizeof ( TCell ); - ras.max_cells = cells_max - ras.cells; - if ( ras.max_cells < 2 ) - goto ReduceBands; + ras.cells = buffer + cell_start; + ras.max_cells = (FT_PtrDist)( FT_MAX_GRAY_POOL - cell_start ); + ras.num_cells = 0; - for ( yindex = 0; yindex < ras.ycount; yindex++ ) - ras.ycells[yindex] = NULL; + ras.ycells = (PCell*)buffer; + while ( ycount ) + ras.ycells[--ycount] = 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; + ras.min_ey = band[1]; + ras.max_ey = band[0]; error = gray_convert_glyph_inner( RAS_VAR ); if ( !error ) { - gray_sweep( RAS_VAR_ &ras.target ); + gray_sweep( RAS_VAR ); band--; continue; } else if ( error != ErrRaster_Memory_Overflow ) return 1; - ReduceBands: /* render pool overflow; we will reduce the render band by half */ - bottom = band->min; - top = band->max; - middle = bottom + ( ( top - bottom ) >> 1 ); + width >>= 1; /* This is too complex for a single scanline; there must */ /* be some problems. */ - if ( middle == bottom ) + if ( width == 0 ) { -#ifdef FT_DEBUG_LEVEL_TRACE FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" )); -#endif return 1; } - if ( bottom-top >= ras.band_size ) - ras.band_shoot++; - - band[1].min = bottom; - band[1].max = middle; - band[0].min = middle; - band[0].max = top; band++; + band[1] = band[0]; + band[0] += width; } while ( band >= bands ); } - if ( ras.band_shoot > 8 && ras.band_size > 16 ) - ras.band_size = ras.band_size / 2; - return 0; } static int - gray_raster_render( gray_PRaster raster, + gray_raster_render( FT_Raster raster, const FT_Raster_Params* params ) { - const FT_Outline* outline = (const FT_Outline*)params->source; - const FT_Bitmap* target_map = params->target; + const FT_Outline* outline = (const FT_Outline*)params->source; + const FT_Bitmap* target_map = params->target; + FT_BBox cbox, clip; +#ifndef FT_STATIC_RASTER gray_TWorker worker[1]; - - TCell buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( TCell )]; - long buffer_size = sizeof ( buffer ); - int band_size = (int)( buffer_size / - (long)( sizeof ( TCell ) * 8 ) ); +#endif if ( !raster ) return FT_THROW( Invalid_Argument ); + /* this version does not support monochrome rendering */ + if ( !( params->flags & FT_RASTER_FLAG_AA ) ) + return FT_THROW( Invalid_Mode ); + if ( !outline ) return FT_THROW( Invalid_Outline ); @@ -1948,9 +1870,19 @@ typedef ptrdiff_t FT_PtrDist; outline->contours[outline->n_contours - 1] + 1 ) return FT_THROW( Invalid_Outline ); - /* if direct mode is not set, we must have a target bitmap */ - if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) + ras.outline = *outline; + + if ( params->flags & FT_RASTER_FLAG_DIRECT ) { + if ( !params->gray_spans ) + return 0; + + ras.render_span = (FT_Raster_Span_Func)params->gray_spans; + ras.render_span_data = params->user; + } + else + { + /* if direct mode is not set, we must have a target bitmap */ if ( !target_map ) return FT_THROW( Invalid_Argument ); @@ -1960,51 +1892,59 @@ typedef ptrdiff_t FT_PtrDist; if ( !target_map->buffer ) return FT_THROW( Invalid_Argument ); + + if ( target_map->pitch < 0 ) + ras.target.origin = target_map->buffer; + else + ras.target.origin = target_map->buffer + + ( target_map->rows - 1 ) * (unsigned int)target_map->pitch; + + ras.target.pitch = target_map->pitch; + + ras.render_span = (FT_Raster_Span_Func)NULL; + ras.render_span_data = NULL; } - /* this version does not support monochrome rendering */ - if ( !( params->flags & FT_RASTER_FLAG_AA ) ) - return FT_THROW( Invalid_Mode ); + FT_Outline_Get_CBox( outline, &cbox ); + + /* reject too large outline coordinates */ + if ( cbox.xMin < -0x1000000L || cbox.xMax > 0x1000000L || + cbox.yMin < -0x1000000L || cbox.yMax > 0x1000000L ) + return FT_THROW( Invalid_Outline ); + + /* truncate the bounding box to integer pixels */ + cbox.xMin = cbox.xMin >> 6; + cbox.yMin = cbox.yMin >> 6; + cbox.xMax = ( cbox.xMax + 63 ) >> 6; + cbox.yMax = ( cbox.yMax + 63 ) >> 6; /* compute clipping box */ if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) { /* compute clip box from target pixmap */ - ras.clip_box.xMin = 0; - ras.clip_box.yMin = 0; - ras.clip_box.xMax = (FT_Pos)target_map->width; - ras.clip_box.yMax = (FT_Pos)target_map->rows; + clip.xMin = 0; + clip.yMin = 0; + clip.xMax = (FT_Pos)target_map->width; + clip.yMax = (FT_Pos)target_map->rows; } else if ( params->flags & FT_RASTER_FLAG_CLIP ) - ras.clip_box = params->clip_box; + clip = params->clip_box; else { - ras.clip_box.xMin = -32768L; - ras.clip_box.yMin = -32768L; - ras.clip_box.xMax = 32767L; - ras.clip_box.yMax = 32767L; + clip.xMin = -32768L; + clip.yMin = -32768L; + clip.xMax = 32767L; + clip.yMax = 32767L; } - gray_init_cells( RAS_VAR_ buffer, buffer_size ); - - ras.outline = *outline; - ras.num_cells = 0; - ras.invalid = 1; - ras.band_size = band_size; - ras.num_gray_spans = 0; - ras.span_y = 0; + /* clip to target bitmap, exit if nothing to do */ + ras.min_ex = FT_MAX( cbox.xMin, clip.xMin ); + ras.min_ey = FT_MAX( cbox.yMin, clip.yMin ); + ras.max_ex = FT_MIN( cbox.xMax, clip.xMax ); + ras.max_ey = FT_MIN( cbox.yMax, clip.yMax ); - if ( params->flags & FT_RASTER_FLAG_DIRECT ) - { - ras.render_span = (FT_Raster_Span_Func)params->gray_spans; - ras.render_span_data = params->user; - } - else - { - ras.target = *target_map; - ras.render_span = (FT_Raster_Span_Func)gray_render_span; - ras.render_span_data = &ras; - } + if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey ) + return 0; return gray_convert_glyph( RAS_VAR ); } @@ -2013,7 +1953,7 @@ typedef ptrdiff_t FT_PtrDist; /**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/ /**** a static object. *****/ -#ifdef _STANDALONE_ +#ifdef STANDALONE_ static int gray_raster_new( void* memory, @@ -2025,7 +1965,7 @@ typedef ptrdiff_t FT_PtrDist; *araster = (FT_Raster)&the_raster; - FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); + FT_ZERO( &the_raster ); return 0; } @@ -2038,7 +1978,7 @@ typedef ptrdiff_t FT_PtrDist; FT_UNUSED( raster ); } -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ static int gray_raster_new( FT_Memory memory, @@ -2068,13 +2008,13 @@ typedef ptrdiff_t FT_PtrDist; FT_FREE( raster ); } -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ static void - gray_raster_reset( FT_Raster raster, - char* pool_base, - long pool_size ) + gray_raster_reset( FT_Raster raster, + unsigned char* pool_base, + unsigned long pool_size ) { FT_UNUSED( raster ); FT_UNUSED( pool_base ); @@ -2101,11 +2041,12 @@ typedef ptrdiff_t FT_PtrDist; FT_GLYPH_FORMAT_OUTLINE, - (FT_Raster_New_Func) gray_raster_new, - (FT_Raster_Reset_Func) gray_raster_reset, - (FT_Raster_Set_Mode_Func)gray_raster_set_mode, - (FT_Raster_Render_Func) gray_raster_render, - (FT_Raster_Done_Func) gray_raster_done ) + (FT_Raster_New_Func) gray_raster_new, /* raster_new */ + (FT_Raster_Reset_Func) gray_raster_reset, /* raster_reset */ + (FT_Raster_Set_Mode_Func)gray_raster_set_mode, /* raster_set_mode */ + (FT_Raster_Render_Func) gray_raster_render, /* raster_render */ + (FT_Raster_Done_Func) gray_raster_done /* raster_done */ + ) /* END */ diff --git a/third_party/freetype/src/smooth/ftgrays.h b/third_party/freetype/src/smooth/ftgrays.h index 1b5760330c..a5447da1a9 100644 --- a/third_party/freetype/src/smooth/ftgrays.h +++ b/third_party/freetype/src/smooth/ftgrays.h @@ -4,7 +4,7 @@ /* */ /* FreeType smooth renderer declaration */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,15 +16,15 @@ /***************************************************************************/ -#ifndef __FTGRAYS_H__ -#define __FTGRAYS_H__ +#ifndef FTGRAYS_H_ +#define FTGRAYS_H_ #ifdef __cplusplus extern "C" { #endif -#ifdef _STANDALONE_ +#ifdef STANDALONE_ #include "ftimage.h" #else #include <ft2build.h> @@ -52,7 +52,7 @@ } #endif -#endif /* __FTGRAYS_H__ */ +#endif /* FTGRAYS_H_ */ /* END */ diff --git a/third_party/freetype/src/smooth/ftsmerrs.h b/third_party/freetype/src/smooth/ftsmerrs.h index cc38aa1996..a528c61832 100644 --- a/third_party/freetype/src/smooth/ftsmerrs.h +++ b/third_party/freetype/src/smooth/ftsmerrs.h @@ -4,7 +4,7 @@ /* */ /* smooth renderer error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __FTSMERRS_H__ -#define __FTSMERRS_H__ +#ifndef FTSMERRS_H_ +#define FTSMERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX Smooth_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __FTSMERRS_H__ */ +#endif /* FTSMERRS_H_ */ /* END */ diff --git a/third_party/freetype/src/smooth/ftsmooth.c b/third_party/freetype/src/smooth/ftsmooth.c index 3620550534..c9292df350 100644 --- a/third_party/freetype/src/smooth/ftsmooth.c +++ b/third_party/freetype/src/smooth/ftsmooth.c @@ -4,7 +4,7 @@ /* */ /* Anti-aliasing renderer interface (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -87,7 +87,7 @@ FT_GlyphSlot slot, FT_BBox* cbox ) { - FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); + FT_ZERO( cbox ); if ( slot->format == render->glyph_format ) FT_Outline_Get_CBox( &slot->outline, cbox ); @@ -114,8 +114,8 @@ #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING FT_Pos height_org, width_org; #endif - FT_Int hmul = mode == FT_RENDER_MODE_LCD; - FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; + FT_Int hmul = ( mode == FT_RENDER_MODE_LCD ); + FT_Int vmul = ( mode == FT_RENDER_MODE_LCD_V ); FT_Raster_Params params; @@ -428,7 +428,8 @@ } - FT_DEFINE_RENDERER( ft_smooth_renderer_class, + FT_DEFINE_RENDERER( + ft_smooth_renderer_class, FT_MODULE_RENDERER, sizeof ( FT_RendererRec ), @@ -437,25 +438,25 @@ 0x10000L, 0x20000L, - 0, /* module specific interface */ + NULL, /* module specific interface */ - (FT_Module_Constructor)ft_smooth_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , + (FT_Module_Constructor)ft_smooth_init, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) NULL, /* get_interface */ FT_GLYPH_FORMAT_OUTLINE, - (FT_Renderer_RenderFunc) ft_smooth_render, - (FT_Renderer_TransformFunc)ft_smooth_transform, - (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, - (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + (FT_Renderer_RenderFunc) ft_smooth_render, /* render_glyph */ + (FT_Renderer_TransformFunc)ft_smooth_transform, /* transform_glyph */ + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */ + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, /* set_mode */ - (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET /* raster_class */ ) - FT_DEFINE_RENDERER( ft_smooth_lcd_renderer_class, + FT_DEFINE_RENDERER( + ft_smooth_lcd_renderer_class, FT_MODULE_RENDERER, sizeof ( FT_RendererRec ), @@ -464,24 +465,25 @@ 0x10000L, 0x20000L, - 0, /* module specific interface */ + NULL, /* module specific interface */ - (FT_Module_Constructor)ft_smooth_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , + (FT_Module_Constructor)ft_smooth_init, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) NULL, /* get_interface */ FT_GLYPH_FORMAT_OUTLINE, - (FT_Renderer_RenderFunc) ft_smooth_render_lcd, - (FT_Renderer_TransformFunc)ft_smooth_transform, - (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, - (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + (FT_Renderer_RenderFunc) ft_smooth_render_lcd, /* render_glyph */ + (FT_Renderer_TransformFunc)ft_smooth_transform, /* transform_glyph */ + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */ + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, /* set_mode */ - (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET /* raster_class */ ) - FT_DEFINE_RENDERER( ft_smooth_lcdv_renderer_class, + + FT_DEFINE_RENDERER( + ft_smooth_lcdv_renderer_class, FT_MODULE_RENDERER, sizeof ( FT_RendererRec ), @@ -490,21 +492,20 @@ 0x10000L, 0x20000L, - 0, /* module specific interface */ + NULL, /* module specific interface */ - (FT_Module_Constructor)ft_smooth_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , + (FT_Module_Constructor)ft_smooth_init, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) NULL, /* get_interface */ FT_GLYPH_FORMAT_OUTLINE, - (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, - (FT_Renderer_TransformFunc)ft_smooth_transform, - (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, - (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, /* render_glyph */ + (FT_Renderer_TransformFunc)ft_smooth_transform, /* transform_glyph */ + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */ + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, /* set_mode */ - (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET /* raster_class */ ) diff --git a/third_party/freetype/src/smooth/ftsmooth.h b/third_party/freetype/src/smooth/ftsmooth.h index 765018c239..929e26078c 100644 --- a/third_party/freetype/src/smooth/ftsmooth.h +++ b/third_party/freetype/src/smooth/ftsmooth.h @@ -4,7 +4,7 @@ /* */ /* Anti-aliasing renderer interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTSMOOTH_H__ -#define __FTSMOOTH_H__ +#ifndef FTSMOOTH_H_ +#define FTSMOOTH_H_ #include <ft2build.h> @@ -43,7 +43,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSMOOTH_H__ */ +#endif /* FTSMOOTH_H_ */ /* END */ diff --git a/third_party/freetype/src/smooth/ftspic.c b/third_party/freetype/src/smooth/ftspic.c index 8e6ed57eec..fb89be3488 100644 --- a/third_party/freetype/src/smooth/ftspic.c +++ b/third_party/freetype/src/smooth/ftspic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for smooth module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/smooth/ftspic.h b/third_party/freetype/src/smooth/ftspic.h index 071afcff20..9ddd1c7905 100644 --- a/third_party/freetype/src/smooth/ftspic.h +++ b/third_party/freetype/src/smooth/ftspic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for smooth module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTSPIC_H__ -#define __FTSPIC_H__ +#ifndef FTSPIC_H_ +#define FTSPIC_H_ #include FT_INTERNAL_PIC_H @@ -69,7 +69,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSPIC_H__ */ +#endif /* FTSPIC_H_ */ /* END */ diff --git a/third_party/freetype/src/smooth/smooth.c b/third_party/freetype/src/smooth/smooth.c index 4ca4344c89..200f5dcb9a 100644 --- a/third_party/freetype/src/smooth/smooth.c +++ b/third_party/freetype/src/smooth/smooth.c @@ -4,7 +4,7 @@ /* */ /* FreeType anti-aliasing rasterer module component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/truetype/truetype.c b/third_party/freetype/src/truetype/truetype.c index f929437dc1..4866103a7f 100644 --- a/third_party/freetype/src/truetype/truetype.c +++ b/third_party/freetype/src/truetype/truetype.c @@ -4,7 +4,7 @@ /* */ /* FreeType TrueType driver component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/truetype/ttdriver.c b/third_party/freetype/src/truetype/ttdriver.c index 08b30c95ad..19f7858b3e 100644 --- a/third_party/freetype/src/truetype/ttdriver.c +++ b/third_party/freetype/src/truetype/ttdriver.c @@ -4,7 +4,7 @@ /* */ /* TrueType font driver implementation (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,6 +25,7 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include FT_MULTIPLE_MASTERS_H #include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_METRICS_VARIATIONS_H #endif #include FT_SERVICE_TRUETYPE_ENGINE_H @@ -61,23 +62,50 @@ static FT_Error tt_property_set( FT_Module module, /* TT_Driver */ const char* property_name, - const void* value ) + const void* value, + FT_Bool value_is_string ) { FT_Error error = FT_Err_Ok; TT_Driver driver = (TT_Driver)module; +#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + FT_UNUSED( value_is_string ); +#endif + if ( !ft_strcmp( property_name, "interpreter-version" ) ) { - FT_UInt* interpreter_version = (FT_UInt*)value; + FT_UInt interpreter_version; -#ifndef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( *interpreter_version != TT_INTERPRETER_VERSION_35 ) - error = FT_ERR( Unimplemented_Feature ); +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + if ( value_is_string ) + { + const char* s = (const char*)value; + + + interpreter_version = (FT_UInt)ft_strtol( s, NULL, 10 ); + } else #endif - driver->interpreter_version = *interpreter_version; + { + FT_UInt* iv = (FT_UInt*)value; + + + interpreter_version = *iv; + } + + if ( interpreter_version == TT_INTERPRETER_VERSION_35 +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + || interpreter_version == TT_INTERPRETER_VERSION_38 +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + || interpreter_version == TT_INTERPRETER_VERSION_40 +#endif + ) + driver->interpreter_version = interpreter_version; + else + error = FT_ERR( Unimplemented_Feature ); return error; } @@ -117,8 +145,10 @@ FT_DEFINE_SERVICE_PROPERTIESREC( tt_service_properties, - (FT_Properties_SetFunc)tt_property_set, - (FT_Properties_GetFunc)tt_property_get ) + + (FT_Properties_SetFunc)tt_property_set, /* set_property */ + (FT_Properties_GetFunc)tt_property_get /* get_property */ + ) /*************************************************************************/ @@ -194,13 +224,20 @@ FT_Fixed *advances ) { FT_UInt nn; - TT_Face face = (TT_Face) ttface; + TT_Face face = (TT_Face)ttface; /* XXX: TODO: check for sbits */ if ( flags & FT_LOAD_VERTICAL_LAYOUT ) { +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* no fast retrieval for blended MM fonts without VVAR table */ + if ( !face->is_default_instance && + !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + return FT_THROW( Unimplemented_Feature ); +#endif + for ( nn = 0; nn < count; nn++ ) { FT_Short tsb; @@ -214,6 +251,13 @@ } else { +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* no fast retrieval for blended MM fonts without HVAR table */ + if ( !face->is_default_instance && + !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + return FT_THROW( Unimplemented_Feature ); +#endif + for ( nn = 0; nn < count; nn++ ) { FT_Short lsb; @@ -228,6 +272,7 @@ return FT_Err_Ok; } + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -259,11 +304,11 @@ /* use the scaled metrics, even when tt_size_reset fails */ FT_Select_Metrics( size->face, strike_index ); - tt_size_reset( ttsize ); /* ignore return value */ + tt_size_reset( ttsize, 0 ); /* ignore return value */ } else { - SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; + SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; FT_Size_Metrics* metrics = &size->metrics; @@ -291,7 +336,7 @@ if ( FT_HAS_FIXED_SIZES( size->face ) ) { TT_Face ttface = (TT_Face)size->face; - SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; + SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; FT_ULong strike_index; @@ -309,8 +354,27 @@ if ( FT_IS_SCALABLE( size->face ) ) { - error = tt_size_reset( ttsize ); + error = tt_size_reset( ttsize, 0 ); ttsize->root.metrics = ttsize->metrics; + +#ifdef TT_USE_BYTECODE_INTERPRETER + /* for the `MPS' bytecode instruction we need the point size */ + { + FT_UInt resolution = ttsize->metrics.x_ppem > ttsize->metrics.y_ppem + ? req->horiResolution + : req->vertResolution; + + + /* if we don't have a resolution value, assume 72dpi */ + if ( req->type == FT_SIZE_REQUEST_TYPE_SCALES || + !resolution ) + resolution = 72; + + ttsize->point_size = FT_MulDiv( ttsize->ttmetrics.ppem, + 64 * 72, + resolution ); + } +#endif } return error; @@ -415,24 +479,45 @@ /*************************************************************************/ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_DEFINE_SERVICE_MULTIMASTERSREC( tt_service_gx_multi_masters, - (FT_Get_MM_Func) NULL, - (FT_Set_MM_Design_Func) NULL, - (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, - (FT_Get_MM_Var_Func) TT_Get_MM_Var, - (FT_Set_Var_Design_Func)TT_Set_Var_Design ) -#endif + + (FT_Get_MM_Func) NULL, /* get_mm */ + (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ + (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, /* set_mm_blend */ + (FT_Get_MM_Blend_Func) TT_Get_MM_Blend, /* get_mm_blend */ + (FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */ + (FT_Set_Var_Design_Func)TT_Set_Var_Design, /* set_var_design */ + (FT_Get_Var_Design_Func)TT_Get_Var_Design, /* get_var_design */ + + (FT_Get_Var_Blend_Func) tt_get_var_blend, /* get_var_blend */ + (FT_Done_Blend_Func) tt_done_blend /* done_blend */ + ) + + FT_DEFINE_SERVICE_METRICSVARIATIONSREC( + tt_service_metrics_variations, + + (FT_HAdvance_Adjust_Func)tt_hadvance_adjust, /* hadvance_adjust */ + (FT_LSB_Adjust_Func) NULL, /* lsb_adjust */ + (FT_RSB_Adjust_Func) NULL, /* rsb_adjust */ + + (FT_VAdvance_Adjust_Func)NULL, /* vadvance_adjust */ + (FT_TSB_Adjust_Func) NULL, /* tsb_adjust */ + (FT_BSB_Adjust_Func) NULL, /* bsb_adjust */ + (FT_VOrg_Adjust_Func) NULL, /* vorg_adjust */ + + (FT_Metrics_Adjust_Func) tt_apply_mvar /* metrics_adjust */ + ) + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = { #ifdef TT_USE_BYTECODE_INTERPRETER -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_TRUETYPE_ENGINE_TYPE_UNPATENTED -#else FT_TRUETYPE_ENGINE_TYPE_PATENTED -#endif #else /* !TT_USE_BYTECODE_INTERPRETER */ @@ -441,21 +526,28 @@ #endif /* TT_USE_BYTECODE_INTERPRETER */ }; + FT_DEFINE_SERVICE_TTGLYFREC( tt_service_truetype_glyf, - (TT_Glyf_GetLocationFunc)tt_face_get_location ) + + (TT_Glyf_GetLocationFunc)tt_face_get_location /* get_location */ + ) + #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_DEFINE_SERVICEDESCREC5( + FT_DEFINE_SERVICEDESCREC6( tt_services, - FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, - FT_SERVICE_ID_MULTI_MASTERS, &TT_SERVICE_GX_MULTI_MASTERS_GET, - FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, - FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, - FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) + + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, + FT_SERVICE_ID_MULTI_MASTERS, &TT_SERVICE_GX_MULTI_MASTERS_GET, + FT_SERVICE_ID_METRICS_VARIATIONS, &TT_SERVICE_METRICS_VARIATIONS_GET, + FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, + FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, + FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) #else FT_DEFINE_SERVICEDESCREC4( tt_services, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, @@ -483,7 +575,7 @@ #endif result = ft_service_list_lookup( TT_SERVICES_GET, tt_interface ); - if ( result != NULL ) + if ( result ) return result; #ifndef FT_CONFIG_OPTION_PIC @@ -534,31 +626,31 @@ 0x10000L, /* driver version == 1.0 */ 0x20000L, /* driver requires FreeType 2.0 or above */ - (void*)0, /* driver specific interface */ + NULL, /* module-specific interface */ - tt_driver_init, - tt_driver_done, - tt_get_interface, + tt_driver_init, /* FT_Module_Constructor module_init */ + tt_driver_done, /* FT_Module_Destructor module_done */ + tt_get_interface, /* FT_Module_Requester get_interface */ sizeof ( TT_FaceRec ), sizeof ( TT_SizeRec ), sizeof ( FT_GlyphSlotRec ), - tt_face_init, - tt_face_done, - tt_size_init, - tt_size_done, - tt_slot_init, - 0, /* FT_Slot_DoneFunc */ + tt_face_init, /* FT_Face_InitFunc init_face */ + tt_face_done, /* FT_Face_DoneFunc done_face */ + tt_size_init, /* FT_Size_InitFunc init_size */ + tt_size_done, /* FT_Size_DoneFunc done_size */ + tt_slot_init, /* FT_Slot_InitFunc init_slot */ + NULL, /* FT_Slot_DoneFunc done_slot */ - tt_glyph_load, + tt_glyph_load, /* FT_Slot_LoadFunc load_glyph */ - tt_get_kerning, - 0, /* FT_Face_AttachFunc */ - tt_get_advances, + tt_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ + tt_get_advances, /* FT_Face_GetAdvancesFunc get_advances */ - tt_size_request, - TT_SIZE_SELECT + tt_size_request, /* FT_Size_RequestFunc request_size */ + TT_SIZE_SELECT /* FT_Size_SelectFunc select_size */ ) diff --git a/third_party/freetype/src/truetype/ttdriver.h b/third_party/freetype/src/truetype/ttdriver.h index 6cacd60966..3bcba7f745 100644 --- a/third_party/freetype/src/truetype/ttdriver.h +++ b/third_party/freetype/src/truetype/ttdriver.h @@ -4,7 +4,7 @@ /* */ /* High-level TrueType driver interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTDRIVER_H__ -#define __TTDRIVER_H__ +#ifndef TTDRIVER_H_ +#define TTDRIVER_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTDRIVER_H__ */ +#endif /* TTDRIVER_H_ */ /* END */ diff --git a/third_party/freetype/src/truetype/tterrors.h b/third_party/freetype/src/truetype/tterrors.h index ba32cf744c..a49f205156 100644 --- a/third_party/freetype/src/truetype/tterrors.h +++ b/third_party/freetype/src/truetype/tterrors.h @@ -4,7 +4,7 @@ /* */ /* TrueType error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __TTERRORS_H__ -#define __TTERRORS_H__ +#ifndef TTERRORS_H_ +#define TTERRORS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX TT_Err_ @@ -36,6 +36,7 @@ #include FT_ERRORS_H -#endif /* __TTERRORS_H__ */ +#endif /* TTERRORS_H_ */ + /* END */ diff --git a/third_party/freetype/src/truetype/ttgload.c b/third_party/freetype/src/truetype/ttgload.c index a792ad44a0..64dc05c1c9 100644 --- a/third_party/freetype/src/truetype/ttgload.c +++ b/third_party/freetype/src/truetype/ttgload.c @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,6 +24,7 @@ #include FT_TRUETYPE_TAGS_H #include FT_OUTLINE_H #include FT_TRUETYPE_DRIVER_H +#include FT_LIST_H #include "ttgload.h" #include "ttpload.h" @@ -121,7 +122,7 @@ FT_UInt glyph_index ) { TT_Face face = loader->face; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); #endif @@ -152,7 +153,7 @@ loader->top_bearing = top_bearing; loader->vadvance = advance_height; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 && loader->exec ) { @@ -164,7 +165,7 @@ /* backwards compatibility mode on and off. */ sph_set_tweaks( loader, glyph_index ); } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ if ( !loader->linear_def ) { @@ -397,18 +398,18 @@ FT_TRACE5(( " Instructions size: %u\n", n_ins )); - /* check it */ - if ( ( limit - p ) < n_ins ) - { - FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); - error = FT_THROW( Too_Many_Hints ); - goto Fail; - } - #ifdef TT_USE_BYTECODE_INTERPRETER if ( IS_HINTED( load->load_flags ) ) { + /* check instructions size */ + if ( ( limit - p ) < n_ins ) + { + FT_TRACE1(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); + error = FT_THROW( Too_Many_Hints ); + goto Fail; + } + /* we don't trust `maxSizeOfInstructions' in the `maxp' table */ /* and thus update the bytecode array size by ourselves */ @@ -426,7 +427,8 @@ load->glyph->control_len = n_ins; load->glyph->control_data = load->exec->glyphIns; - FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins ); + if ( n_ins ) + FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins ); } #endif /* TT_USE_BYTECODE_INTERPRETER */ @@ -439,7 +441,7 @@ flag = (FT_Byte*)outline->tags; flag_limit = flag + n_points; - FT_ASSERT( flag != NULL ); + FT_ASSERT( flag ); while ( flag < flag_limit ) { @@ -659,6 +661,7 @@ } while ( subglyph->flags & MORE_COMPONENTS ); gloader->current.num_subglyphs = num_subglyphs; + FT_TRACE5(( " %d components\n", num_subglyphs )); #ifdef TT_USE_BYTECODE_INTERPRETER @@ -730,7 +733,8 @@ TT_Hint_Glyph( TT_Loader loader, FT_Bool is_composite ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \ + defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL TT_Face face = loader->face; TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); #endif @@ -813,13 +817,23 @@ #endif - /* save glyph phantom points */ - loader->pp1 = zone->cur[zone->n_points - 4]; - loader->pp2 = zone->cur[zone->n_points - 3]; - loader->pp3 = zone->cur[zone->n_points - 2]; - loader->pp4 = zone->cur[zone->n_points - 1]; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* Save possibly modified glyph phantom points unless in v40 backwards */ + /* compatibility mode, where no movement on the x axis means no reason */ + /* to change bearings or advance widths. */ + if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 && + !loader->exec->backwards_compatibility ) ) + { +#endif + loader->pp1 = zone->cur[zone->n_points - 4]; + loader->pp2 = zone->cur[zone->n_points - 3]; + loader->pp3 = zone->cur[zone->n_points - 2]; + loader->pp4 = zone->cur[zone->n_points - 1]; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + } +#endif -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN ) @@ -828,7 +842,7 @@ else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN ) FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 ); } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ return FT_Err_Ok; } @@ -872,13 +886,23 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( loader->face->doblend ) + if ( loader->face->doblend && !loader->face->is_default_instance ) { /* Deltas apply to the unscaled data. */ error = TT_Vary_Apply_Glyph_Deltas( loader->face, loader->glyph_index, outline, (FT_UInt)n_points ); + + /* recalculate linear horizontal and vertical advances */ + /* if we don't have HVAR and VVAR, respectively */ + if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + loader->linear = outline->points[n_points - 3].x - + outline->points[n_points - 4].x; + if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + loader->vadvance = outline->points[n_points - 1].x - + outline->points[n_points - 2].x; + if ( error ) return error; } @@ -894,7 +918,7 @@ } { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY TT_Face face = loader->face; TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); @@ -913,7 +937,7 @@ FT_Bool do_scale = FALSE; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { @@ -944,7 +968,7 @@ } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ { /* scale the glyph */ @@ -1075,7 +1099,7 @@ : -subglyph->transform.yx; int c = subglyph->transform.xy > 0 ? subglyph->transform.xy : -subglyph->transform.xy; - int d = subglyph->transform.yy > 0 ? subglyph->transform.yy + int d = subglyph->transform.yy > 0 ? subglyph->transform.yy : -subglyph->transform.yy; int m = a > b ? a : b; int n = c > d ? c : d; @@ -1321,49 +1345,71 @@ * (3) for everything else. * */ + static void + tt_loader_set_pp( TT_Loader loader ) + { + FT_Bool subpixel_hinting = 0; + FT_Bool grayscale = 0; + FT_Bool use_aw_2 = 0; + #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( loader->face ); +#endif + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) + { + subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting + : 0; + grayscale = loader->exec ? loader->exec->grayscale + : 0; + } +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) + { + subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting_lean + : 0; + grayscale = loader->exec ? loader->exec->grayscale_cleartype + : 0; + } +#endif + + use_aw_2 = (FT_Bool)( subpixel_hinting && grayscale ); + + loader->pp1.x = loader->bbox.xMin - loader->left_bearing; + loader->pp1.y = 0; + loader->pp2.x = loader->pp1.x + loader->advance; + loader->pp2.y = 0; + + loader->pp3.x = use_aw_2 ? loader->advance / 2 : 0; + loader->pp3.y = loader->bbox.yMax + loader->top_bearing; + loader->pp4.x = use_aw_2 ? loader->advance / 2 : 0; + loader->pp4.y = loader->pp3.y - loader->vadvance; + } + -#define TT_LOADER_SET_PP( loader ) \ - do \ - { \ - FT_Bool subpixel_hinting_ = loader->exec \ - ? loader->exec->subpixel_hinting \ - : 0; \ - FT_Bool grayscale_ = loader->exec \ - ? loader->exec->grayscale \ - : 0; \ - FT_Bool use_aw_2_ = (FT_Bool)( subpixel_hinting_ && \ - grayscale_ ); \ - \ - \ - (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \ - (loader)->pp1.y = 0; \ - (loader)->pp2.x = (loader)->pp1.x + (loader)->advance; \ - (loader)->pp2.y = 0; \ - \ - (loader)->pp3.x = use_aw_2_ ? (loader)->advance / 2 : 0; \ - (loader)->pp3.y = (loader)->bbox.yMax + (loader)->top_bearing; \ - (loader)->pp4.x = use_aw_2_ ? (loader)->advance / 2 : 0; \ - (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \ - } while ( 0 ) - -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - -#define TT_LOADER_SET_PP( loader ) \ - do \ - { \ - (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \ - (loader)->pp1.y = 0; \ - (loader)->pp2.x = (loader)->pp1.x + (loader)->advance; \ - (loader)->pp2.y = 0; \ - \ - (loader)->pp3.x = 0; \ - (loader)->pp3.y = (loader)->bbox.yMax + (loader)->top_bearing; \ - (loader)->pp4.x = 0; \ - (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \ - } while ( 0 ) - -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + /* a utility function to retrieve i-th node from given FT_List */ + static FT_ListNode + ft_list_get_node_at( FT_List list, + FT_UInt index ) + { + FT_ListNode cur; + + + if ( !list ) + return NULL; + + for ( cur = list->head; cur; cur = cur->next ) + { + if ( !index ) + return cur; + + index--; + } + + return NULL; + } /*************************************************************************/ @@ -1395,13 +1441,17 @@ #endif - /* some fonts have an incorrect value of `maxComponentDepth', */ - /* thus we allow depth 1 to catch the majority of them */ - if ( recurse_count > 1 && - recurse_count > face->max_profile.maxComponentDepth ) +#ifdef FT_DEBUG_LEVEL_TRACE + if ( recurse_count ) + FT_TRACE5(( " nesting level: %d\n", recurse_count )); +#endif + + /* some fonts have an incorrect value of `maxComponentDepth' */ + if ( recurse_count > face->max_profile.maxComponentDepth ) { - error = FT_THROW( Invalid_Composite ); - goto Exit; + FT_TRACE1(( "load_truetype_glyph: maxComponentDepth set to %d\n", + recurse_count )); + face->max_profile.maxComponentDepth = (FT_UShort)recurse_count; } #ifndef FT_CONFIG_OPTION_INCREMENTAL @@ -1447,7 +1497,7 @@ offset = 0; loader->byte_len = glyph_data.length; - FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) ); + FT_ZERO( &inc_stream ); FT_Stream_OpenMemory( &inc_stream, glyph_data.pointer, (FT_ULong)glyph_data.length ); @@ -1465,10 +1515,10 @@ { #ifdef FT_CONFIG_OPTION_INCREMENTAL /* for the incremental interface, `glyf_offset' is always zero */ - if ( !loader->glyf_offset && + if ( !face->glyf_offset && !face->root.internal->incremental_interface ) #else - if ( !loader->glyf_offset ) + if ( !face->glyf_offset ) #endif /* FT_CONFIG_OPTION_INCREMENTAL */ { FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" )); @@ -1477,7 +1527,7 @@ } error = face->access_glyph_frame( loader, glyph_index, - loader->glyf_offset + offset, + face->glyf_offset + offset, (FT_UInt)loader->byte_len ); if ( error ) goto Exit; @@ -1516,7 +1566,7 @@ /* must initialize points before (possibly) overriding */ /* glyph metrics from the incremental interface */ - TT_LOADER_SET_PP( loader ); + tt_loader_set_pp( loader ); #ifdef FT_CONFIG_OPTION_INCREMENTAL tt_get_metrics_incr_overrides( loader, glyph_index ); @@ -1524,7 +1574,7 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( loader->face->doblend ) + if ( loader->face->doblend && !loader->face->is_default_instance ) { /* a small outline structure with four elements for */ /* communication with `TT_Vary_Apply_Glyph_Deltas' */ @@ -1567,6 +1617,14 @@ loader->pp3.y = points[2].y; loader->pp4.x = points[3].x; loader->pp4.y = points[3].y; + + + /* recalculate linear horizontal and vertical advances */ + /* if we don't have HVAR and VVAR, respectively */ + if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + loader->linear = loader->pp2.x - loader->pp1.x; + if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + loader->vadvance = loader->pp4.x - loader->pp3.x; } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ @@ -1591,7 +1649,7 @@ /* must initialize phantom points before (possibly) overriding */ /* glyph metrics from the incremental interface */ - TT_LOADER_SET_PP( loader ); + tt_loader_set_pp( loader ); #ifdef FT_CONFIG_OPTION_INCREMENTAL tt_get_metrics_incr_overrides( loader, glyph_index ); @@ -1627,10 +1685,48 @@ /* otherwise, load a composite! */ else if ( loader->n_contours == -1 ) { + FT_Memory memory = face->root.memory; + FT_UInt start_point; FT_UInt start_contour; FT_ULong ins_pos; /* position of composite instructions, if any */ + FT_ListNode node, node2; + + + /* + * We store the glyph index directly in the `node->data' pointer, + * following the glib solution (cf. macro `GUINT_TO_POINTER') with a + * double cast to make this portable. Note, however, that this needs + * pointers with a width of at least 32 bits. + */ + + + /* clear the nodes filled by sibling chains */ + node = ft_list_get_node_at( &loader->composites, recurse_count ); + for ( node2 = node; node2; node2 = node2->next ) + node2->data = (void*)ULONG_MAX; + + /* check whether we already have a composite glyph with this index */ + if ( FT_List_Find( &loader->composites, + (void*)(unsigned long)glyph_index ) ) + { + FT_TRACE1(( "TT_Load_Composite_Glyph:" + " infinite recursion detected\n" )); + error = FT_THROW( Invalid_Composite ); + goto Exit; + } + + else if ( node ) + node->data = (void*)(unsigned long)glyph_index; + + else + { + if ( FT_NEW( node ) ) + goto Exit; + node->data = (void*)(unsigned long)glyph_index; + FT_List_Add( &loader->composites, node ); + } start_point = (FT_UInt)gloader->base.outline.n_points; start_contour = (FT_UInt)gloader->base.outline.n_contours; @@ -1649,7 +1745,7 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( face->doblend ) + if ( face->doblend && !face->is_default_instance ) { short i, limit; FT_SubGlyph subglyph; @@ -1659,8 +1755,6 @@ char* tags = NULL; short* contours = NULL; - FT_Memory memory = face->root.memory; - limit = (short)gloader->current.num_subglyphs; @@ -1669,6 +1763,10 @@ outline.n_points = (short)( gloader->current.num_subglyphs + 4 ); outline.n_contours = outline.n_points; + outline.points = NULL; + outline.tags = NULL; + outline.contours = NULL; + if ( FT_NEW_ARRAY( points, outline.n_points ) || FT_NEW_ARRAY( tags, outline.n_points ) || FT_NEW_ARRAY( contours, outline.n_points ) ) @@ -1716,22 +1814,22 @@ /* this call provides additional offsets */ /* for each component's translation */ - if ( ( error = TT_Vary_Apply_Glyph_Deltas( - face, - glyph_index, - &outline, - (FT_UInt)outline.n_points ) ) != 0 ) + if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas( + face, + glyph_index, + &outline, + (FT_UInt)outline.n_points ) ) ) goto Exit1; subglyph = gloader->current.subglyphs; for ( i = 0; i < limit; i++, subglyph++ ) { - /* XXX: overflow check for subglyph->{arg1,arg2}. */ - /* Deltas must be within signed 16-bit, */ - /* but the restriction of summed deltas is not clear */ - subglyph->arg1 = (FT_Int16)points[i].x; - subglyph->arg2 = (FT_Int16)points[i].y; + if ( subglyph->flags & ARGS_ARE_XY_VALUES ) + { + subglyph->arg1 = (FT_Int16)points[i].x; + subglyph->arg2 = (FT_Int16)points[i].y; + } } loader->pp1.x = points[i + 0].x; @@ -1744,6 +1842,13 @@ loader->pp4.x = points[i + 3].x; loader->pp4.y = points[i + 3].y; + /* recalculate linear horizontal and vertical advances */ + /* if we don't have HVAR and VVAR, respectively */ + if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + loader->linear = loader->pp2.x - loader->pp1.x; + if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + loader->vadvance = loader->pp4.x - loader->pp3.x; + Exit1: FT_FREE( outline.points ); FT_FREE( outline.tags ); @@ -1803,6 +1908,9 @@ { FT_Vector pp[4]; + FT_Int linear_hadvance; + FT_Int linear_vadvance; + /* Each time we call load_truetype_glyph in this loop, the */ /* value of `gloader.base.subglyphs' can change due to table */ @@ -1815,6 +1923,9 @@ pp[2] = loader->pp3; pp[3] = loader->pp4; + linear_hadvance = loader->linear; + linear_vadvance = loader->vadvance; + num_base_points = (FT_UInt)gloader->base.outline.n_points; error = load_truetype_glyph( loader, @@ -1834,6 +1945,9 @@ loader->pp2 = pp[1]; loader->pp3 = pp[2]; loader->pp4 = pp[3]; + + loader->linear = linear_hadvance; + loader->vadvance = linear_vadvance; } num_points = (FT_UInt)gloader->base.outline.n_points; @@ -1908,7 +2022,8 @@ FT_UInt glyph_index ) { TT_Face face = loader->face; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \ + defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); #endif @@ -1935,11 +2050,18 @@ glyph->metrics.horiBearingY = bbox.yMax; glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - /* adjust advance width to the value contained in the hdmx table */ - /* unless FT_LOAD_COMPUTE_METRICS is set */ - if ( !face->postscript.isFixedPitch && - IS_HINTED( loader->load_flags ) && - !( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) ) + /* Adjust advance width to the value contained in the hdmx table */ + /* unless FT_LOAD_COMPUTE_METRICS is set or backwards compatibility */ + /* mode of the v40 interpreter is active. See `ttinterp.h' for */ + /* details on backwards compatibility mode. */ + if ( +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 && + ( loader->exec && loader->exec->backwards_compatibility ) ) && +#endif + !face->postscript.isFixedPitch && + IS_HINTED( loader->load_flags ) && + !( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) ) { FT_Byte* widthp; @@ -1948,7 +2070,7 @@ size->root.metrics.x_ppem, glyph_index ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { @@ -1966,7 +2088,7 @@ } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ { if ( widthp ) @@ -2155,12 +2277,16 @@ #ifdef TT_USE_BYTECODE_INTERPRETER FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); #endif +#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \ + defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( (TT_Face)glyph->face ); +#endif face = (TT_Face)glyph->face; stream = face->root.stream; - FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) ); + FT_ZERO( loader ); #ifdef TT_USE_BYTECODE_INTERPRETER @@ -2168,11 +2294,13 @@ if ( IS_HINTED( load_flags ) && !glyf_table_only ) { TT_ExecContext exec; - FT_Bool grayscale; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); + FT_Bool grayscale = TRUE; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + FT_Bool subpixel_hinting_lean; + FT_Bool grayscale_cleartype; +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_Bool subpixel_hinting = FALSE; #if 0 @@ -2184,7 +2312,7 @@ FT_Bool subpixel_positioned; FT_Bool gray_cleartype; #endif -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ FT_Bool reexecute = FALSE; @@ -2205,7 +2333,26 @@ if ( !exec ) return FT_THROW( Could_Not_Find_Context ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) + { + subpixel_hinting_lean = TRUE; + grayscale_cleartype = !FT_BOOL( load_flags & + FT_LOAD_TARGET_LCD || + load_flags & + FT_LOAD_TARGET_LCD_V ); + exec->vertical_lcd_lean = FT_BOOL( load_flags & + FT_LOAD_TARGET_LCD_V ); + } + else + { + subpixel_hinting_lean = FALSE; + grayscale_cleartype = FALSE; + exec->vertical_lcd_lean = FALSE; + } +#endif + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { @@ -2262,18 +2409,23 @@ } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - { +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) + grayscale = FT_BOOL( !subpixel_hinting_lean && + FT_LOAD_TARGET_MODE( load_flags ) != + FT_RENDER_MODE_MONO ); + else +#endif grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - FT_RENDER_MODE_MONO ); - } + FT_RENDER_MODE_MONO ); error = TT_Load_Context( exec, face, size ); if ( error ) return error; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { @@ -2301,9 +2453,37 @@ } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ { + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) + { + /* a change from mono to subpixel rendering (and vice versa) */ + /* requires a re-execution of the CVT program */ + if ( subpixel_hinting_lean != exec->subpixel_hinting_lean ) + { + FT_TRACE4(( "tt_loader_init: subpixel hinting change," + " re-executing `prep' table\n" )); + + exec->subpixel_hinting_lean = subpixel_hinting_lean; + reexecute = TRUE; + } + + /* a change from colored to grayscale subpixel rendering (and */ + /* vice versa) requires a re-execution of the CVT program */ + if ( grayscale_cleartype != exec->grayscale_cleartype ) + { + FT_TRACE4(( "tt_loader_init: grayscale subpixel hinting change," + " re-executing `prep' table\n" )); + + exec->grayscale_cleartype = grayscale_cleartype; + reexecute = TRUE; + } + } +#endif + /* a change from mono to grayscale rendering (and vice versa) */ /* requires a re-execution of the CVT program */ if ( grayscale != exec->grayscale ) @@ -2336,10 +2516,11 @@ if ( exec->GS.instruct_control & 2 ) exec->GS = tt_default_graphics_state; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* check whether we have a font hinted for ClearType -- */ /* note that this flag can also be modified in a glyph's bytecode */ - if ( exec->GS.instruct_control & 4 ) + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 && + exec->GS.instruct_control & 4 ) exec->ignore_x_mode = 0; #endif @@ -2350,32 +2531,6 @@ #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 */ - /* else... */ - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - if ( face->root.internal->incremental_interface ) - loader->glyf_offset = 0; - else - -#endif - - { - error = face->goto_table( face, TTAG_glyf, stream, 0 ); - - if ( FT_ERR_EQ( error, Table_Missing ) ) - loader->glyf_offset = 0; - else if ( error ) - { - FT_ERROR(( "tt_loader_init: could not access glyph table\n" )); - return error; - } - else - loader->glyf_offset = FT_STREAM_POS(); - } - /* get face's glyph loader */ if ( !glyf_table_only ) { @@ -2393,10 +2548,23 @@ loader->glyph = (FT_GlyphSlot)glyph; loader->stream = stream; + loader->composites.head = NULL; + loader->composites.tail = NULL; + return FT_Err_Ok; } + static void + tt_loader_done( TT_Loader loader ) + { + FT_List_Finalize( &loader->composites, + NULL, + loader->face->root.memory, + NULL ); + } + + /*************************************************************************/ /* */ /* <Function> */ @@ -2433,17 +2601,21 @@ FT_Error error; TT_LoaderRec loader; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#define IS_DEFAULT_INSTANCE ( ( (TT_Face)glyph->face )->is_default_instance ) +#else +#define IS_DEFAULT_INSTANCE 1 +#endif + FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index )); #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - /* try to load embedded bitmap if any */ - /* */ - /* XXX: The convention should be emphasized in */ - /* the documents because it can be confusing. */ + /* try to load embedded bitmap (if any) */ if ( size->strike_index != 0xFFFFFFFFUL && - ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) + ( load_flags & FT_LOAD_NO_BITMAP ) == 0 && + IS_DEFAULT_INSTANCE ) { error = load_sbit_image( size, glyph, glyph_index, load_flags ); if ( !error ) @@ -2453,6 +2625,7 @@ /* for the bbox we need the header only */ (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE ); (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE ); + tt_loader_done( &loader ); glyph->linearHoriAdvance = loader.linear; glyph->linearVertAdvance = loader.vadvance; @@ -2476,14 +2649,20 @@ /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */ if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid ) - return FT_THROW( Invalid_Size_Handle ); + { + error = FT_THROW( Invalid_Size_Handle ); + goto Exit; + } if ( load_flags & FT_LOAD_SBITS_ONLY ) - return FT_THROW( Invalid_Argument ); + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } error = tt_loader_init( &loader, size, glyph, load_flags, FALSE ); if ( error ) - return error; + goto Exit; glyph->format = FT_GLYPH_FORMAT_OUTLINE; glyph->num_subglyphs = 0; @@ -2548,6 +2727,8 @@ error = compute_glyph_metrics( &loader, glyph_index ); } + tt_loader_done( &loader ); + /* Set the `high precision' bit flag. */ /* This is _critical_ to get correct output for monochrome */ /* TrueType glyphs at all sizes using the bytecode interpreter. */ @@ -2556,6 +2737,13 @@ size->root.metrics.y_ppem < 24 ) glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; + Exit: +#ifdef FT_DEBUG_LEVEL_TRACE + if ( error ) + FT_TRACE1(( " failed (error code 0x%x)\n", + error )); +#endif + return error; } diff --git a/third_party/freetype/src/truetype/ttgload.h b/third_party/freetype/src/truetype/ttgload.h index 8e3255e106..1dd6c841db 100644 --- a/third_party/freetype/src/truetype/ttgload.h +++ b/third_party/freetype/src/truetype/ttgload.h @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTGLOAD_H__ -#define __TTGLOAD_H__ +#ifndef TTGLOAD_H_ +#define TTGLOAD_H_ #include <ft2build.h> @@ -56,7 +56,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTGLOAD_H__ */ +#endif /* TTGLOAD_H_ */ /* END */ diff --git a/third_party/freetype/src/truetype/ttinterp.c b/third_party/freetype/src/truetype/ttinterp.c index ae2a82adc5..6ea1a80bb1 100644 --- a/third_party/freetype/src/truetype/ttinterp.c +++ b/third_party/freetype/src/truetype/ttinterp.c @@ -4,7 +4,7 @@ /* */ /* TrueType bytecode interpreter (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,10 +26,14 @@ #include FT_TRIGONOMETRY_H #include FT_SYSTEM_H #include FT_TRUETYPE_DRIVER_H +#include FT_MULTIPLE_MASTERS_H #include "ttinterp.h" #include "tterrors.h" #include "ttsubpix.h" +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include "ttgxvar.h" +#endif #ifdef TT_USE_BYTECODE_INTERPRETER @@ -45,19 +49,21 @@ #define FT_COMPONENT trace_ttinterp - /*************************************************************************/ - /* */ - /* In order to detect infinite loops in the code, we set up a counter */ - /* within the run loop. A single stroke of interpretation is now */ - /* limited to a maximum number of opcodes defined below. */ - /* */ -#define MAX_RUNNABLE_OPCODES 1000000L - +#define NO_SUBPIXEL_HINTING \ + ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ + TT_INTERPRETER_VERSION_35 ) -#define SUBPIXEL_HINTING \ +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY +#define SUBPIXEL_HINTING_INFINALITY \ ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ TT_INTERPRETER_VERSION_38 ) +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL +#define SUBPIXEL_HINTING_MINIMAL \ + ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ + TT_INTERPRETER_VERSION_40 ) +#endif #define PROJECT( v1, v2 ) \ exc->func_project( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y ) @@ -74,14 +80,6 @@ /*************************************************************************/ /* */ - /* Instruction dispatch function, as used by the interpreter. */ - /* */ - typedef void (*TInstruction_Function)( TT_ExecContext exc, - FT_Long* args ); - - - /*************************************************************************/ - /* */ /* Two simple bounds-checking macros. */ /* */ #define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) @@ -94,20 +92,6 @@ #undef FAILURE #define FAILURE 1 -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING -#define GUESS_VECTOR( V ) \ - do \ - { \ - if ( exc->face->unpatented_hinting ) \ - { \ - exc->GS.V.x = (FT_F2Dot14)( exc->GS.both_x_axis ? 0x4000 : 0 ); \ - exc->GS.V.y = (FT_F2Dot14)( exc->GS.both_x_axis ? 0 : 0x4000 ); \ - } \ - } while (0) -#else -#define GUESS_VECTOR( V ) do { } while (0) -#endif - /*************************************************************************/ /* */ @@ -145,7 +129,7 @@ coderange = &exec->codeRangeTable[range - 1]; - FT_ASSERT( coderange->base != NULL ); + FT_ASSERT( coderange->base ); /* NOTE: Because the last instruction of a program may be a CALL */ /* which will return to the first byte *after* the code */ @@ -309,8 +293,8 @@ exec->stackSize = 0; exec->glyphSize = 0; - exec->stack = NULL; - exec->glyphIns = NULL; + exec->stack = NULL; + exec->glyphIns = NULL; exec->face = NULL; exec->size = NULL; @@ -416,6 +400,7 @@ exec->maxIDefs = size->max_instruction_defs; exec->FDefs = size->function_defs; exec->IDefs = size->instruction_defs; + exec->pointSize = size->point_size; exec->tt_metrics = size->ttmetrics; exec->metrics = size->metrics; @@ -438,7 +423,7 @@ /* In case of multi-threading it can happen that the old size object */ /* no longer exists, thus we must clear all glyph zone references. */ - ft_memset( &exec->zp0, 0, sizeof ( exec->zp0 ) ); + FT_ZERO( &exec->zp0 ); exec->zp1 = exec->zp0; exec->zp2 = exec->zp0; } @@ -556,10 +541,6 @@ exec->GS.freeVector = exec->GS.projVector; exec->GS.dualVector = exec->GS.projVector; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - exec->GS.both_x_axis = TRUE; -#endif - exec->GS.round_state = 1; exec->GS.loop = 1; @@ -586,10 +567,6 @@ { 0x4000, 0 }, { 0x4000, 0 }, -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - TRUE, -#endif - 1, 64, 1, TRUE, 68, 0, 0, 9, 3, 0, FALSE, 0, 1, 1, 1 @@ -709,17 +686,17 @@ /* IUP[0] */ PACK( 0, 0 ), /* IUP[1] */ PACK( 0, 0 ), - /* SHP[0] */ PACK( 0, 0 ), - /* SHP[1] */ PACK( 0, 0 ), + /* SHP[0] */ PACK( 0, 0 ), /* loops */ + /* SHP[1] */ PACK( 0, 0 ), /* loops */ /* SHC[0] */ PACK( 1, 0 ), /* SHC[1] */ PACK( 1, 0 ), /* SHZ[0] */ PACK( 1, 0 ), /* SHZ[1] */ PACK( 1, 0 ), - /* SHPIX */ PACK( 1, 0 ), - /* IP */ PACK( 0, 0 ), + /* SHPIX */ PACK( 1, 0 ), /* loops */ + /* IP */ PACK( 0, 0 ), /* loops */ /* MSIRP[0] */ PACK( 2, 0 ), /* MSIRP[1] */ PACK( 2, 0 ), - /* AlignRP */ PACK( 0, 0 ), + /* AlignRP */ PACK( 0, 0 ), /* loops */ /* RTDG */ PACK( 0, 0 ), /* MIAP[0] */ PACK( 2, 0 ), /* MIAP[1] */ PACK( 2, 0 ), @@ -792,7 +769,7 @@ /* SANGW */ PACK( 1, 0 ), /* AA */ PACK( 1, 0 ), - /* FlipPT */ PACK( 0, 0 ), + /* FlipPT */ PACK( 0, 0 ), /* loops */ /* FlipRgON */ PACK( 2, 0 ), /* FlipRgOFF */ PACK( 2, 0 ), /* INS_$83 */ PACK( 0, 0 ), @@ -810,8 +787,8 @@ /* INS_$8F */ PACK( 0, 0 ), /* INS_$90 */ PACK( 0, 0 ), - /* INS_$91 */ PACK( 0, 0 ), - /* INS_$92 */ PACK( 0, 0 ), + /* GETVAR */ PACK( 0, 0 ), /* will be handled specially */ + /* GETDATA */ PACK( 0, 1 ), /* INS_$93 */ PACK( 0, 0 ), /* INS_$94 */ PACK( 0, 0 ), /* INS_$95 */ PACK( 0, 0 ), @@ -1093,8 +1070,13 @@ "7 INS_$8F", "7 INS_$90", +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + "6 GETVAR", + "7 GETDATA", +#else "7 INS_$91", "7 INS_$92", +#endif "7 INS_$93", "7 INS_$94", "7 INS_$95", @@ -1479,34 +1461,22 @@ { if ( !exc->tt_metrics.ratio ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( exc->face->unpatented_hinting ) - { - if ( exc->GS.both_x_axis ) - exc->tt_metrics.ratio = exc->tt_metrics.x_ratio; - else - exc->tt_metrics.ratio = exc->tt_metrics.y_ratio; - } - else -#endif - { - if ( exc->GS.projVector.y == 0 ) - exc->tt_metrics.ratio = exc->tt_metrics.x_ratio; + if ( exc->GS.projVector.y == 0 ) + exc->tt_metrics.ratio = exc->tt_metrics.x_ratio; - else if ( exc->GS.projVector.x == 0 ) - exc->tt_metrics.ratio = exc->tt_metrics.y_ratio; + else if ( exc->GS.projVector.x == 0 ) + exc->tt_metrics.ratio = exc->tt_metrics.y_ratio; - else - { - FT_F26Dot6 x, y; + else + { + FT_F26Dot6 x, y; - x = TT_MulFix14( exc->tt_metrics.x_ratio, - exc->GS.projVector.x ); - y = TT_MulFix14( exc->tt_metrics.y_ratio, - exc->GS.projVector.y ); - exc->tt_metrics.ratio = FT_Hypot( x, y ); - } + x = TT_MulFix14( exc->tt_metrics.x_ratio, + exc->GS.projVector.x ); + y = TT_MulFix14( exc->tt_metrics.y_ratio, + exc->GS.projVector.y ); + exc->tt_metrics.ratio = FT_Hypot( x, y ); } } return exc->tt_metrics.ratio; @@ -1604,7 +1574,7 @@ static FT_Short GetShortIns( TT_ExecContext exc ) { - /* Reading a byte stream so there is no endianess (DaveP) */ + /* Reading a byte stream so there is no endianness (DaveP) */ exc->IP += 2; return (FT_Short)( ( exc->code[exc->IP - 2] << 8 ) + exc->code[exc->IP - 1] ); @@ -1643,7 +1613,7 @@ range = &exc->codeRangeTable[aRange - 1]; - if ( range->base == NULL ) /* invalid coderange */ + if ( !range->base ) /* invalid coderange */ { exc->error = FT_THROW( Invalid_CodeRange ); return FAILURE; @@ -1685,6 +1655,10 @@ /* <InOut> */ /* zone :: The affected glyph zone. */ /* */ + /* <Note> */ + /* See `ttinterp.h' for details on backwards compatibility mode. */ + /* `Touches' the point. */ + /* */ static void Direct_Move( TT_ExecContext exc, TT_GlyphZone zone, @@ -1694,19 +1668,28 @@ FT_F26Dot6 v; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_ASSERT( !exc->face->unpatented_hinting ); -#endif - v = exc->GS.freeVector.x; if ( v != 0 ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( !SUBPIXEL_HINTING || +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && ( !exc->ignore_x_mode || ( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); + else +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* Exception to the post-IUP curfew: Allow the x component of */ + /* diagonal moves, but only post-IUP. DejaVu tries to adjust */ + /* diagonal stems like on `Z' and `z' post-IUP. */ + if ( SUBPIXEL_HINTING_MINIMAL && !exc->backwards_compatibility ) + zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); + else +#endif + + if ( NO_SUBPIXEL_HINTING ) zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; @@ -1716,7 +1699,13 @@ if ( v != 0 ) { - zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( !( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && + exc->iupy_called ) ) +#endif + zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } @@ -1749,10 +1738,6 @@ FT_F26Dot6 v; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_ASSERT( !exc->face->unpatented_hinting ); -#endif - v = exc->GS.freeVector.x; if ( v != 0 ) @@ -1771,6 +1756,7 @@ /* */ /* The following versions are used whenever both vectors are both */ /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ + /* See `ttinterp.h' for details on backwards compatibility mode. */ /* */ /*************************************************************************/ @@ -1781,12 +1767,19 @@ FT_UShort point, FT_F26Dot6 distance ) { - FT_UNUSED( exc ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && !exc->ignore_x_mode ) + zone->cur[point].x += distance; + else +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( !SUBPIXEL_HINTING || - !exc->ignore_x_mode ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( SUBPIXEL_HINTING_MINIMAL && !exc->backwards_compatibility ) + zone->cur[point].x += distance; + else +#endif + + if ( NO_SUBPIXEL_HINTING ) zone->cur[point].x += distance; zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; @@ -1801,8 +1794,14 @@ { FT_UNUSED( exc ); - zone->cur[point].y += distance; - zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( !( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && exc->iupy_called ) ) +#endif + zone->cur[point].y += distance; + + zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } @@ -2081,7 +2080,7 @@ FT_F26Dot6 distance, FT_F26Dot6 compensation ) { - FT_F26Dot6 val; + FT_F26Dot6 val; FT_UNUSED( exc ); @@ -2120,7 +2119,7 @@ /* Rounded distance. */ /* */ /* <Note> */ - /* The TrueType specification says very few about the relationship */ + /* The TrueType specification says very little about the relationship */ /* between rounding and engine compensation. However, it seems from */ /* the description of super round that we should add the compensation */ /* before rounding. */ @@ -2345,10 +2344,6 @@ FT_Pos dx, FT_Pos dy ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_ASSERT( !exc->face->unpatented_hinting ); -#endif - return TT_DotFix14( dx, dy, exc->GS.projVector.x, exc->GS.projVector.y ); @@ -2450,51 +2445,6 @@ static void Compute_Funcs( TT_ExecContext exc ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( exc->face->unpatented_hinting ) - { - /* If both vectors point rightwards along the x axis, set */ - /* `both-x-axis' true, otherwise set it false. The x values only */ - /* need be tested because the vector has been normalised to a unit */ - /* vector of length 0x4000 = unity. */ - exc->GS.both_x_axis = (FT_Bool)( exc->GS.projVector.x == 0x4000 && - exc->GS.freeVector.x == 0x4000 ); - - /* Throw away projection and freedom vector information */ - /* because the patents don't allow them to be stored. */ - /* The relevant US Patents are 5155805 and 5325479. */ - exc->GS.projVector.x = 0; - exc->GS.projVector.y = 0; - exc->GS.freeVector.x = 0; - exc->GS.freeVector.y = 0; - - if ( exc->GS.both_x_axis ) - { - exc->func_project = Project_x; - exc->func_move = Direct_Move_X; - exc->func_move_orig = Direct_Move_Orig_X; - } - else - { - exc->func_project = Project_y; - exc->func_move = Direct_Move_Y; - exc->func_move_orig = Direct_Move_Orig_Y; - } - - if ( exc->GS.dualVector.x == 0x4000 ) - exc->func_dualproj = Project_x; - else if ( exc->GS.dualVector.y == 0x4000 ) - exc->func_dualproj = Project_y; - else - exc->func_dualproj = Dual_Project; - - /* Force recalculation of cached aspect ratio */ - exc->tt_metrics.ratio = 0; - - return; - } -#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */ - if ( exc->GS.freeVector.x == 0x4000 ) exc->F_dot_P = exc->GS.projVector.x; else if ( exc->GS.freeVector.y == 0x4000 ) @@ -2634,13 +2584,20 @@ Ins_MPS( TT_ExecContext exc, FT_Long* args ) { - /* Note: The point size should be irrelevant in a given font program; */ - /* we thus decide to return only the PPEM value. */ -#if 0 - args[0] = exc->metrics.pointSize; -#else - args[0] = exc->func_cur_ppem( exc ); -#endif + if ( NO_SUBPIXEL_HINTING ) + { + /* Microsoft's GDI bytecode interpreter always returns value 12; */ + /* we return the current PPEM value instead. */ + args[0] = exc->func_cur_ppem( exc ); + } + else + { + /* A possible practical application of the MPS instruction is to */ + /* implement optical scaling and similar features, which should be */ + /* based on perceptual attributes, thus independent of the */ + /* resolution. */ + args[0] = exc->pointSize; + } } @@ -2933,7 +2890,7 @@ /* */ /* NEG[]: NEGate */ /* Opcode range: 0x65 */ - /* Stack: f26.6 --> f26.6 */ + /* Stack: f26.6 --> f26.6 */ /* */ static void Ins_NEG( FT_Long* args ) @@ -2978,8 +2935,6 @@ Ins_RS( TT_ExecContext exc, FT_Long* args ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_ULong I = (FT_ULong)args[0]; @@ -2992,9 +2947,10 @@ } else { +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* subpixel hinting - avoid Typeman Dstroke and */ /* IStroke and Vacuform rounds */ - if ( SUBPIXEL_HINTING && + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && ( ( I == 24 && ( exc->face->sph_found_func_flags & @@ -3009,25 +2965,9 @@ exc->iup_called ) ) ) args[0] = 0; else +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ args[0] = exc->storage[I]; } - -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - FT_ULong I = (FT_ULong)args[0]; - - - if ( BOUNDSL( I, exc->storeSize ) ) - { - if ( exc->pedantic_hinting ) - ARRAY_BOUND_ERROR; - else - args[0] = 0; - } - else - args[0] = exc->storage[I]; - -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ } @@ -3190,7 +3130,7 @@ /*************************************************************************/ /* */ /* MAX[]: MAXimum */ - /* Opcode range: 0x68 */ + /* Opcode range: 0x8B */ /* Stack: int32? int32? --> int32 */ /* */ static void @@ -3204,7 +3144,7 @@ /*************************************************************************/ /* */ /* MIN[]: MINimum */ - /* Opcode range: 0x69 */ + /* Opcode range: 0x8C */ /* Stack: int32? int32? --> int32 */ /* */ static void @@ -3448,13 +3388,27 @@ FT_Long* args ) { if ( args[0] == 0 && exc->args == 0 ) + { exc->error = FT_THROW( Bad_Argument ); + return; + } + exc->IP += args[0]; if ( exc->IP < 0 || ( exc->callTop > 0 && exc->IP > exc->callStack[exc->callTop - 1].Def->end ) ) + { exc->error = FT_THROW( Bad_Argument ); + return; + } + exc->step_ins = FALSE; + + if ( args[0] < 0 ) + { + if ( ++exc->neg_jump_counter > exc->neg_jump_counter_max ) + exc->error = FT_THROW( Execution_Too_Long ); + } } @@ -3509,7 +3463,7 @@ TT_DefRecord* rec; TT_DefRecord* limit; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* arguments to opcodes are skipped by `SKIP_Code' */ FT_Byte opcode_pattern[9][12] = { /* #0 inline delta function 1 */ @@ -3607,7 +3561,7 @@ FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 }; FT_UShort i; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* some font programs are broken enough to redefine functions! */ @@ -3652,7 +3606,7 @@ if ( n > exc->maxFunc ) exc->maxFunc = (FT_UInt16)n; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* We don't know for sure these are typeman functions, */ /* however they are only active when RS 22 is called */ if ( n >= 64 && n <= 66 ) @@ -3665,9 +3619,9 @@ while ( SkipCode( exc ) == SUCCESS ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING ) + if ( SUBPIXEL_HINTING_INFINALITY ) { for ( i = 0; i < opcode_patterns; i++ ) { @@ -3774,7 +3728,7 @@ ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ); } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ switch ( exc->opcode ) { @@ -3803,9 +3757,9 @@ TT_CallRec* pRec; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY exc->sph_in_func_flags = 0x0000; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ if ( exc->callTop <= 0 ) /* We encountered an ENDF without a call */ { @@ -3891,8 +3845,8 @@ if ( !def->active ) goto Fail; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && ( ( exc->iup_called && ( exc->sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) || @@ -3900,7 +3854,7 @@ goto Fail; else exc->sph_in_func_flags = def->sph_fdef_flags; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* check the call stack */ if ( exc->callTop >= exc->callSize ) @@ -3979,14 +3933,14 @@ if ( !def->active ) goto Fail; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) goto Fail; else exc->sph_in_func_flags = def->sph_fdef_flags; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* check stack */ if ( exc->callTop >= exc->callSize ) @@ -4009,6 +3963,10 @@ Ins_Goto_CodeRange( exc, def->range, def->start ); exc->step_ins = FALSE; + + exc->loopcall_counter += (FT_ULong)args[0]; + if ( exc->loopcall_counter > exc->loopcall_counter_max ) + exc->error = FT_THROW( Execution_Too_Long ); } return; @@ -4079,6 +4037,7 @@ exc->error = FT_THROW( Nested_DEFS ); return; case 0x2D: /* ENDF */ + def->end = exc->IP; return; } } @@ -4298,16 +4257,12 @@ exc->GS.dualVector.x = AA; exc->GS.dualVector.y = BB; } - else - GUESS_VECTOR( projVector ); if ( ( opcode & 2 ) == 0 ) { exc->GS.freeVector.x = AA; exc->GS.freeVector.y = BB; } - else - GUESS_VECTOR( freeVector ); Compute_Funcs( exc ); } @@ -4329,7 +4284,6 @@ &exc->GS.projVector ) == SUCCESS ) { exc->GS.dualVector = exc->GS.projVector; - GUESS_VECTOR( freeVector ); Compute_Funcs( exc ); } } @@ -4350,7 +4304,6 @@ (FT_UShort)args[0], &exc->GS.freeVector ) == SUCCESS ) { - GUESS_VECTOR( projVector ); Compute_Funcs( exc ); } } @@ -4365,7 +4318,6 @@ static void Ins_SFVTPV( TT_ExecContext exc ) { - GUESS_VECTOR( projVector ); exc->GS.freeVector = exc->GS.projVector; Compute_Funcs( exc ); } @@ -4394,7 +4346,6 @@ Normalize( X, Y, &exc->GS.projVector ); exc->GS.dualVector = exc->GS.projVector; - GUESS_VECTOR( freeVector ); Compute_Funcs( exc ); } @@ -4420,7 +4371,6 @@ X = S; Normalize( X, Y, &exc->GS.freeVector ); - GUESS_VECTOR( projVector ); Compute_Funcs( exc ); } @@ -4435,21 +4385,8 @@ Ins_GPV( TT_ExecContext exc, FT_Long* args ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( exc->face->unpatented_hinting ) - { - args[0] = exc->GS.both_x_axis ? 0x4000 : 0; - args[1] = exc->GS.both_x_axis ? 0 : 0x4000; - } - else - { - args[0] = exc->GS.projVector.x; - args[1] = exc->GS.projVector.y; - } -#else args[0] = exc->GS.projVector.x; args[1] = exc->GS.projVector.y; -#endif } @@ -4463,21 +4400,8 @@ Ins_GFV( TT_ExecContext exc, FT_Long* args ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( exc->face->unpatented_hinting ) - { - args[0] = exc->GS.both_x_axis ? 0x4000 : 0; - args[1] = exc->GS.both_x_axis ? 0 : 0x4000; - } - else - { - args[0] = exc->GS.freeVector.x; - args[1] = exc->GS.freeVector.y; - } -#else args[0] = exc->GS.freeVector.x; args[1] = exc->GS.freeVector.y; -#endif } @@ -4597,7 +4521,7 @@ /* */ /* FLIPOFF[]: Set auto-FLIP to OFF */ /* Opcode range: 0x4E */ - /* Stack: --> */ + /* Stack: --> */ /* */ static void Ins_FLIPOFF( TT_ExecContext exc ) @@ -4916,13 +4840,13 @@ } } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */ - if ( SUBPIXEL_HINTING && - exc->ignore_x_mode && - FT_ABS( D ) == 64 ) + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + FT_ABS( D ) == 64 ) D += 1; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ args[0] = D; } @@ -5007,7 +4931,6 @@ } Normalize( A, B, &exc->GS.projVector ); - GUESS_VECTOR( freeVector ); Compute_Funcs( exc ); } @@ -5179,12 +5102,23 @@ exc->GS.instruct_control &= ~(FT_Byte)Kf; exc->GS.instruct_control |= (FT_Byte)L; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* INSTCTRL modifying flag 3 also has an effect */ - /* outside of the CVT program */ if ( K == 3 ) - exc->ignore_x_mode = FT_BOOL( L == 4 ); + { +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + /* INSTCTRL modifying flag 3 also has an effect */ + /* outside of the CVT program */ + if ( SUBPIXEL_HINTING_INFINALITY ) + exc->ignore_x_mode = FT_BOOL( L == 4 ); #endif + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* Native ClearType fonts sign a waiver that turns off all backwards */ + /* compatibility hacks and lets them program points to the grid like */ + /* it's 1996. They might sign a waiver for just one glyph, though. */ + if ( SUBPIXEL_HINTING_MINIMAL ) + exc->backwards_compatibility = !FT_BOOL( L == 4 ); +#endif + } } @@ -5239,14 +5173,14 @@ /* */ /* SCANTYPE[]: SCAN TYPE */ /* Opcode range: 0x8D */ - /* Stack: uint32? --> */ + /* Stack: uint16 --> */ /* */ static void Ins_SCANTYPE( TT_ExecContext exc, FT_Long* args ) { if ( args[0] >= 0 ) - exc->GS.scan_type = (FT_Int)args[0]; + exc->GS.scan_type = (FT_Int)args[0] & 0xFFFF; } @@ -5269,6 +5203,15 @@ FT_UShort point; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backwards compatibility mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && + exc->iupy_called ) + goto Fail; +#endif + if ( exc->top < exc->GS.loop ) { if ( exc->pedantic_hinting ) @@ -5315,6 +5258,15 @@ FT_UShort I, K, L; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backwards compatibility mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && + exc->iupy_called ) + return; +#endif + K = (FT_UShort)args[1]; L = (FT_UShort)args[0]; @@ -5344,6 +5296,15 @@ FT_UShort I, K, L; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backwards compatibility mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && + exc->iupy_called ) + return; +#endif + K = (FT_UShort)args[1]; L = (FT_UShort)args[0]; @@ -5396,31 +5357,14 @@ d = PROJECT( zp.cur + p, zp.org + p ); -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( exc->face->unpatented_hinting ) - { - if ( exc->GS.both_x_axis ) - { - *x = d; - *y = 0; - } - else - { - *x = 0; - *y = d; - } - } - else -#endif - { - *x = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.x, exc->F_dot_P ); - *y = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.y, exc->F_dot_P ); - } + *x = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.x, exc->F_dot_P ); + *y = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.y, exc->F_dot_P ); return SUCCESS; } + /* See `ttinterp.h' for details on backwards compatibility mode. */ static void Move_Zp2_Point( TT_ExecContext exc, FT_UShort point, @@ -5428,35 +5372,28 @@ FT_F26Dot6 dy, FT_Bool touch ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( exc->face->unpatented_hinting ) + if ( exc->GS.freeVector.x != 0 ) { - if ( exc->GS.both_x_axis ) - { - exc->zp2.cur[point].x += dx; - if ( touch ) - exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; - } - else - { - exc->zp2.cur[point].y += dy; - if ( touch ) - exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; - } - return; - } +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( !( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility ) ) #endif + exc->zp2.cur[point].x += dx; - if ( exc->GS.freeVector.x != 0 ) - { - exc->zp2.cur[point].x += dx; if ( touch ) exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; } if ( exc->GS.freeVector.y != 0 ) { - exc->zp2.cur[point].y += dy; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( !( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && + exc->iupy_called ) ) +#endif + exc->zp2.cur[point].y += dy; + if ( touch ) exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; } @@ -5503,13 +5440,12 @@ } } else -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* doesn't follow Cleartype spec but produces better result */ - if ( SUBPIXEL_HINTING && - exc->ignore_x_mode ) + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode ) Move_Zp2_Point( exc, point, 0, dy, TRUE ); else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ Move_Zp2_Point( exc, point, dx, dy, TRUE ); exc->GS.loop--; @@ -5637,9 +5573,15 @@ { FT_F26Dot6 dx, dy; FT_UShort point; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_Int B1, B2; #endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + FT_Bool in_twilight = FT_BOOL( exc->GS.gep0 == 0 || + exc->GS.gep1 == 0 || + exc->GS.gep2 == 0 ); +#endif + if ( exc->top < exc->GS.loop + 1 ) @@ -5649,26 +5591,8 @@ goto Fail; } -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( exc->face->unpatented_hinting ) - { - if ( exc->GS.both_x_axis ) - { - dx = (FT_UInt32)args[0]; - dy = 0; - } - else - { - dx = 0; - dy = (FT_UInt32)args[0]; - } - } - else -#endif - { - dx = TT_MulFix14( args[0], exc->GS.freeVector.x ); - dy = TT_MulFix14( args[0], exc->GS.freeVector.y ); - } + dx = TT_MulFix14( args[0], exc->GS.freeVector.x ); + dy = TT_MulFix14( args[0], exc->GS.freeVector.y ); while ( exc->GS.loop > 0 ) { @@ -5685,7 +5609,8 @@ } } else -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY ) { /* If not using ignore_x_mode rendering, allow ZP2 move. */ /* If inline deltas aren't allowed, skip ZP2 move. */ @@ -5695,8 +5620,7 @@ /* - the glyph is specifically set to allow SHPIX moves */ /* - the move is on a previously Y-touched point */ - if ( SUBPIXEL_HINTING && - exc->ignore_x_mode ) + if ( exc->ignore_x_mode ) { /* save point for later comparison */ if ( exc->GS.freeVector.y != 0 ) @@ -5760,15 +5684,30 @@ else Move_Zp2_Point( exc, point, dx, dy, TRUE ); } + else +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility ) + { + /* Special case: allow SHPIX to move points in the twilight zone. */ + /* Otherwise, treat SHPIX the same as DELTAP. Unbreaks various */ + /* fonts such as older versions of Rokkitt and DTL Argo T Light */ + /* that would glitch severly after calling ALIGNRP after a blocked */ + /* SHPIX. */ + if ( in_twilight || + ( !( exc->iupx_called && exc->iupy_called ) && + ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) || + ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) ) ) ) + Move_Zp2_Point( exc, point, 0, dy, TRUE ); + } + else +#endif + Move_Zp2_Point( exc, point, dx, dy, TRUE ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY Skip: - -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - Move_Zp2_Point( exc, point, dx, dy, TRUE ); - -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - +#endif exc->GS.loop--; } @@ -5788,14 +5727,13 @@ Ins_MSIRP( TT_ExecContext exc, FT_Long* args ) { - FT_UShort point; + FT_UShort point = 0; FT_F26Dot6 distance; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_F26Dot6 control_value_cutin = 0; /* pacify compiler */ +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + FT_F26Dot6 control_value_cutin = 0; - if ( SUBPIXEL_HINTING ) + if ( SUBPIXEL_HINTING_INFINALITY ) { control_value_cutin = exc->GS.control_value_cutin; @@ -5804,8 +5742,7 @@ !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) control_value_cutin = 0; } - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ point = (FT_UShort)args[0]; @@ -5828,14 +5765,14 @@ distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* subpixel hinting - make MSIRP respect CVT cut-in; */ - if ( SUBPIXEL_HINTING && + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->GS.freeVector.x != 0 && FT_ABS( distance - args[1] ) >= control_value_cutin ) distance = args[1]; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ exc->func_move( exc, &exc->zp1, point, args[1] - distance ); @@ -5874,10 +5811,10 @@ if ( ( exc->opcode & 1 ) != 0 ) { cur_dist = FAST_PROJECT( &exc->zp0.cur[point] ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 ) distance = Round_None( exc, cur_dist, @@ -5920,14 +5857,14 @@ cvtEntry = (FT_ULong)args[1]; point = (FT_UShort)args[0]; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->GS.freeVector.x != 0 && exc->GS.freeVector.y == 0 && !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) control_value_cutin = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ if ( BOUNDS( point, exc->zp0.n_points ) || BOUNDSL( cvtEntry, exc->cvtSize ) ) @@ -5961,27 +5898,27 @@ if ( exc->GS.gep0 == 0 ) /* If in twilight zone */ { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */ /* Determined via experimentation and may be incorrect... */ - if ( !SUBPIXEL_HINTING || - ( !exc->ignore_x_mode || - !exc->face->sph_compatibility_mode ) ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + if ( !( SUBPIXEL_HINTING_INFINALITY && + ( exc->ignore_x_mode && + exc->face->sph_compatibility_mode ) ) ) +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ exc->zp0.org[point].x = TT_MulFix14( distance, exc->GS.freeVector.x ); exc->zp0.org[point].y = TT_MulFix14( distance, exc->GS.freeVector.y ), exc->zp0.cur[point] = exc->zp0.org[point]; } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && ( exc->sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) && distance > 0 && exc->GS.freeVector.y != 0 ) distance = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ org_dist = FAST_PROJECT( &exc->zp0.cur[point] ); @@ -5990,10 +5927,10 @@ if ( FT_ABS( distance - org_dist ) > control_value_cutin ) distance = org_dist; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 ) distance = Round_None( exc, distance, exc->tt_metrics.compensations[0] ); @@ -6022,19 +5959,19 @@ Ins_MDRP( TT_ExecContext exc, FT_Long* args ) { - FT_UShort point; + FT_UShort point = 0; FT_F26Dot6 org_dist, distance, minimum_distance; minimum_distance = exc->GS.minimum_distance; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->GS.freeVector.x != 0 && !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) minimum_distance = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ point = (FT_UShort)args[0]; @@ -6098,10 +6035,10 @@ if ( ( exc->opcode & 4 ) != 0 ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 ) distance = Round_None( exc, org_dist, @@ -6169,11 +6106,11 @@ org_dist, control_value_cutin, minimum_distance; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_Int B1 = 0; /* pacify compiler */ FT_Int B2 = 0; FT_Bool reverse_move = FALSE; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ minimum_distance = exc->GS.minimum_distance; @@ -6181,13 +6118,13 @@ point = (FT_UShort)args[0]; cvtEntry = (FT_ULong)( args[1] + 1 ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->GS.freeVector.x != 0 && !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) control_value_cutin = minimum_distance = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ @@ -6240,8 +6177,8 @@ cvt_dist = -cvt_dist; } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->GS.freeVector.y != 0 && ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) ) @@ -6251,7 +6188,7 @@ else if ( cur_dist > 64 && cur_dist < 84 ) cvt_dist += 32; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* control value cut-in and round */ @@ -6286,16 +6223,16 @@ else { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* do cvt cut-in always in MIRP for sph */ - if ( SUBPIXEL_HINTING && + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->GS.gep0 == exc->GS.gep1 ) { if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin ) cvt_dist = org_dist; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ distance = Round_None( exc, @@ -6319,8 +6256,8 @@ } } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY ) { B1 = exc->zp1.cur[point].y; @@ -6337,12 +6274,12 @@ ( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) ) distance += 64; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ exc->func_move( exc, &exc->zp1, point, distance - cur_dist ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY ) { B2 = exc->zp1.cur[point].y; @@ -6366,7 +6303,7 @@ exc->func_move( exc, &exc->zp1, point, -( distance - cur_dist ) ); } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ Fail: exc->GS.rp1 = exc->GS.rp0; @@ -6391,8 +6328,8 @@ FT_F26Dot6 distance; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->iup_called && ( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) ) @@ -6400,7 +6337,7 @@ exc->error = FT_THROW( Invalid_Reference ); goto Fail; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ if ( exc->top < exc->GS.loop || BOUNDS( exc->GS.rp0, exc->zp0.n_points ) ) @@ -6515,6 +6452,7 @@ R.x = FT_MulDiv( val, dax, discriminant ); R.y = FT_MulDiv( val, day, discriminant ); + /* XXX: Block in backwards_compatibility and/or post-IUP? */ exc->zp2.cur[point].x = exc->zp1.cur[a0].x + R.x; exc->zp2.cur[point].y = exc->zp1.cur[a0].y + R.y; } @@ -6522,6 +6460,7 @@ { /* else, take the middle of the middles of A and B */ + /* XXX: Block in backwards_compatibility and/or post-IUP? */ exc->zp2.cur[point].x = ( exc->zp1.cur[a0].x + exc->zp1.cur[a1].x + exc->zp0.cur[b0].x + @@ -6598,7 +6537,9 @@ * Otherwise, by definition, the value of exc->twilight.orus[n] is (0,0), * for every n. */ - twilight = exc->GS.gep0 == 0 || exc->GS.gep1 == 0 || exc->GS.gep2 == 0; + twilight = ( exc->GS.gep0 == 0 || + exc->GS.gep1 == 0 || + exc->GS.gep2 == 0 ); if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) ) { @@ -6646,7 +6587,7 @@ cur_range = PROJECT( &exc->zp1.cur[exc->GS.rp2], cur_base ); } - for ( ; exc->GS.loop > 0; --exc->GS.loop ) + for ( ; exc->GS.loop > 0; exc->GS.loop-- ) { FT_UInt point = (FT_UInt)exc->stack[--exc->args]; FT_F26Dot6 org_dist, cur_dist, new_dist; @@ -6910,6 +6851,23 @@ FT_Short contour; /* current contour */ +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backwards compatibility mode. */ + /* Allow IUP until it has been called on both axes. Immediately */ + /* return on subsequent ones. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility ) + { + if ( exc->iupx_called && exc->iupy_called ) + return; + + if ( exc->opcode & 1 ) + exc->iupx_called = TRUE; + else + exc->iupy_called = TRUE; + } +#endif + /* ignore empty outlines */ if ( exc->pts.n_contours == 0 ) return; @@ -6933,15 +6891,15 @@ contour = 0; point = 0; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - exc->ignore_x_mode ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode ) { exc->iup_called = TRUE; if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP ) return; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ do { @@ -7013,37 +6971,16 @@ FT_UShort A; FT_ULong C, P; FT_Long B; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_UShort B1, B2; - if ( SUBPIXEL_HINTING && + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->iup_called && ( exc->sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) ) goto Fail; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - /* Delta hinting is covered by US Patent 5159668. */ - if ( exc->face->unpatented_hinting ) - { - FT_Long n = args[0] * 2; - - - if ( exc->args < n ) - { - if ( exc->pedantic_hinting ) - exc->error = FT_THROW( Too_Few_Arguments ); - n = exc->args; - } - - exc->args -= n; - exc->new_top = exc->args; - return; - } -#endif +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ P = (FT_ULong)exc->func_cur_ppem( exc ); nump = (FT_ULong)args[0]; /* some points theoretically may occur more @@ -7097,9 +7034,9 @@ B++; B *= 1L << ( 6 - exc->GS.delta_shift ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING ) + if ( SUBPIXEL_HINTING_INFINALITY ) { /* * Allow delta move if @@ -7156,9 +7093,25 @@ } } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + + { - exc->func_move( exc, &exc->zp0, A, B ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backwards compatibility */ + /* mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility ) + { + if ( !( exc->iupx_called && exc->iupy_called ) && + ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) || + ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) ) + exc->func_move( exc, &exc->zp0, A, B ); + } + else +#endif + exc->func_move( exc, &exc->zp0, A, B ); + } } } else @@ -7186,26 +7139,6 @@ FT_Long B; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - /* Delta hinting is covered by US Patent 5159668. */ - if ( exc->face->unpatented_hinting ) - { - FT_Long n = args[0] * 2; - - - if ( exc->args < n ) - { - if ( exc->pedantic_hinting ) - exc->error = FT_THROW( Too_Few_Arguments ); - n = exc->args; - } - - exc->args -= n; - exc->new_top = exc->args; - return; - } -#endif - P = (FT_ULong)exc->func_cur_ppem( exc ); nump = (FT_ULong)args[0]; @@ -7294,20 +7227,21 @@ Ins_GETINFO( TT_ExecContext exc, FT_Long* args ) { - FT_Long K; + FT_Long K; + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( exc->face ); K = 0; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /********************************/ /* RASTERIZER VERSION */ /* Selector Bit: 0 */ /* Return Bit(s): 0-7 */ /* */ - if ( SUBPIXEL_HINTING && - ( args[0] & 1 ) != 0 && - exc->subpixel_hinting ) + if ( SUBPIXEL_HINTING_INFINALITY && + ( args[0] & 1 ) != 0 && + exc->subpixel_hinting ) { if ( exc->ignore_x_mode ) { @@ -7321,9 +7255,9 @@ K = TT_INTERPRETER_VERSION_38; } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ if ( ( args[0] & 1 ) != 0 ) - K = TT_INTERPRETER_VERSION_35; + K = driver->interpreter_version; /********************************/ /* GLYPH ROTATED */ @@ -7331,7 +7265,7 @@ /* Return Bit(s): 8 */ /* */ if ( ( args[0] & 2 ) != 0 && exc->tt_metrics.rotated ) - K |= 0x80; + K |= 1 << 8; /********************************/ /* GLYPH STRETCHED */ @@ -7339,19 +7273,83 @@ /* Return Bit(s): 9 */ /* */ if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched ) - K |= 1 << 8; + K |= 1 << 9; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT /********************************/ - /* HINTING FOR GRAYSCALE */ + /* VARIATION GLYPH */ + /* Selector Bit: 3 */ + /* Return Bit(s): 10 */ + /* */ + /* XXX: UNDOCUMENTED! */ + if ( (args[0] & 8 ) != 0 && exc->face->blend ) + K |= 1 << 10; +#endif + + /********************************/ + /* BI-LEVEL HINTING AND */ + /* GRAYSCALE RENDERING */ /* Selector Bit: 5 */ /* Return Bit(s): 12 */ /* */ if ( ( args[0] & 32 ) != 0 && exc->grayscale ) K |= 1 << 12; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( SUBPIXEL_HINTING_MINIMAL ) + { + /********************************/ + /* HINTING FOR SUBPIXEL */ + /* Selector Bit: 6 */ + /* Return Bit(s): 13 */ + /* */ + /* v40 does subpixel hinting by default. */ + if ( ( args[0] & 64 ) != 0 ) + K |= 1 << 13; + + /********************************/ + /* VERTICAL LCD SUBPIXELS? */ + /* Selector Bit: 8 */ + /* Return Bit(s): 15 */ + /* */ + if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd_lean ) + K |= 1 << 15; + + /********************************/ + /* SUBPIXEL POSITIONED? */ + /* Selector Bit: 10 */ + /* Return Bit(s): 17 */ + /* */ + /* XXX: FreeType supports it, dependent on what client does? */ + if ( ( args[0] & 1024 ) != 0 ) + K |= 1 << 17; + + /********************************/ + /* SYMMETRICAL SMOOTHING */ + /* Selector Bit: 11 */ + /* Return Bit(s): 18 */ + /* */ + /* The only smoothing method FreeType supports unless someone sets */ + /* FT_LOAD_TARGET_MONO. */ + if ( ( args[0] & 2048 ) != 0 ) + K |= 1 << 18; + + /********************************/ + /* CLEARTYPE HINTING AND */ + /* GRAYSCALE RENDERING */ + /* Selector Bit: 12 */ + /* Return Bit(s): 19 */ + /* */ + /* Grayscale rendering is what FreeType does anyway unless someone */ + /* sets FT_LOAD_TARGET_MONO or FT_LOAD_TARGET_LCD(_V) */ + if ( ( args[0] & 4096 ) != 0 && exc->grayscale_cleartype ) + K |= 1 << 19; + } +#endif + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING && + if ( SUBPIXEL_HINTING_INFINALITY && exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 ) { @@ -7424,12 +7422,63 @@ } } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ args[0] = K; } +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + /*************************************************************************/ + /* */ + /* GETVARIATION[]: get normalized variation (blend) coordinates */ + /* Opcode range: 0x91 */ + /* Stack: --> f2.14... */ + /* */ + /* XXX: UNDOCUMENTED! There is no official documentation from Apple for */ + /* this bytecode instruction. Active only if a font has GX */ + /* variation axes. */ + /* */ + static void + Ins_GETVARIATION( TT_ExecContext exc, + FT_Long* args ) + { + FT_UInt num_axes = exc->face->blend->num_axis; + FT_Fixed* coords = exc->face->blend->normalizedcoords; + + FT_UInt i; + + + if ( BOUNDS( num_axes, exc->stackSize + 1 - exc->top ) ) + { + exc->error = FT_THROW( Stack_Overflow ); + return; + } + + for ( i = 0; i < num_axes; i++ ) + args[i] = coords[i] >> 2; /* convert 16.16 to 2.14 format */ + } + + + /*************************************************************************/ + /* */ + /* GETDATA[]: no idea what this is good for */ + /* Opcode range: 0x92 */ + /* Stack: --> 17 */ + /* */ + /* XXX: UNDOCUMENTED! There is no documentation from Apple for this */ + /* very weird bytecode instruction. */ + /* */ + static void + Ins_GETDATA( FT_Long* args ) + { + args[0] = 17; + } + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + static void Ins_UNKNOWN( TT_ExecContext exc ) { @@ -7503,10 +7552,11 @@ FT_EXPORT_DEF( FT_Error ) TT_RunIns( TT_ExecContext exc ) { - FT_Long ins_counter = 0; /* executed instructions counter */ + FT_ULong ins_counter = 0; /* executed instructions counter */ + FT_ULong num_twilight_points; FT_UShort i; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_Byte opcode_pattern[1][2] = { /* #8 TypeMan Talk Align */ { @@ -7517,12 +7567,65 @@ FT_UShort opcode_patterns = 1; FT_UShort opcode_pointer[1] = { 0 }; FT_UShort opcode_size[1] = { 1 }; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY exc->iup_called = FALSE; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* Toggle backwards compatibility according to what font says, except */ + /* when it's a `tricky' font that heavily relies on the interpreter to */ + /* render glyphs correctly, e.g. DFKai-SB. Backwards compatibility */ + /* hacks may break it. */ + if ( SUBPIXEL_HINTING_MINIMAL && + !FT_IS_TRICKY( &exc->face->root ) ) + exc->backwards_compatibility = !( exc->GS.instruct_control & 4 ); + else + exc->backwards_compatibility = FALSE; + + exc->iupx_called = FALSE; + exc->iupy_called = FALSE; +#endif + + /* We restrict the number of twilight points to a reasonable, */ + /* heuristic value to avoid slow execution of malformed bytecode. */ + num_twilight_points = FT_MAX( 30, + 2 * ( exc->pts.n_points + exc->cvtSize ) ); + if ( exc->twilight.n_points > num_twilight_points ) + { + if ( num_twilight_points > 0xFFFFU ) + num_twilight_points = 0xFFFFU; + + FT_TRACE5(( "TT_RunIns: Resetting number of twilight points\n" + " from %d to the more reasonable value %d\n", + exc->twilight.n_points, + num_twilight_points )); + exc->twilight.n_points = (FT_UShort)num_twilight_points; + } + + /* Set up loop detectors. We restrict the number of LOOPCALL loops */ + /* and the number of JMPR, JROT, and JROF calls with a negative */ + /* argument to values that depend on the size of the CVT table and */ + /* the number of points in the current glyph (if applicable). */ + /* */ + /* The idea is that in real-world bytecode you either iterate over */ + /* all CVT entries, or over all points (or contours) of a glyph, and */ + /* such iterations don't happen very often. */ + exc->loopcall_counter = 0; + exc->neg_jump_counter = 0; + + /* The maximum values are heuristic. */ + exc->loopcall_counter_max = FT_MAX( 100, + 10 * ( exc->pts.n_points + + exc->cvtSize ) ); + FT_TRACE5(( "TT_RunIns: Limiting total number of loops in LOOPCALL" + " to %d\n", exc->loopcall_counter_max )); + + exc->neg_jump_counter_max = exc->loopcall_counter_max; + FT_TRACE5(( "TT_RunIns: Limiting total number of backward jumps" + " to %d\n", exc->neg_jump_counter_max )); /* set PPEM and CVT functions */ exc->tt_metrics.ratio = 0; @@ -7565,7 +7668,7 @@ ? 2 : 12 - ( *opcode_name[exc->opcode] - '0' ), "#" )); - for ( n = 0; n < cnt; n++ ) + for ( n = 1; n <= cnt; n++ ) FT_TRACE7(( " %d", exc->stack[exc->top - n] )); FT_TRACE6(( "\n" )); } @@ -7601,7 +7704,21 @@ exc->args = 0; } - exc->new_top = exc->args + ( Pop_Push_Count[exc->opcode] & 15 ); +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + if ( exc->opcode == 0x91 ) + { + /* this is very special: GETVARIATION returns */ + /* a variable number of arguments */ + + /* it is the job of the application to `activate' GX handling, */ + /* this is, calling any of the GX API functions on the current */ + /* font to select a variation instance */ + if ( exc->face->blend ) + exc->new_top = exc->args + exc->face->blend->num_axis; + } + else +#endif + exc->new_top = exc->args + ( Pop_Push_Count[exc->opcode] & 15 ); /* `new_top' is the new top of the stack, after the instruction's */ /* execution. `top' will be set to `new_top' after the `switch' */ @@ -7615,9 +7732,9 @@ exc->step_ins = TRUE; exc->error = FT_Err_Ok; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING ) + if ( SUBPIXEL_HINTING_INFINALITY ) { for ( i = 0; i < opcode_patterns; i++ ) { @@ -7646,7 +7763,7 @@ } } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ { FT_Long* args = exc->stack + exc->args; @@ -7794,7 +7911,7 @@ Ins_ALIGNPTS( exc, args ); break; - case 0x28: /* ???? */ + case 0x28: /* RAW */ Ins_UNKNOWN( exc ); break; @@ -8146,10 +8263,33 @@ Ins_INSTCTRL( exc, args ); break; - case 0x8F: + case 0x8F: /* ADJUST */ + case 0x90: /* ADJUST */ Ins_UNKNOWN( exc ); break; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + case 0x91: + /* it is the job of the application to `activate' GX handling, */ + /* this is, calling any of the GX API functions on the current */ + /* font to select a variation instance */ + if ( exc->face->blend ) + Ins_GETVARIATION( exc, args ); + else + Ins_UNKNOWN( exc ); + break; + + case 0x92: + /* there is at least one MS font (LaoUI.ttf version 5.01) that */ + /* uses IDEFs for 0x91 and 0x92; for this reason we activate */ + /* GETDATA for GX fonts only, similar to GETVARIATION */ + if ( exc->face->blend ) + Ins_GETDATA( args ); + else + Ins_UNKNOWN( exc ); + break; +#endif + default: if ( opcode >= 0xE0 ) Ins_MIRP( exc, args ); @@ -8230,7 +8370,7 @@ /* increment instruction counter and check if we didn't */ /* run this program for too long (e.g. infinite loops). */ - if ( ++ins_counter > MAX_RUNNABLE_OPCODES ) + if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES ) return FT_THROW( Execution_Too_Long ); LSuiteLabel_: @@ -8247,6 +8387,7 @@ } while ( !exc->instruction_trap ); LNo_Error_: + FT_TRACE4(( " %d instructions executed\n", ins_counter )); return FT_Err_Ok; LErrorCodeOverflow_: diff --git a/third_party/freetype/src/truetype/ttinterp.h b/third_party/freetype/src/truetype/ttinterp.h index 32706d0760..6625e16c76 100644 --- a/third_party/freetype/src/truetype/ttinterp.h +++ b/third_party/freetype/src/truetype/ttinterp.h @@ -4,7 +4,7 @@ /* */ /* TrueType bytecode interpreter (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTINTERP_H__ -#define __TTINTERP_H__ +#ifndef TTINTERP_H_ +#define TTINTERP_H_ #include <ft2build.h> #include "ttobjs.h" @@ -99,7 +99,7 @@ FT_BEGIN_HEADER } TT_CallRec, *TT_CallStack; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /*************************************************************************/ /* */ @@ -138,7 +138,7 @@ FT_BEGIN_HEADER } SPH_Font_Class; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /*************************************************************************/ @@ -170,6 +170,7 @@ FT_BEGIN_HEADER pts, twilight; + FT_Long pointSize; /* in 26.6 format */ FT_Size_Metrics metrics; TT_Size_Metrics tt_metrics; /* size metrics */ @@ -247,9 +248,135 @@ FT_BEGIN_HEADER TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */ TT_Set_CVT_Func func_move_cvt; /* incr a cvt entry (in pixels) */ - FT_Bool grayscale; /* are we hinting for grayscale? */ - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + FT_Bool grayscale; /* bi-level hinting and */ + /* grayscale rendering */ + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* + * Modern TrueType fonts are usually rendered through Microsoft's + * collection of rendering techniques called ClearType (e.g., subpixel + * rendering and subpixel hinting). When ClearType was introduced, most + * fonts were not ready. Microsoft decided to implement a backwards + * compatibility mode that employed several simple to complicated + * assumptions and tricks that modified the interpretation of the + * bytecode contained in these fonts to make them look ClearType-y + * somehow. Most (web)fonts that were released since then have come to + * rely on these hacks to render correctly, even some of Microsoft's + * flagship ClearType fonts (Calibri, Cambria, Segoe UI). + * + * The minimal subpixel hinting code (interpreter version 40) employs a + * small list of font-agnostic hacks to bludgeon non-native-ClearType + * fonts (except tricky ones[1]) into submission. It will not try to + * toggle hacks for specific fonts for performance and complexity + * reasons. The focus is on modern (web)fonts rather than legacy fonts + * that were made for black-and-white rendering. + * + * Major hacks + * + * - Any point movement on the x axis is ignored (cf. `Direct_Move' and + * `Direct_Move_X'). This has the smallest code footprint and single + * biggest effect. The ClearType way to increase resolution is + * supersampling the x axis, the FreeType way is ignoring instructions + * on the x axis, which gives the same result in the majority of + * cases. + * + * - Points are not moved post-IUP (neither on the x nor on the y axis), + * except the x component of diagonal moves post-IUP (cf. + * `Direct_Move', `Direct_Move_Y', `Move_Zp2_Point'). Post-IUP + * changes are commonly used to `fix' pixel patterns which has little + * use outside monochrome rendering. + * + * - SHPIX and DELTAP don't execute unless moving a composite on the + * y axis or moving a previously y touched point. SHPIX additionally + * denies movement on the x axis (cf. `Ins_SHPIX' and `Ins_DELTAP'). + * Both instructions are commonly used to `fix' pixel patterns for + * monochrome or Windows's GDI rendering but make little sense for + * FreeType rendering. Both can distort the outline. See [2] for + * details. + * + * - The hdmx table and modifications to phantom points are ignored. + * Bearings and advance widths remain unchanged (except rounding them + * outside the interpreter!), cf. `compute_glyph_metrics' and + * `TT_Hint_Glyph'. Letting non-native-ClearType fonts modify spacing + * might mess up spacing. + * + * Minor hacks + * + * - FLIPRGON, FLIPRGOFF, and FLIPPT don't execute post-IUP. This + * prevents dents in e.g. Arial-Regular's `D' and `G' glyphs at + * various sizes. + * + * (Post-IUP is the state after both IUP[x] and IUP[y] have been + * executed.) + * + * The best results are achieved for fonts that were from the outset + * designed with ClearType in mind, meaning they leave the x axis mostly + * alone and don't mess with the `final' outline to produce more + * pleasing pixel patterns. The harder the designer tried to produce + * very specific patterns (`superhinting') for pre-ClearType-displays, + * the worse the results. + * + * Microsoft defines a way to turn off backwards compatibility and + * interpret instructions as before (called `native ClearType')[2][3]. + * The font designer then regains full control and is responsible for + * making the font work correctly with ClearType without any + * hand-holding by the interpreter or rasterizer[4]. The v40 + * interpreter assumes backwards compatibility by default, which can be + * turned off the same way by executing the following in the control + * program (cf. `Ins_INSTCTRL'). + * + * #PUSH 4,3 + * INSTCTRL[] + * + * [1] Tricky fonts as FreeType defines them rely on the bytecode + * interpreter to display correctly. Hacks can interfere with them, + * so they get treated like native ClearType fonts (v40 with + * backwards compatibility turned off). Cf. `TT_RunIns'. + * + * [2] Proposed by Microsoft's Greg Hitchcock in + * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx + * + * [3] Beat Stamm describes it in more detail: + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec12 + * + * [4] The list of `native ClearType' fonts is small at the time of this + * writing; I found the following on a Windows 10 Update 1511 + * installation: Constantia, Corbel, Sitka, Malgun Gothic, Microsoft + * JhengHei (Bold and UI Bold), Microsoft YaHei (Bold and UI Bold), + * SimSun, NSimSun, and Yu Gothic. + * + */ + + /* Using v40 implies subpixel hinting. Used to detect interpreter */ + /* version switches. `_lean' to differentiate from the Infinality */ + /* `subpixel_hinting', which is managed differently. */ + FT_Bool subpixel_hinting_lean; + + /* Long side of a LCD subpixel is vertical (e.g., screen is rotated). */ + /* `_lean' to differentiate from the Infinality `vertical_lcd', which */ + /* is managed differently. */ + FT_Bool vertical_lcd_lean; + + /* Default to backwards compatibility mode in v40 interpreter. If */ + /* this is false, it implies the interpreter is in v35 or in native */ + /* ClearType mode. */ + FT_Bool backwards_compatibility; + + /* Useful for detecting and denying post-IUP trickery that is usually */ + /* used to fix pixel patterns (`superhinting'). */ + FT_Bool iupx_called; + FT_Bool iupy_called; + + /* ClearType hinting and grayscale rendering, as used by Universal */ + /* Windows Platform apps (Windows 8 and above). Like the standard */ + /* colorful ClearType mode, it utilizes a vastly increased virtual */ + /* resolution on the x axis. Different from bi-level hinting and */ + /* grayscale rendering, the old mode from Win9x days that roughly */ + /* adheres to the physical pixel grid on both axes. */ + FT_Bool grayscale_cleartype; +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL */ + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY TT_Round_Func func_round_sphn; /* subpixel rounding function */ FT_Bool subpixel_hinting; /* Using subpixel hinting? */ @@ -279,7 +406,15 @@ FT_BEGIN_HEADER FT_ULong sph_in_func_flags; /* flags to indicate if in */ /* special functions */ -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + + /* We maintain two counters (in addition to the instruction counter) */ + /* that act as loop detectors for LOOPCALL and jump opcodes with */ + /* negative arguments. */ + FT_ULong loopcall_counter; + FT_ULong loopcall_counter_max; + FT_ULong neg_jump_counter; + FT_ULong neg_jump_counter_max; } TT_ExecContextRec; @@ -382,7 +517,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTINTERP_H__ */ +#endif /* TTINTERP_H_ */ /* END */ diff --git a/third_party/freetype/src/truetype/ttobjs.c b/third_party/freetype/src/truetype/ttobjs.c index 6060d6f5d1..18aa48a93f 100644 --- a/third_party/freetype/src/truetype/ttobjs.c +++ b/third_party/freetype/src/truetype/ttobjs.c @@ -4,7 +4,7 @@ /* */ /* Objects manager (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,10 +32,6 @@ #include "ttinterp.h" #endif -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING -#include FT_TRUETYPE_UNPATENTED_H -#endif - #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include "ttgxvar.h" #endif @@ -121,7 +117,7 @@ FT_Error error; - FT_MEM_ZERO( zone, sizeof ( *zone ) ); + FT_ZERO( zone ); zone->memory = memory; if ( FT_NEW_ARRAY( zone->org, maxPoints ) || @@ -246,7 +242,7 @@ tt_check_trickyness_sfnt_ids( TT_Face face ) { #define TRICK_SFNT_IDS_PER_FACE 3 -#define TRICK_SFNT_IDS_NUM_FACES 17 +#define TRICK_SFNT_IDS_NUM_FACES 18 static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES] [TRICK_SFNT_IDS_PER_FACE] = { @@ -270,6 +266,11 @@ { 0x5A30CA3BUL, 0x00009063UL }, /* fpgm */ { 0x13A42602UL, 0x0000007EUL } /* prep */ }, + { /* DFKaiShu2 */ + { 0x11E5EAD4UL, 0x00000350UL }, /* cvt */ + { 0xA6E78C01UL, 0x00008998UL }, /* fpgm */ + { 0x13A42602UL, 0x0000007EUL } /* prep */ + }, { /* HuaTianKaiTi */ { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt */ { 0x9C9E48B8UL, 0x0000BEA2UL }, /* fpgm */ @@ -397,11 +398,11 @@ for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ ) { if ( !has_cvt && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length ) - num_matched_ids[j] ++; + num_matched_ids[j]++; if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length ) - num_matched_ids[j] ++; + num_matched_ids[j]++; if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length ) - num_matched_ids[j] ++; + num_matched_ids[j]++; if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE ) return TRUE; } @@ -535,6 +536,7 @@ goto Exit; /* check that we have a valid TrueType file */ + FT_TRACE2(( " " )); error = sfnt->init_face( stream, face, face_index, num_params, params ); /* Stream may have changed. */ @@ -576,58 +578,50 @@ if ( FT_IS_SCALABLE( ttface ) ) { - #ifdef FT_CONFIG_OPTION_INCREMENTAL - if ( !ttface->internal->incremental_interface ) - error = tt_face_load_loca( face, stream ); - if ( !error ) - error = tt_face_load_cvt( face, stream ); - if ( !error ) - error = tt_face_load_fpgm( face, stream ); - if ( !error ) - error = tt_face_load_prep( face, stream ); - - /* Check the scalable flag based on `loca'. */ - if ( !ttface->internal->incremental_interface && - ttface->num_fixed_sizes && - face->glyph_locations && - tt_check_single_notdef( ttface ) ) +#endif { - FT_TRACE5(( "tt_face_init:" - " Only the `.notdef' glyph has an outline.\n" - " " - " Resetting scalable flag to FALSE.\n" )); + error = tt_face_load_loca( face, stream ); - ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; + /* having a (non-zero) `glyf' table without */ + /* a `loca' table is not valid */ + if ( face->glyf_len && FT_ERR_EQ( error, Table_Missing ) ) + goto Exit; + if ( error ) + goto Exit; } -#else /* !FT_CONFIG_OPTION_INCREMENTAL */ + /* `fpgm', `cvt', and `prep' are optional */ + error = tt_face_load_cvt( face, stream ); + if ( error && FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; - if ( !error ) - error = tt_face_load_loca( face, stream ); - if ( !error ) - error = tt_face_load_cvt( face, stream ); - if ( !error ) - error = tt_face_load_fpgm( face, stream ); - if ( !error ) - error = tt_face_load_prep( face, stream ); + error = tt_face_load_fpgm( face, stream ); + if ( error && FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; + + error = tt_face_load_prep( face, stream ); + if ( error && FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; /* Check the scalable flag based on `loca'. */ - if ( ttface->num_fixed_sizes && - face->glyph_locations && - tt_check_single_notdef( ttface ) ) +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( !ttface->internal->incremental_interface ) +#endif { - FT_TRACE5(( "tt_face_init:" - " Only the `.notdef' glyph has an outline.\n" - " " - " Resetting scalable flag to FALSE.\n" )); + if ( ttface->num_fixed_sizes && + face->glyph_locations && + tt_check_single_notdef( ttface ) ) + { + FT_TRACE5(( "tt_face_init:" + " Only the `.notdef' glyph has an outline.\n" + " " + " Resetting scalable flag to FALSE.\n" )); - ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; + ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; + } } - -#endif /* !FT_CONFIG_OPTION_INCREMENTAL */ - } #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT @@ -670,35 +664,14 @@ named_style->coords ); if ( error ) goto Exit; + + tt_apply_mvar( face ); } } } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ -#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ - !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) - - { - 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 ) - unpatented_hinting = TRUE; - - if ( !unpatented_hinting ) - ttface->internal->ignore_unpatented_hinter = TRUE; - } - -#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING && - !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - /* initialize standard glyph loading routines */ TT_Init_Glyph_Loading( face ); @@ -761,7 +734,7 @@ face->cvt_program_size = 0; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - tt_done_blend( memory, face->blend ); + tt_done_blend( face ); face->blend = NULL; #endif } @@ -849,6 +822,11 @@ FT_TRACE4(( "Executing `fpgm' table.\n" )); error = face->interpreter( exec ); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( error ) + FT_TRACE4(( " interpretation failed with error code 0x%x\n", + error )); +#endif } else error = FT_Err_Ok; @@ -912,8 +890,12 @@ TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); FT_TRACE4(( "Executing `prep' table.\n" )); - error = face->interpreter( exec ); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( error ) + FT_TRACE4(( " interpretation failed with error code 0x%x\n", + error )); +#endif } else error = FT_Err_Ok; @@ -1078,7 +1060,15 @@ } /* Fine, now run the font program! */ + + /* In case of an error while executing `fpgm', we intentionally don't */ + /* clean up immediately – bugs in the `fpgm' are so fundamental that */ + /* all following hinting calls should fail. Additionally, `fpgm' is */ + /* to be executed just once; calling it again is completely useless */ + /* and might even lead to extremely slow behaviour if it is malformed */ + /* (containing an infinite loop, for example). */ error = tt_size_run_fpgm( size, pedantic ); + return error; Exit: if ( error ) @@ -1097,8 +1087,10 @@ if ( size->bytecode_ready < 0 ) error = tt_size_init_bytecode( (FT_Size)size, pedantic ); + else + error = size->bytecode_ready; - if ( error || size->bytecode_ready ) + if ( error ) goto Exit; /* rescale CVT when needed */ @@ -1130,6 +1122,8 @@ error = tt_size_run_prep( size, pedantic ); } + else + error = size->cvt_ready; Exit: return error; @@ -1206,13 +1200,15 @@ /* have been changed. */ /* */ /* <Input> */ - /* size :: A handle to the target size object. */ + /* size :: A handle to the target size object. */ + /* */ + /* only_height :: Only recompute ascender, descender, and height. */ /* */ FT_LOCAL_DEF( FT_Error ) - tt_size_reset( TT_Size size ) + tt_size_reset( TT_Size size, + FT_Bool only_height ) { TT_Face face; - FT_Error error = FT_Err_Ok; FT_Size_Metrics* metrics; @@ -1234,17 +1230,26 @@ /* */ if ( face->header.Flags & 8 ) { - metrics->x_scale = FT_DivFix( metrics->x_ppem << 6, - face->root.units_per_EM ); - metrics->y_scale = FT_DivFix( metrics->y_ppem << 6, - face->root.units_per_EM ); - metrics->ascender = FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) ); metrics->descender = FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) ); metrics->height = FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) ); + } + + size->ttmetrics.valid = TRUE; + + if ( only_height ) + return FT_Err_Ok; + + if ( face->header.Flags & 8 ) + { + metrics->x_scale = FT_DivFix( metrics->x_ppem << 6, + face->root.units_per_EM ); + metrics->y_scale = FT_DivFix( metrics->y_ppem << 6, + face->root.units_per_EM ); + metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width, metrics->x_scale ) ); @@ -1272,10 +1277,7 @@ size->cvt_ready = -1; #endif /* TT_USE_BYTECODE_INTERPRETER */ - if ( !error ) - size->ttmetrics.valid = TRUE; - - return error; + return FT_Err_Ok; } @@ -1301,10 +1303,12 @@ TT_Driver driver = (TT_Driver)ttdriver; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - driver->interpreter_version = TT_INTERPRETER_VERSION_38; -#else driver->interpreter_version = TT_INTERPRETER_VERSION_35; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + driver->interpreter_version = TT_INTERPRETER_VERSION_38; +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + driver->interpreter_version = TT_INTERPRETER_VERSION_40; #endif #else /* !TT_USE_BYTECODE_INTERPRETER */ diff --git a/third_party/freetype/src/truetype/ttobjs.h b/third_party/freetype/src/truetype/ttobjs.h index 9396089a99..65929e5928 100644 --- a/third_party/freetype/src/truetype/ttobjs.h +++ b/third_party/freetype/src/truetype/ttobjs.h @@ -4,7 +4,7 @@ /* */ /* Objects manager (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTOBJS_H__ -#define __TTOBJS_H__ +#ifndef TTOBJS_H_ +#define TTOBJS_H_ #include <ft2build.h> @@ -72,10 +72,6 @@ FT_BEGIN_HEADER FT_UnitVector projVector; FT_UnitVector freeVector; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_Bool both_x_axis; -#endif - FT_Long loop; FT_F26Dot6 minimum_distance; FT_Int round_state; @@ -290,6 +286,8 @@ FT_BEGIN_HEADER #ifdef TT_USE_BYTECODE_INTERPRETER + FT_Long point_size; /* for the `MPS' bytecode instruction */ + FT_UInt num_function_defs; /* number of function definitions */ FT_UInt max_function_defs; TT_DefArray function_defs; /* table of function definitions */ @@ -391,7 +389,8 @@ FT_BEGIN_HEADER #endif /* TT_USE_BYTECODE_INTERPRETER */ FT_LOCAL( FT_Error ) - tt_size_reset( TT_Size size ); + tt_size_reset( TT_Size size, + FT_Bool only_height ); /*************************************************************************/ @@ -419,7 +418,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTOBJS_H__ */ +#endif /* TTOBJS_H_ */ /* END */ diff --git a/third_party/freetype/src/truetype/ttpic.c b/third_party/freetype/src/truetype/ttpic.c index 242a6b76dd..66bd7e1934 100644 --- a/third_party/freetype/src/truetype/ttpic.c +++ b/third_party/freetype/src/truetype/ttpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for truetype module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/truetype/ttpic.h b/third_party/freetype/src/truetype/ttpic.h index 076ae56efa..1410cd73c3 100644 --- a/third_party/freetype/src/truetype/ttpic.h +++ b/third_party/freetype/src/truetype/ttpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for truetype module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTPIC_H__ -#define __TTPIC_H__ +#ifndef TTPIC_H_ +#define TTPIC_H_ #include FT_INTERNAL_PIC_H @@ -25,15 +25,17 @@ #ifndef FT_CONFIG_OPTION_PIC -#define TT_SERVICES_GET tt_services -#define TT_SERVICE_GX_MULTI_MASTERS_GET tt_service_gx_multi_masters -#define TT_SERVICE_TRUETYPE_GLYF_GET tt_service_truetype_glyf -#define TT_SERVICE_PROPERTIES_GET tt_service_properties +#define TT_SERVICES_GET tt_services +#define TT_SERVICE_GX_MULTI_MASTERS_GET tt_service_gx_multi_masters +#define TT_SERVICE_METRICS_VARIATIONS_GET tt_service_metrics_variations +#define TT_SERVICE_TRUETYPE_GLYF_GET tt_service_truetype_glyf +#define TT_SERVICE_PROPERTIES_GET tt_service_properties #else /* FT_CONFIG_OPTION_PIC */ #include FT_MULTIPLE_MASTERS_H #include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_METRICS_VARIATIONS_H #include FT_SERVICE_TRUETYPE_GLYF_H #include FT_SERVICE_PROPERTIES_H @@ -42,12 +44,13 @@ FT_BEGIN_HEADER typedef struct TTModulePIC_ { - FT_ServiceDescRec* tt_services; + FT_ServiceDescRec* tt_services; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_Service_MultiMastersRec tt_service_gx_multi_masters; + FT_Service_MultiMastersRec tt_service_gx_multi_masters; + FT_Service_MetricsVariationsRec tt_service_metrics_variations; #endif - FT_Service_TTGlyfRec tt_service_truetype_glyf; - FT_Service_PropertiesRec tt_service_properties; + FT_Service_TTGlyfRec tt_service_truetype_glyf; + FT_Service_PropertiesRec tt_service_properties; } TTModulePIC; @@ -56,6 +59,8 @@ FT_BEGIN_HEADER ( (TTModulePIC*)((lib)->pic_container.truetype) ) #define TT_SERVICES_GET \ ( GET_PIC( library )->tt_services ) +#define TT_SERVICE_METRICS_VARIATIONS_GET \ + ( GET_PIC( library )->tt_service_metrics_variations ) #define TT_SERVICE_GX_MULTI_MASTERS_GET \ ( GET_PIC( library )->tt_service_gx_multi_masters ) #define TT_SERVICE_TRUETYPE_GLYF_GET \ @@ -77,7 +82,7 @@ FT_END_HEADER /* */ -#endif /* __TTPIC_H__ */ +#endif /* TTPIC_H_ */ /* END */ diff --git a/third_party/freetype/src/truetype/ttpload.c b/third_party/freetype/src/truetype/ttpload.c index 4647c938ae..70ac15da4a 100644 --- a/third_party/freetype/src/truetype/ttpload.c +++ b/third_party/freetype/src/truetype/ttpload.c @@ -4,7 +4,7 @@ /* */ /* TrueType-specific tables loader (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -73,9 +73,21 @@ /* it is possible that a font doesn't have a glyf table at all */ /* or its size is zero */ if ( FT_ERR_EQ( error, Table_Missing ) ) - face->glyf_len = 0; + { + face->glyf_len = 0; + face->glyf_offset = 0; + } else if ( error ) goto Exit; + else + { +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( face->root.internal->incremental_interface ) + face->glyf_offset = 0; + else +#endif + face->glyf_offset = FT_STREAM_POS(); + } FT_TRACE2(( "Locations " )); error = face->goto_table( face, TTAG_loca, stream, &table_len ); @@ -92,8 +104,7 @@ if ( table_len >= 0x40000L ) { FT_TRACE2(( "table too large\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; + table_len = 0x3FFFFL; } face->num_locations = table_len >> shift; } @@ -104,8 +115,7 @@ if ( table_len >= 0x20000L ) { FT_TRACE2(( "table too large\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; + table_len = 0x1FFFFL; } face->num_locations = table_len >> shift; } @@ -124,8 +134,9 @@ TT_Table entry = face->dir_tables; TT_Table limit = entry + face->num_tables; - FT_Long pos = (FT_Long)FT_STREAM_POS(); - FT_Long dist = 0x7FFFFFFFL; + FT_Long pos = (FT_Long)FT_STREAM_POS(); + FT_Long dist = 0x7FFFFFFFL; + FT_Bool found = 0; /* compute the distance to next table in font file */ @@ -135,10 +146,13 @@ if ( diff > 0 && diff < dist ) - dist = diff; + { + dist = diff; + found = 1; + } } - if ( entry == limit ) + if ( !found ) { /* `loca' is the last table */ dist = (FT_Long)stream->size - pos; @@ -218,12 +232,13 @@ } } - /* Check broken location data */ + /* Check broken location data. */ if ( pos1 > face->glyf_len ) { FT_TRACE1(( "tt_face_get_location:" - " too large offset=0x%08lx found for gid=0x%04lx," - " exceeding the end of glyf table (0x%08lx)\n", + " too large offset (0x%08lx) found for glyph index %ld,\n" + " " + " exceeding the end of `glyf' table (0x%08lx)\n", pos1, gindex, face->glyf_len )); *asize = 0; return 0; @@ -231,11 +246,26 @@ if ( pos2 > face->glyf_len ) { - FT_TRACE1(( "tt_face_get_location:" - " too large offset=0x%08lx found for gid=0x%04lx," - " truncate at the end of glyf table (0x%08lx)\n", - pos2, gindex + 1, face->glyf_len )); - pos2 = face->glyf_len; + /* We try to sanitize the last `loca' entry. */ + if ( gindex == face->num_locations - 1 ) + { + FT_TRACE1(( "tt_face_get_location:" + " too large offset (0x%08lx) found for glyph index %ld,\n" + " " + " truncating at the end of `glyf' table (0x%08lx)\n", + pos2, gindex + 1, face->glyf_len )); + pos2 = face->glyf_len; + } + else + { + FT_TRACE1(( "tt_face_get_location:" + " too large offset (0x%08lx) found for glyph index %ld,\n" + " " + " exceeding the end of `glyf' table (0x%08lx)\n", + pos2, gindex + 1, face->glyf_len )); + *asize = 0; + return 0; + } } /* The `loca' table must be ordered; it refers to the length of */ @@ -494,7 +524,7 @@ { FT_Error error; FT_Memory memory = stream->memory; - FT_UInt version, nn, num_records; + FT_UInt nn, num_records; FT_ULong table_size, record_size; FT_Byte* p; FT_Byte* limit; @@ -511,7 +541,10 @@ p = face->hdmx_table; limit = p + table_size; - version = FT_NEXT_USHORT( p ); + /* Given that `hdmx' tables are losing its importance (for example, */ + /* variation fonts introduced in OpenType 1.8 must not have this */ + /* table) we no longer test for a correct `version' field. */ + p += 2; num_records = FT_NEXT_USHORT( p ); record_size = FT_NEXT_ULONG( p ); @@ -530,10 +563,10 @@ record_size &= 0xFFFFU; /* The limit for `num_records' is a heuristic value. */ - if ( version != 0 || - num_records > 255 || - record_size > 0x10001L || - record_size < 4 ) + if ( num_records > 255 || + ( num_records > 0 && + ( record_size > 0x10001L || + record_size < 4 ) ) ) { error = FT_THROW( Invalid_File_Format ); goto Fail; diff --git a/third_party/freetype/src/truetype/ttpload.h b/third_party/freetype/src/truetype/ttpload.h index bc92369827..79079f345a 100644 --- a/third_party/freetype/src/truetype/ttpload.h +++ b/third_party/freetype/src/truetype/ttpload.h @@ -4,7 +4,7 @@ /* */ /* TrueType-specific tables loader (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTPLOAD_H__ -#define __TTPLOAD_H__ +#ifndef TTPLOAD_H_ +#define TTPLOAD_H_ #include <ft2build.h> @@ -69,7 +69,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTPLOAD_H__ */ +#endif /* TTPLOAD_H_ */ /* END */ diff --git a/third_party/freetype/src/truetype/ttsubpix.c b/third_party/freetype/src/truetype/ttsubpix.c index 0d391e95a0..5d803cde14 100644 --- a/third_party/freetype/src/truetype/ttsubpix.c +++ b/third_party/freetype/src/truetype/ttsubpix.c @@ -4,7 +4,7 @@ /* */ /* TrueType Subpixel Hinting. */ /* */ -/* Copyright 2010-2015 by */ +/* Copyright 2010-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,7 +27,7 @@ #include "ttsubpix.h" -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /*************************************************************************/ /* */ @@ -1000,12 +1000,12 @@ } } -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#else /* !TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* ANSI C doesn't like empty source files */ typedef int _tt_subpix_dummy; -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* !TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* END */ diff --git a/third_party/freetype/src/truetype/ttsubpix.h b/third_party/freetype/src/truetype/ttsubpix.h index 9151aa3250..c68f97ff07 100644 --- a/third_party/freetype/src/truetype/ttsubpix.h +++ b/third_party/freetype/src/truetype/ttsubpix.h @@ -4,7 +4,7 @@ /* */ /* TrueType Subpixel Hinting. */ /* */ -/* Copyright 2010-2015 by */ +/* Copyright 2010-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTSUBPIX_H__ -#define __TTSUBPIX_H__ +#ifndef TTSUBPIX_H_ +#define TTSUBPIX_H_ #include <ft2build.h> #include "ttobjs.h" @@ -27,7 +27,7 @@ FT_BEGIN_HEADER -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /*************************************************************************/ /* */ @@ -100,11 +100,12 @@ FT_BEGIN_HEADER #define SPH_OPTION_SET_COMPATIBLE_WIDTHS FALSE #define SPH_OPTION_SET_RASTERIZER_VERSION 38 -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ FT_END_HEADER -#endif /* __TTSUBPIX_H__ */ +#endif /* TTSUBPIX_H_ */ + /* END */ diff --git a/third_party/freetype/src/type1/t1afm.c b/third_party/freetype/src/type1/t1afm.c index 7f32059f85..792ea2ff91 100644 --- a/third_party/freetype/src/type1/t1afm.c +++ b/third_party/freetype/src/type1/t1afm.c @@ -4,7 +4,7 @@ /* */ /* AFM support for Type 1 fonts (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -197,7 +197,7 @@ /* encoding of first glyph (1 byte) */ /* encoding of second glyph (1 byte) */ /* offset (little-endian short) */ - for ( ; p < limit ; p += 4 ) + for ( ; p < limit; p += 4 ) { kp->index1 = FT_Get_Char_Index( t1_face, p[0] ); kp->index2 = FT_Get_Char_Index( t1_face, p[1] ); @@ -208,7 +208,7 @@ kp++; } - if ( oldcharmap != NULL ) + if ( oldcharmap ) error = FT_Set_Charmap( t1_face, oldcharmap ); if ( error ) goto Exit; @@ -239,9 +239,19 @@ AFM_ParserRec parser; AFM_FontInfo fi = NULL; FT_Error error = FT_ERR( Unknown_File_Format ); - T1_Font t1_font = &( (T1_Face)t1_face )->type1; + T1_Face face = (T1_Face)t1_face; + T1_Font t1_font = &face->type1; + if ( face->afm_data ) + { + FT_TRACE1(( "T1_Read_Metrics:" + " Freeing previously attached metrics data.\n" )); + T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data ); + + face->afm_data = NULL; + } + if ( FT_NEW( fi ) || FT_FRAME_ENTER( stream->size ) ) goto Exit; @@ -250,7 +260,7 @@ fi->Ascender = t1_font->font_bbox.yMax; fi->Descender = t1_font->font_bbox.yMin; - psaux = (PSAux_Service)( (T1_Face)t1_face )->psaux; + psaux = (PSAux_Service)face->psaux; if ( psaux->afm_parser_funcs ) { error = psaux->afm_parser_funcs->init( &parser, @@ -298,15 +308,15 @@ if ( fi->NumKernPair ) { t1_face->face_flags |= FT_FACE_FLAG_KERNING; - ( (T1_Face)t1_face )->afm_data = fi; - fi = NULL; + face->afm_data = fi; + fi = NULL; } } FT_FRAME_EXIT(); Exit: - if ( fi != NULL ) + if ( fi ) T1_Done_Metrics( memory, fi ); return error; diff --git a/third_party/freetype/src/type1/t1afm.h b/third_party/freetype/src/type1/t1afm.h index 0f42f3e3a8..9f62cd013d 100644 --- a/third_party/freetype/src/type1/t1afm.h +++ b/third_party/freetype/src/type1/t1afm.h @@ -4,7 +4,7 @@ /* */ /* AFM support for Type 1 fonts (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1AFM_H__ -#define __T1AFM_H__ +#ifndef T1AFM_H_ +#define T1AFM_H_ #include <ft2build.h> #include "t1objs.h" @@ -48,7 +48,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1AFM_H__ */ +#endif /* T1AFM_H_ */ /* END */ diff --git a/third_party/freetype/src/type1/t1driver.c b/third_party/freetype/src/type1/t1driver.c index 571f2d2f8c..c2089947f9 100644 --- a/third_party/freetype/src/type1/t1driver.c +++ b/third_party/freetype/src/type1/t1driver.c @@ -4,7 +4,7 @@ /* */ /* Type 1 driver interface (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,6 +29,7 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_HASH_H #include FT_SERVICE_MULTIPLE_MASTERS_H #include FT_SERVICE_GLYPH_DICT_H @@ -87,8 +88,8 @@ static const FT_Service_GlyphDictRec t1_service_glyph_dict = { - (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)t1_get_name_index + (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, /* get_name */ + (FT_GlyphDict_NameIndexFunc)t1_get_name_index /* name_index */ }; @@ -106,7 +107,7 @@ static const FT_Service_PsFontNameRec t1_service_ps_name = { - (FT_PsName_GetFunc)t1_get_ps_name + (FT_PsName_GetFunc)t1_get_ps_name /* get_ps_font_name */ }; @@ -118,11 +119,16 @@ #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT static const FT_Service_MultiMastersRec t1_service_multi_masters = { - (FT_Get_MM_Func) T1_Get_Multi_Master, - (FT_Set_MM_Design_Func) T1_Set_MM_Design, - (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, - (FT_Get_MM_Var_Func) T1_Get_MM_Var, - (FT_Set_Var_Design_Func)T1_Set_Var_Design + (FT_Get_MM_Func) T1_Get_Multi_Master, /* get_mm */ + (FT_Set_MM_Design_Func) T1_Set_MM_Design, /* set_mm_design */ + (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, /* set_mm_blend */ + (FT_Get_MM_Blend_Func) T1_Get_MM_Blend, /* get_mm_blend */ + (FT_Get_MM_Var_Func) T1_Get_MM_Var, /* get_mm_var */ + (FT_Set_Var_Design_Func)T1_Set_Var_Design, /* set_var_design */ + (FT_Get_Var_Design_Func)T1_Get_Var_Design, /* get_var_design */ + + (FT_Get_Var_Blend_Func) NULL, /* get_var_blend */ + (FT_Done_Blend_Func) T1_Done_Blend /* done_blend */ }; #endif @@ -329,13 +335,37 @@ break; case PS_DICT_SUBR: - if ( idx < (FT_UInt)type1->num_subrs ) { - retval = type1->subrs_len[idx] + 1; - if ( value && value_len >= retval ) + FT_Bool ok = 0; + + + if ( type1->subrs_hash ) { - ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 ); - ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; + /* convert subr index to array index */ + size_t* val = ft_hash_num_lookup( (FT_Int)idx, + type1->subrs_hash ); + + + if ( val ) + { + idx = *val; + ok = 1; + } + } + else + { + if ( idx < (FT_UInt)type1->num_subrs ) + ok = 1; + } + + if ( ok ) + { + retval = type1->subrs_len[idx] + 1; + if ( value && value_len >= retval ) + { + ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 ); + ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; + } } } break; @@ -567,18 +597,18 @@ static const FT_Service_PsInfoRec t1_service_ps_info = { - (PS_GetFontInfoFunc) t1_ps_get_font_info, - (PS_GetFontExtraFunc) t1_ps_get_font_extra, - (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, - (PS_GetFontPrivateFunc)t1_ps_get_font_private, - (PS_GetFontValueFunc) t1_ps_get_font_value, + (PS_GetFontInfoFunc) t1_ps_get_font_info, /* ps_get_font_info */ + (PS_GetFontExtraFunc) t1_ps_get_font_extra, /* ps_get_font_extra */ + (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, /* ps_has_glyph_names */ + (PS_GetFontPrivateFunc)t1_ps_get_font_private, /* ps_get_font_private */ + (PS_GetFontValueFunc) t1_ps_get_font_value, /* ps_get_font_value */ }; #ifndef T1_CONFIG_OPTION_NO_AFM static const FT_Service_KerningRec t1_service_kerning = { - T1_Get_Track_Kerning, + T1_Get_Track_Kerning, /* get_track */ }; #endif @@ -689,36 +719,37 @@ 0x10000L, 0x20000L, - 0, /* format interface */ + NULL, /* module-specific interface */ - T1_Driver_Init, - T1_Driver_Done, - Get_Interface, + T1_Driver_Init, /* FT_Module_Constructor module_init */ + T1_Driver_Done, /* FT_Module_Destructor module_done */ + Get_Interface, /* FT_Module_Requester get_interface */ }, sizeof ( T1_FaceRec ), sizeof ( T1_SizeRec ), sizeof ( T1_GlyphSlotRec ), - T1_Face_Init, - T1_Face_Done, - T1_Size_Init, - T1_Size_Done, - T1_GlyphSlot_Init, - T1_GlyphSlot_Done, + T1_Face_Init, /* FT_Face_InitFunc init_face */ + T1_Face_Done, /* FT_Face_DoneFunc done_face */ + T1_Size_Init, /* FT_Size_InitFunc init_size */ + T1_Size_Done, /* FT_Size_DoneFunc done_size */ + T1_GlyphSlot_Init, /* FT_Slot_InitFunc init_slot */ + T1_GlyphSlot_Done, /* FT_Slot_DoneFunc done_slot */ - T1_Load_Glyph, + T1_Load_Glyph, /* FT_Slot_LoadFunc load_glyph */ #ifdef T1_CONFIG_OPTION_NO_AFM - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ + NULL, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ #else - Get_Kerning, - T1_Read_Metrics, + Get_Kerning, /* FT_Face_GetKerningFunc get_kerning */ + T1_Read_Metrics, /* FT_Face_AttachFunc attach_file */ #endif - T1_Get_Advances, - T1_Size_Request, - 0 /* FT_Size_SelectFunc */ + T1_Get_Advances, /* FT_Face_GetAdvancesFunc get_advances */ + + T1_Size_Request, /* FT_Size_RequestFunc request_size */ + NULL /* FT_Size_SelectFunc select_size */ }; diff --git a/third_party/freetype/src/type1/t1driver.h b/third_party/freetype/src/type1/t1driver.h index 34bcf81ccf..292786448d 100644 --- a/third_party/freetype/src/type1/t1driver.h +++ b/third_party/freetype/src/type1/t1driver.h @@ -4,7 +4,7 @@ /* */ /* High-level Type 1 driver interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1DRIVER_H__ -#define __T1DRIVER_H__ +#ifndef T1DRIVER_H_ +#define T1DRIVER_H_ #include <ft2build.h> @@ -36,7 +36,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1DRIVER_H__ */ +#endif /* T1DRIVER_H_ */ /* END */ diff --git a/third_party/freetype/src/type1/t1errors.h b/third_party/freetype/src/type1/t1errors.h index fc7a9bd64e..492dbb4a42 100644 --- a/third_party/freetype/src/type1/t1errors.h +++ b/third_party/freetype/src/type1/t1errors.h @@ -4,7 +4,7 @@ /* */ /* Type 1 error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __T1ERRORS_H__ -#define __T1ERRORS_H__ +#ifndef T1ERRORS_H_ +#define T1ERRORS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX T1_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __T1ERRORS_H__ */ +#endif /* T1ERRORS_H_ */ /* END */ diff --git a/third_party/freetype/src/type1/t1gload.c b/third_party/freetype/src/type1/t1gload.c index 85ada2ea6a..aaf19b6dcc 100644 --- a/third_party/freetype/src/type1/t1gload.c +++ b/third_party/freetype/src/type1/t1gload.c @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -183,6 +183,7 @@ decoder.num_subrs = type1->num_subrs; decoder.subrs = type1->subrs; decoder.subrs_len = type1->subrs_len; + decoder.subrs_hash = type1->subrs_hash; decoder.buildchar = face->buildchar; decoder.len_buildchar = face->len_buildchar; @@ -245,9 +246,10 @@ 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.subrs_hash = type1->subrs_hash; decoder.buildchar = face->buildchar; decoder.len_buildchar = face->len_buildchar; @@ -346,6 +348,7 @@ decoder.num_subrs = type1->num_subrs; decoder.subrs = type1->subrs; decoder.subrs_len = type1->subrs_len; + decoder.subrs_hash = type1->subrs_hash; decoder.buildchar = face->buildchar; decoder.len_buildchar = face->len_buildchar; diff --git a/third_party/freetype/src/type1/t1gload.h b/third_party/freetype/src/type1/t1gload.h index 05f60d586a..cc4d5e734f 100644 --- a/third_party/freetype/src/type1/t1gload.h +++ b/third_party/freetype/src/type1/t1gload.h @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1GLOAD_H__ -#define __T1GLOAD_H__ +#ifndef T1GLOAD_H_ +#define T1GLOAD_H_ #include <ft2build.h> @@ -47,7 +47,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1GLOAD_H__ */ +#endif /* T1GLOAD_H_ */ /* END */ diff --git a/third_party/freetype/src/type1/t1load.c b/third_party/freetype/src/type1/t1load.c index dbf4eafd71..f5c661f7de 100644 --- a/third_party/freetype/src/type1/t1load.c +++ b/third_party/freetype/src/type1/t1load.c @@ -4,7 +4,7 @@ /* */ /* Type 1 font loader (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -66,6 +66,7 @@ #include FT_MULTIPLE_MASTERS_H #include FT_INTERNAL_TYPE1_TYPES_H #include FT_INTERNAL_CALC_H +#include FT_INTERNAL_HASH_H #include "t1load.h" #include "t1errors.h" @@ -236,7 +237,7 @@ if ( ncv <= axismap->blend_points[0] ) return INT_TO_FIXED( axismap->design_points[0] ); - for ( j = 1; j < axismap->num_points; ++j ) + for ( j = 1; j < axismap->num_points; j++ ) { if ( ncv <= axismap->blend_points[j] ) return INT_TO_FIXED( axismap->design_points[j - 1] ) + @@ -320,12 +321,12 @@ mmvar->num_axis = mmaster.num_axis; mmvar->num_designs = mmaster.num_designs; - mmvar->num_namedstyles = ~0U; /* Does not apply */ + mmvar->num_namedstyles = 0; /* Not supported */ mmvar->axis = (FT_Var_Axis*)&mmvar[1]; /* Point to axes after MM_Var struct */ mmvar->namedstyle = NULL; - for ( i = 0 ; i < mmaster.num_axis; ++i ) + for ( i = 0; i < mmaster.num_axis; i++ ) { mmvar->axis[i].name = mmaster.axis[i].name; mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum); @@ -336,6 +337,9 @@ mmvar->axis[i].strid = ~0U; /* Does not apply */ mmvar->axis[i].tag = ~0U; /* Does not apply */ + if ( !mmvar->axis[i].name ) + continue; + if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 ) mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' ); else if ( ft_strcmp( mmvar->axis[i].name, "Width" ) == 0 ) @@ -350,7 +354,7 @@ axiscoords, blend->num_axis ); - for ( i = 0; i < mmaster.num_axis; ++i ) + for ( i = 0; i < mmaster.num_axis; i++ ) mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i], axiscoords[i] ); } @@ -409,6 +413,41 @@ FT_LOCAL_DEF( FT_Error ) + T1_Get_MM_Blend( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + PS_Blend blend = face->blend; + + FT_Fixed axiscoords[4]; + FT_UInt i, nc; + + + if ( !blend ) + return FT_THROW( Invalid_Argument ); + + mm_weights_unmap( blend->weight_vector, + axiscoords, + blend->num_axis ); + + nc = num_coords; + if ( num_coords > blend->num_axis ) + { + FT_TRACE2(( "T1_Get_MM_Blend: only using first %d of %d coordinates\n", + blend->num_axis, num_coords )); + nc = blend->num_axis; + } + + for ( i = 0; i < nc; i++ ) + coords[i] = axiscoords[i]; + for ( ; i < num_coords; i++ ) + coords[i] = 0x8000; + + return FT_Err_Ok; + } + + + FT_LOCAL_DEF( FT_Error ) T1_Set_MM_Design( T1_Face face, FT_UInt num_coords, FT_Long* coords ) @@ -500,13 +539,49 @@ if ( num_coords > T1_MAX_MM_AXIS ) num_coords = T1_MAX_MM_AXIS; - for ( i = 0; i < num_coords; ++i ) + for ( i = 0; i < num_coords; i++ ) lcoords[i] = FIXED_TO_INT( coords[i] ); return T1_Set_MM_Design( face, num_coords, lcoords ); } + FT_LOCAL_DEF( FT_Error ) + T1_Get_Var_Design( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + PS_Blend blend = face->blend; + + FT_Fixed axiscoords[4]; + FT_UInt i, nc; + + + if ( !blend ) + return FT_THROW( Invalid_Argument ); + + mm_weights_unmap( blend->weight_vector, + axiscoords, + blend->num_axis ); + + nc = num_coords; + if ( num_coords > blend->num_axis ) + { + FT_TRACE2(( "T1_Get_Var_Design:" + " only using first %d of %d coordinates\n", + blend->num_axis, num_coords )); + nc = blend->num_axis; + } + + for ( i = 0; i < nc; i++ ) + coords[i] = mm_axis_unmap( &blend->design_map[i], axiscoords[i] ); + for ( ; i < num_coords; i++ ) + coords[i] = 0; + + return FT_Err_Ok; + } + + FT_LOCAL_DEF( void ) T1_Done_Blend( T1_Face face ) { @@ -1401,6 +1476,7 @@ FT_Memory memory = parser->root.memory; FT_Error error; FT_Int num_subrs; + FT_UInt count; PSAux_Service psaux = (PSAux_Service)face->psaux; @@ -1420,6 +1496,47 @@ } num_subrs = (FT_Int)T1_ToInt( parser ); + if ( num_subrs < 0 ) + { + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } + + /* we certainly need more than 8 bytes per subroutine */ + if ( parser->root.limit >= parser->root.cursor && + num_subrs > ( parser->root.limit - parser->root.cursor ) >> 3 ) + { + /* + * There are two possibilities. Either the font contains an invalid + * value for `num_subrs', or we have a subsetted font where the + * subroutine indices are not adjusted, e.g. + * + * /Subrs 812 array + * dup 0 { ... } NP + * dup 51 { ... } NP + * dup 681 { ... } NP + * ND + * + * In both cases, we use a number hash that maps from subr indices to + * actual array elements. + */ + + FT_TRACE0(( "parse_subrs: adjusting number of subroutines" + " (from %d to %d)\n", + num_subrs, + ( parser->root.limit - parser->root.cursor ) >> 3 )); + num_subrs = ( parser->root.limit - parser->root.cursor ) >> 3; + + if ( !loader->subrs_hash ) + { + if ( FT_NEW( loader->subrs_hash ) ) + goto Fail; + + error = ft_hash_num_init( loader->subrs_hash, memory ); + if ( error ) + goto Fail; + } + } /* position the parser right before the `dup' of the first subr */ T1_Skip_PS_Token( parser ); /* `array' */ @@ -1440,7 +1557,7 @@ /* */ /* `index' + binary data */ /* */ - for (;;) + for ( count = 0; ; count++ ) { FT_Long idx; FT_ULong size; @@ -1476,6 +1593,14 @@ T1_Skip_Spaces ( parser ); } + /* if we use a hash, the subrs index is the key, and a running */ + /* counter specified for `T1_Add_Table' acts as the value */ + if ( loader->subrs_hash ) + { + ft_hash_num_insert( idx, count, loader->subrs_hash, memory ); + idx = count; + } + /* with synthetic fonts it is possible we get here twice */ if ( loader->num_subrs ) continue; @@ -1487,7 +1612,7 @@ /* */ if ( face->type1.private_dict.lenIV >= 0 ) { - FT_Byte* temp; + FT_Byte* temp = NULL; /* some fonts define empty subr records -- this is not totally */ @@ -1691,7 +1816,7 @@ if ( face->type1.private_dict.lenIV >= 0 && n < num_glyphs + TABLE_EXTEND ) { - FT_Byte* temp; + FT_Byte* temp = NULL; if ( size <= (FT_ULong)face->type1.private_dict.lenIV ) @@ -1719,6 +1844,12 @@ } } + if ( !n ) + { + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + loader->num_glyphs = n; /* if /.notdef is found but does not occupy index 0, do our magic. */ @@ -2047,7 +2178,7 @@ parser->root.error = t1_load_keyword( face, loader, keyword ); - if ( parser->root.error != FT_Err_Ok ) + if ( parser->root.error ) { if ( FT_ERR_EQ( parser->root.error, Ignore ) ) parser->root.error = FT_Err_Ok; @@ -2086,18 +2217,7 @@ { FT_UNUSED( face ); - FT_MEM_ZERO( loader, sizeof ( *loader ) ); - loader->num_glyphs = 0; - 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->keywords_encountered = 0; + FT_ZERO( loader ); } @@ -2105,6 +2225,7 @@ t1_done_loader( T1_Loader loader ) { T1_Parser parser = &loader->parser; + FT_Memory memory = parser->root.memory; /* finalize tables */ @@ -2114,6 +2235,10 @@ T1_Release_Table( &loader->swap_table ); T1_Release_Table( &loader->subrs ); + /* finalize hash */ + ft_hash_num_free( loader->subrs_hash, memory ); + FT_FREE( loader->subrs_hash ); + /* finalize parser */ T1_Finalize_Parser( parser ); } @@ -2230,11 +2355,15 @@ if ( loader.subrs.init ) { - loader.subrs.init = 0; type1->num_subrs = loader.num_subrs; type1->subrs_block = loader.subrs.block; type1->subrs = loader.subrs.elements; type1->subrs_len = loader.subrs.lengths; + type1->subrs_hash = loader.subrs_hash; + + /* prevent `t1_done_loader' from freeing the propagated data */ + loader.subrs.init = 0; + loader.subrs_hash = NULL; } if ( !IS_INCREMENTAL ) diff --git a/third_party/freetype/src/type1/t1load.h b/third_party/freetype/src/type1/t1load.h index de422e7ecd..2d86984f0e 100644 --- a/third_party/freetype/src/type1/t1load.h +++ b/third_party/freetype/src/type1/t1load.h @@ -4,7 +4,7 @@ /* */ /* Type 1 font loader (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1LOAD_H__ -#define __T1LOAD_H__ +#ifndef T1LOAD_H_ +#define T1LOAD_H_ #include <ft2build.h> @@ -46,6 +46,7 @@ FT_BEGIN_HEADER FT_Int num_subrs; PS_TableRec subrs; + FT_Hash subrs_hash; FT_Bool fontdata; FT_UInt keywords_encountered; /* T1_LOADER_ENCOUNTERED_XXX */ @@ -69,7 +70,7 @@ FT_BEGIN_HEADER T1_Get_Multi_Master( T1_Face face, FT_Multi_Master* master ); - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL( FT_Error ) T1_Get_MM_Var( T1_Face face, FT_MM_Var* *master ); @@ -79,11 +80,21 @@ FT_BEGIN_HEADER FT_Fixed* coords ); FT_LOCAL( FT_Error ) + T1_Get_MM_Blend( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + FT_LOCAL( FT_Error ) T1_Set_MM_Design( T1_Face face, FT_UInt num_coords, FT_Long* coords ); - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL( FT_Error ) + T1_Get_Var_Design( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + FT_LOCAL( FT_Error ) T1_Set_Var_Design( T1_Face face, FT_UInt num_coords, FT_Fixed* coords ); @@ -96,7 +107,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1LOAD_H__ */ +#endif /* T1LOAD_H_ */ /* END */ diff --git a/third_party/freetype/src/type1/t1objs.c b/third_party/freetype/src/type1/t1objs.c index d921063eaa..5637035c80 100644 --- a/third_party/freetype/src/type1/t1objs.c +++ b/third_party/freetype/src/type1/t1objs.c @@ -4,7 +4,7 @@ /* */ /* Type 1 objects manager (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -67,7 +67,7 @@ "pshinter" ); return ( module && pshinter && pshinter->get_globals_funcs ) ? pshinter->get_globals_funcs( module ) - : 0 ; + : 0; } @@ -247,6 +247,9 @@ FT_FREE( type1->subrs ); FT_FREE( type1->subrs_len ); + ft_hash_num_free( type1->subrs_hash, memory ); + FT_FREE( type1->subrs_hash ); + FT_FREE( type1->subrs_block ); FT_FREE( type1->charstrings_block ); FT_FREE( type1->glyph_names_block ); diff --git a/third_party/freetype/src/type1/t1objs.h b/third_party/freetype/src/type1/t1objs.h index 6b4f3cb56d..39d26bf8b9 100644 --- a/third_party/freetype/src/type1/t1objs.h +++ b/third_party/freetype/src/type1/t1objs.h @@ -4,7 +4,7 @@ /* */ /* Type 1 objects manager (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1OBJS_H__ -#define __T1OBJS_H__ +#ifndef T1OBJS_H_ +#define T1OBJS_H_ #include <ft2build.h> @@ -154,7 +154,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1OBJS_H__ */ +#endif /* T1OBJS_H_ */ /* END */ diff --git a/third_party/freetype/src/type1/t1parse.c b/third_party/freetype/src/type1/t1parse.c index 0b68502606..18dd26434c 100644 --- a/third_party/freetype/src/type1/t1parse.c +++ b/third_party/freetype/src/type1/t1parse.c @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -437,7 +437,7 @@ *cur == '\t' || (test_cr && *cur == '\r' ) || *cur == '\n' ) ) - ++cur; + cur++; if ( cur >= limit ) { FT_ERROR(( "T1_Get_Private_Dict:" diff --git a/third_party/freetype/src/type1/t1parse.h b/third_party/freetype/src/type1/t1parse.h index 93b02e3d31..3396680d1a 100644 --- a/third_party/freetype/src/type1/t1parse.h +++ b/third_party/freetype/src/type1/t1parse.h @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1PARSE_H__ -#define __T1PARSE_H__ +#ifndef T1PARSE_H_ +#define T1PARSE_H_ #include <ft2build.h> @@ -123,7 +123,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1PARSE_H__ */ +#endif /* T1PARSE_H_ */ /* END */ diff --git a/third_party/freetype/src/type1/t1tokens.h b/third_party/freetype/src/type1/t1tokens.h index 3992652435..ca0c55f903 100644 --- a/third_party/freetype/src/type1/t1tokens.h +++ b/third_party/freetype/src/type1/t1tokens.h @@ -4,7 +4,7 @@ /* */ /* Type 1 tokenizer (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/type1/type1.c b/third_party/freetype/src/type1/type1.c index 4c70ea7630..bfe0e439fe 100644 --- a/third_party/freetype/src/type1/type1.c +++ b/third_party/freetype/src/type1/type1.c @@ -4,7 +4,7 @@ /* */ /* FreeType Type 1 driver component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ |