From dfc717c4588b40441c3ce2c888b1dd4f53eda2d8 Mon Sep 17 00:00:00 2001 From: volzhs Date: Tue, 10 Oct 2017 01:33:39 +0900 Subject: Update freetype to 2.8.1 --- .../freetype/include/freetype/config/ftoption.h | 21 +- thirdparty/freetype/include/freetype/freetype.h | 37 ++- thirdparty/freetype/include/freetype/ftautoh.h | 14 +- thirdparty/freetype/include/freetype/fterrdef.h | 2 + thirdparty/freetype/include/freetype/fterrors.h | 6 +- thirdparty/freetype/include/freetype/ftglyph.h | 9 + thirdparty/freetype/include/freetype/ftimage.h | 20 +- thirdparty/freetype/include/freetype/ftlcdfil.h | 19 +- thirdparty/freetype/include/freetype/ftmac.h | 9 +- thirdparty/freetype/include/freetype/ftmm.h | 64 ++++- thirdparty/freetype/include/freetype/ftoutln.h | 3 + .../freetype/include/freetype/internal/ftcalc.h | 36 ++- .../freetype/include/freetype/internal/ftobjs.h | 34 ++- thirdparty/freetype/include/freetype/tttags.h | 6 + thirdparty/freetype/src/autofit/afblue.c | 12 +- thirdparty/freetype/src/autofit/afblue.dat | 20 +- thirdparty/freetype/src/autofit/afblue.h | 10 +- thirdparty/freetype/src/autofit/afcjk.c | 12 +- thirdparty/freetype/src/autofit/afhints.c | 6 +- thirdparty/freetype/src/autofit/aflatin.c | 33 ++- thirdparty/freetype/src/autofit/aflatin2.c | 12 +- thirdparty/freetype/src/autofit/afloader.c | 8 +- thirdparty/freetype/src/autofit/afscript.h | 24 +- thirdparty/freetype/src/autofit/afshaper.c | 1 + thirdparty/freetype/src/autofit/afstyles.h | 28 +- thirdparty/freetype/src/base/ftbitmap.c | 5 +- thirdparty/freetype/src/base/ftcalc.c | 150 +++++----- thirdparty/freetype/src/base/ftglyph.c | 16 ++ thirdparty/freetype/src/base/ftlcdfil.c | 211 ++++++-------- thirdparty/freetype/src/base/ftmac.c | 2 +- thirdparty/freetype/src/base/ftmm.c | 32 ++- thirdparty/freetype/src/base/ftobjs.c | 38 +-- thirdparty/freetype/src/base/ftoutln.c | 3 +- thirdparty/freetype/src/base/ftrfork.c | 10 +- thirdparty/freetype/src/base/ftsynth.c | 2 +- thirdparty/freetype/src/base/ftutil.c | 10 +- thirdparty/freetype/src/bdf/bdfdrivr.c | 144 ++++++++-- thirdparty/freetype/src/bdf/bdflib.c | 40 ++- thirdparty/freetype/src/cache/ftcbasic.c | 38 ++- thirdparty/freetype/src/cff/cf2blues.c | 45 +-- thirdparty/freetype/src/cff/cf2blues.h | 2 +- thirdparty/freetype/src/cff/cf2fixed.h | 4 +- thirdparty/freetype/src/cff/cf2font.c | 4 +- thirdparty/freetype/src/cff/cf2ft.c | 4 +- thirdparty/freetype/src/cff/cf2hints.c | 255 +++++++++-------- thirdparty/freetype/src/cff/cf2intrp.c | 179 +++++++----- thirdparty/freetype/src/cff/cffgload.c | 207 ++++++++------ thirdparty/freetype/src/cff/cffload.c | 9 +- thirdparty/freetype/src/cff/cffparse.c | 27 +- thirdparty/freetype/src/gxvalid/README | 2 +- thirdparty/freetype/src/pcf/README | 4 +- thirdparty/freetype/src/pcf/pcfdrivr.c | 12 +- thirdparty/freetype/src/pcf/pcfread.c | 78 +++++- thirdparty/freetype/src/pfr/pfrobjs.c | 6 - thirdparty/freetype/src/psaux/psconv.c | 8 + thirdparty/freetype/src/psaux/t1decode.c | 92 ++++--- thirdparty/freetype/src/psnames/psmodule.c | 13 + thirdparty/freetype/src/psnames/pstables.h | 36 +-- thirdparty/freetype/src/raster/ftrend1.c | 9 +- thirdparty/freetype/src/sfnt/pngshim.c | 72 ++++- thirdparty/freetype/src/sfnt/sfobjs.c | 51 +++- thirdparty/freetype/src/sfnt/ttcmap.c | 112 +++++++- thirdparty/freetype/src/sfnt/ttcmap.h | 2 + thirdparty/freetype/src/sfnt/ttkern.c | 8 +- thirdparty/freetype/src/sfnt/ttpost.c | 7 +- thirdparty/freetype/src/sfnt/ttsbit.c | 20 +- thirdparty/freetype/src/smooth/ftgrays.c | 15 +- thirdparty/freetype/src/smooth/ftsmooth.c | 192 ++++++++----- thirdparty/freetype/src/truetype/ttgload.c | 101 +++++-- thirdparty/freetype/src/truetype/ttgxvar.c | 97 +++++-- thirdparty/freetype/src/truetype/ttinterp.c | 303 +++++++++++++-------- thirdparty/freetype/src/truetype/ttinterp.h | 50 ++-- thirdparty/freetype/src/truetype/ttobjs.c | 16 +- thirdparty/freetype/src/truetype/ttpload.c | 8 +- thirdparty/freetype/src/type1/t1load.c | 4 +- thirdparty/freetype/src/type1/t1objs.c | 6 - thirdparty/freetype/src/type42/t42objs.c | 6 - thirdparty/freetype/src/winfonts/winfnt.c | 6 +- 78 files changed, 2096 insertions(+), 1123 deletions(-) (limited to 'thirdparty/freetype') diff --git a/thirdparty/freetype/include/freetype/config/ftoption.h b/thirdparty/freetype/include/freetype/config/ftoption.h index 1bf6e8f534..2fbe80b9b4 100644 --- a/thirdparty/freetype/include/freetype/config/ftoption.h +++ b/thirdparty/freetype/include/freetype/config/ftoption.h @@ -107,20 +107,17 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ - /* Uncomment the line below if you want to activate sub-pixel rendering */ - /* (a.k.a. LCD rendering, or ClearType) in this build of the library. */ + /* Uncomment the line below if you want to activate LCD rendering */ + /* technology similar to ClearType in this build of the library. This */ + /* technology triples the resolution in the direction color subpixels. */ + /* To mitigate color fringes inherent to this technology, you also need */ + /* to explicitly set up LCD filtering. */ /* */ /* Note that this feature is covered by several Microsoft patents */ /* and should not be activated in any default build of the library. */ - /* */ - /* This macro has no impact on the FreeType API, only on its */ - /* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */ - /* FT_Render_Glyph still generates a bitmap that is 3 times wider than */ - /* the original size in case this macro isn't defined; however, each */ - /* triplet of subpixels has R=G=B. */ - /* */ - /* This is done to allow FreeType clients to run unmodified, forcing */ - /* them to display normal gray-level anti-aliased glyphs. */ + /* When this macro is not defined, FreeType offers alternative LCD */ + /* rendering technology that produces excellent output without LCD */ + /* filtering. */ /* */ /* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ @@ -327,7 +324,7 @@ FT_BEGIN_HEADER /* */ /* - The TrueType driver will provide its own set of glyph names, */ /* if you build it to support postscript names in the TrueType */ - /* `post' table. */ + /* `post' table, but will not synthesize a missing Unicode charmap. */ /* */ /* - The Type 1 driver will not be able to synthesize a Unicode */ /* charmap out of the glyphs found in the fonts. */ diff --git a/thirdparty/freetype/include/freetype/freetype.h b/thirdparty/freetype/include/freetype/freetype.h index 2989fbb5e1..b0c261799a 100644 --- a/thirdparty/freetype/include/freetype/freetype.h +++ b/thirdparty/freetype/include/freetype/freetype.h @@ -575,7 +575,8 @@ FT_BEGIN_HEADER /* */ /* When a new face is created (either through @FT_New_Face or */ /* @FT_Open_Face), the library looks for a Unicode charmap within */ - /* the list and automatically activates it. */ + /* the list and automatically activates it. If there is no Unicode */ + /* charmap, FreeType doesn't set an `active' charmap. */ /* */ /* */ /* See @FT_CharMapRec for the publicly accessible fields of a given */ @@ -1529,7 +1530,13 @@ FT_BEGIN_HEADER /* values of the corresponding fields in @FT_FaceRec. Some values */ /* like ascender or descender are rounded for historical reasons; */ /* more precise values (for outline fonts) can be derived by scaling */ - /* the corresponding @FT_FaceRec values manually. */ + /* the corresponding @FT_FaceRec values manually, with code similar */ + /* to the following. */ + /* */ + /* { */ + /* scaled_ascender = FT_MulFix( face->root.ascender, */ + /* size_metrics->y_scale ); */ + /* } */ /* */ /* Note that due to glyph hinting and the selected rendering mode */ /* these values are usually not exact; consequently, they must be */ @@ -1774,7 +1781,7 @@ FT_BEGIN_HEADER /* and add it to `origin_x'> */ /* */ /* origin_x += slot->advance.x; */ - /* origin_x += slot->rsb_delta - slot->lsb_relta; */ + /* origin_x += slot->rsb_delta - slot->lsb_delta; */ /* endfor */ /* } */ /* */ @@ -1794,9 +1801,9 @@ FT_BEGIN_HEADER /* */ /* */ /* */ - /* if ( prev_rsb_delta - slot->lsb_delta >= 32 ) */ + /* if ( prev_rsb_delta - slot->lsb_delta > 32 ) */ /* origin_x -= 64; */ - /* else if ( prev_rsb_delta - slot->lsb_delta < -32 ) */ + /* else if ( prev_rsb_delta - slot->lsb_delta < -31 ) */ /* origin_x += 64; */ /* */ /* prev_rsb_delta = slot->rsb_delta; */ @@ -3124,11 +3131,13 @@ FT_BEGIN_HEADER /* glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode. */ /* */ /* */ - /* 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. */ + /* Should you define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your */ + /* `ftoption.h', which enables patented ClearType-style rendering, */ + /* the LCD-optimized glyph bitmaps should be filtered to reduce color */ + /* fringes inherent to this technology. You can either set up LCD */ + /* filtering with @FT_Library_SetLcdFilter or @FT_Face_Properties, */ + /* or do the filtering yourself. The default FreeType LCD rendering */ + /* technology does not require filtering. */ /* */ /* The selected render mode only affects vector glyphs of a font. */ /* Embedded bitmaps often have a different pixel mode like */ @@ -4327,6 +4336,9 @@ FT_BEGIN_HEADER /* `a' rounded to the nearest 16.16 fixed integer, halfway cases away */ /* from zero. */ /* */ + /* */ + /* The function uses wrap-around arithmetic. */ + /* */ FT_EXPORT( FT_Fixed ) FT_RoundFix( FT_Fixed a ); @@ -4345,6 +4357,9 @@ FT_BEGIN_HEADER /* */ /* `a' rounded towards plus infinity. */ /* */ + /* */ + /* The function uses wrap-around arithmetic. */ + /* */ FT_EXPORT( FT_Fixed ) FT_CeilFix( FT_Fixed a ); @@ -4442,7 +4457,7 @@ FT_BEGIN_HEADER */ #define FREETYPE_MAJOR 2 #define FREETYPE_MINOR 8 -#define FREETYPE_PATCH 0 +#define FREETYPE_PATCH 1 /*************************************************************************/ diff --git a/thirdparty/freetype/include/freetype/ftautoh.h b/thirdparty/freetype/include/freetype/ftautoh.h index abd540f0b5..2bb675ae46 100644 --- a/thirdparty/freetype/include/freetype/ftautoh.h +++ b/thirdparty/freetype/include/freetype/ftautoh.h @@ -404,12 +404,12 @@ FT_BEGIN_HEADER * activate the warp hinting code in the auto-hinter, this property * switches warping on and off. * - * Warping only works in `light' auto-hinting mode. The idea of the - * code is to slightly scale and shift a glyph along the non-hinted - * dimension (which is usually the horizontal axis) so that as much of - * its segments are aligned (more or less) to the grid. To find out a - * glyph's optimal scaling and shifting value, various parameter - * combinations are tried and scored. + * Warping only works in `normal' auto-hinting mode replacing it. + * The idea of the code is to slightly scale and shift a glyph along + * the non-hinted dimension (which is usually the horizontal axis) so + * that as much of its segments are aligned (more or less) to the grid. + * To find out a glyph's optimal scaling and shifting value, various + * parameter combinations are tried and scored. * * By default, warping is off. The example below shows how to switch on * warping (omitting the error handling). @@ -437,7 +437,7 @@ FT_BEGIN_HEADER * * Since warping is a global property of the auto-hinter it is best to * change its value before rendering any face. Otherwise, you should - * reload all faces that get auto-hinted in `light' hinting mode. + * reload all faces that get auto-hinted in `normal' hinting mode. * */ diff --git a/thirdparty/freetype/include/freetype/fterrdef.h b/thirdparty/freetype/include/freetype/fterrdef.h index cabbac8273..6a6dc85b87 100644 --- a/thirdparty/freetype/include/freetype/fterrdef.h +++ b/thirdparty/freetype/include/freetype/fterrdef.h @@ -233,6 +233,8 @@ "invalid PostScript (post) table" ) FT_ERRORDEF_( DEF_In_Glyf_Bytecode, 0x9C, "found FDEF or IDEF opcode in glyf bytecode" ) + FT_ERRORDEF_( Missing_Bitmap, 0x9D, + "missing bitmap in strike" ) /* CFF, CID, and Type 1 errors */ diff --git a/thirdparty/freetype/include/freetype/fterrors.h b/thirdparty/freetype/include/freetype/fterrors.h index 42769fa7bf..ae382c419f 100644 --- a/thirdparty/freetype/include/freetype/fterrors.h +++ b/thirdparty/freetype/include/freetype/fterrors.h @@ -38,15 +38,15 @@ /* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */ /* defined in `ftoption.h' in order to make the higher byte indicate */ /* the module where the error has happened (this is not compatible */ - /* with standard builds of FreeType 2, however). See the file */ + /* with standard builds of FreeType~2, however). See the file */ /* `ftmoderr.h' for more details. */ /* */ /* *Error* *Message* *Strings* */ /* */ /* Error definitions are set up with special macros that allow client */ /* applications to build a table of error message strings. The */ - /* strings are not included in a normal build of FreeType 2 to */ - /* save space (most client applications do not use them). */ + /* strings are not included in a normal build of FreeType~2 to save */ + /* space (most client applications do not use them). */ /* */ /* To do so, you have to define the following macros before including */ /* this file. */ diff --git a/thirdparty/freetype/include/freetype/ftglyph.h b/thirdparty/freetype/include/freetype/ftglyph.h index 79879a7ac7..db1a2c8ba5 100644 --- a/thirdparty/freetype/include/freetype/ftglyph.h +++ b/thirdparty/freetype/include/freetype/ftglyph.h @@ -231,6 +231,12 @@ FT_BEGIN_HEADER /* */ /* FreeType error code. 0~means success. */ /* */ + /* */ + /* Because `*aglyph->advance.x' and '*aglyph->advance.y' are 16.16 */ + /* fixed-point numbers, `slot->advance.x' and `slot->advance.y' */ + /* (which are in 26.6 fixed-point format) must be in the range */ + /* ]-32768;32768[. */ + /* */ FT_EXPORT( FT_Error ) FT_Get_Glyph( FT_GlyphSlot slot, FT_Glyph *aglyph ); @@ -566,6 +572,9 @@ FT_BEGIN_HEADER /* */ /* The result is undefined if either `a' or `b' is zero. */ /* */ + /* Since the function uses wrap-around arithmetic, results become */ + /* meaningless if the arguments are very large. */ + /* */ FT_EXPORT( void ) FT_Matrix_Multiply( const FT_Matrix* a, FT_Matrix* b ); diff --git a/thirdparty/freetype/include/freetype/ftimage.h b/thirdparty/freetype/include/freetype/ftimage.h index 1a049ef16d..1c789e5a44 100644 --- a/thirdparty/freetype/include/freetype/ftimage.h +++ b/thirdparty/freetype/include/freetype/ftimage.h @@ -1064,24 +1064,24 @@ FT_BEGIN_HEADER /* */ /* */ /* FreeType used to provide an area of memory called the `render */ - /* pool' available to all registered rasters. This was not thread */ - /* safe however and now FreeType never allocates this pool. NULL */ - /* is always passed in as pool_base. */ + /* pool' available to all registered rasterizers. This was not */ + /* thread safe, however, and now FreeType never allocates this pool. */ /* */ - /* This function is called each time the render pool changes, or just */ - /* after a new raster object is created. */ + /* This function is called after a new raster object is created. */ /* */ /* */ /* raster :: A handle to the new raster object. */ /* */ - /* pool_base :: The address in memory of the render pool. */ + /* pool_base :: Previously, the address in memory of the render pool. */ + /* Set this to NULL. */ /* */ - /* pool_size :: The size in bytes of the render pool. */ + /* pool_size :: Previously, the size in bytes of the render pool. */ + /* Set this to 0. */ /* */ /* */ - /* Rasters should ignore the render pool and rely on dynamic or stack */ - /* allocation if they want to (a handle to the memory allocator is */ - /* passed to the raster constructor). */ + /* Rasterizers should rely on dynamic or stack allocation if they */ + /* want to (a handle to the memory allocator is passed to the */ + /* rasterizer constructor). */ /* */ typedef void (*FT_Raster_ResetFunc)( FT_Raster raster, diff --git a/thirdparty/freetype/include/freetype/ftlcdfil.h b/thirdparty/freetype/include/freetype/ftlcdfil.h index 680bd90c89..bdaf9af906 100644 --- a/thirdparty/freetype/include/freetype/ftlcdfil.h +++ b/thirdparty/freetype/include/freetype/ftlcdfil.h @@ -44,9 +44,16 @@ FT_BEGIN_HEADER * Reduce color fringes of subpixel-rendered bitmaps. * * @description: - * 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 + * Should you #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your + * `ftoption.h', which enables patented ClearType-style rendering, + * the LCD-optimized glyph bitmaps should be filtered to reduce color + * fringes inherent to this technology. The default FreeType LCD + * rendering uses different technology, and API described below, + * although available, does nothing. + * + * ClearType-style LCD 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 @@ -54,12 +61,6 @@ FT_BEGIN_HEADER * 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 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 diff --git a/thirdparty/freetype/include/freetype/ftmac.h b/thirdparty/freetype/include/freetype/ftmac.h index ad97c6e4c3..a1656eec0e 100644 --- a/thirdparty/freetype/include/freetype/ftmac.h +++ b/thirdparty/freetype/include/freetype/ftmac.h @@ -35,11 +35,12 @@ FT_BEGIN_HEADER -/* gcc-3.4.1 and later can warn about functions tagged as deprecated */ + /* gcc-3.1 and later can warn about functions tagged as deprecated */ #ifndef FT_DEPRECATED_ATTRIBUTE -#if defined(__GNUC__) && \ - ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) -#define FT_DEPRECATED_ATTRIBUTE __attribute__((deprecated)) +#if defined( __GNUC__ ) && \ + ( ( __GNUC__ >= 4 ) || \ + ( ( __GNUC__ == 3 ) && ( __GNUC_MINOR__ >= 1 ) ) ) +#define FT_DEPRECATED_ATTRIBUTE __attribute__(( deprecated )) #else #define FT_DEPRECATED_ATTRIBUTE #endif diff --git a/thirdparty/freetype/include/freetype/ftmm.h b/thirdparty/freetype/include/freetype/ftmm.h index c41b80ea67..80ac98d612 100644 --- a/thirdparty/freetype/include/freetype/ftmm.h +++ b/thirdparty/freetype/include/freetype/ftmm.h @@ -178,7 +178,8 @@ FT_BEGIN_HEADER /* strid :: The entry in `name' table identifying this instance. */ /* */ /* psid :: The entry in `name' table identifying a PostScript name */ - /* for this instance. */ + /* for this instance. Value 0xFFFF indicates a missing */ + /* entry. */ /* */ typedef struct FT_Var_Named_Style_ { @@ -195,7 +196,7 @@ FT_BEGIN_HEADER /* FT_MM_Var */ /* */ /* */ - /* A structure to model the axes and space of a Adobe MM, TrueType */ + /* A structure to model the axes and space of an Adobe MM, TrueType */ /* GX, or OpenType variation font. */ /* */ /* Some fields are specific to one format and not to the others. */ @@ -321,6 +322,11 @@ FT_BEGIN_HEADER /* */ /* FreeType error code. 0~means success. */ /* */ + /* */ + /* To reset all axes to the default values, call the function with */ + /* `num_coords' set to zero and `coords' set to NULL (new feature in */ + /* FreeType version 2.8.1). */ + /* */ FT_EXPORT( FT_Error ) FT_Set_MM_Design_Coordinates( FT_Face face, FT_UInt num_coords, @@ -351,6 +357,11 @@ FT_BEGIN_HEADER /* */ /* FreeType error code. 0~means success. */ /* */ + /* */ + /* To reset all axes to the default values, call the function with */ + /* `num_coords' set to zero and `coords' set to NULL (new feature in */ + /* FreeType version 2.8.1). */ + /* */ FT_EXPORT( FT_Error ) FT_Set_Var_Design_Coordinates( FT_Face face, FT_UInt num_coords, @@ -415,6 +426,11 @@ FT_BEGIN_HEADER /* */ /* FreeType error code. 0~means success. */ /* */ + /* */ + /* To reset all axes to the default values, call the function with */ + /* `num_coords' set to zero and `coords' set to NULL (new feature in */ + /* FreeType version 2.8.1). */ + /* */ FT_EXPORT( FT_Error ) FT_Set_MM_Blend_Coordinates( FT_Face face, FT_UInt num_coords, @@ -479,6 +495,50 @@ FT_BEGIN_HEADER FT_UInt num_coords, FT_Fixed* coords ); + + /*************************************************************************/ + /* */ + /* */ + /* FT_VAR_AXIS_FLAG_XXX */ + /* */ + /* */ + /* A list of bit flags used in the return value of */ + /* @FT_Get_Var_Axis_Flags. */ + /* */ + /* */ + /* FT_VAR_AXIS_FLAG_HIDDEN :: */ + /* The variation axis should not be exposed to user interfaces. */ + /* */ +#define FT_VAR_AXIS_FLAG_HIDDEN 1 + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Get_Var_Axis_Flags */ + /* */ + /* */ + /* Get the `flags' field of an OpenType Variation Axis Record. */ + /* */ + /* Not meaningful for Adobe MM fonts (`*flags' is always zero). */ + /* */ + /* */ + /* master :: The variation descriptor. */ + /* */ + /* axis_index :: The index of the requested variation axis. */ + /* */ + /* */ + /* flags :: The `flags' field. See @FT_VAR_AXIS_FLAG_XXX for */ + /* possible values. */ + /* */ + /* */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Var_Axis_Flags( FT_MM_Var* master, + FT_UInt axis_index, + FT_UInt* flags ); + /* */ diff --git a/thirdparty/freetype/include/freetype/ftoutln.h b/thirdparty/freetype/include/freetype/ftoutln.h index 07f73ebb1b..56f56a9603 100644 --- a/thirdparty/freetype/include/freetype/ftoutln.h +++ b/thirdparty/freetype/include/freetype/ftoutln.h @@ -385,6 +385,9 @@ FT_BEGIN_HEADER /* @FT_Outline_Embolden, which uses the same strength in both */ /* directions. */ /* */ + /* */ + /* 2.4.10 */ + /* */ FT_EXPORT( FT_Error ) FT_Outline_EmboldenXY( FT_Outline* outline, FT_Pos xstrength, diff --git a/thirdparty/freetype/include/freetype/internal/ftcalc.h b/thirdparty/freetype/include/freetype/internal/ftcalc.h index c9ac9d8246..8b35f03d88 100644 --- a/thirdparty/freetype/include/freetype/internal/ftcalc.h +++ b/thirdparty/freetype/include/freetype/internal/ftcalc.h @@ -399,16 +399,42 @@ FT_BEGIN_HEADER #endif /* 0 */ -#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) -#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) -#define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) -#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 ) -#define FLOAT_TO_FIXED( x ) ( (FT_Long)( x * 65536.0 ) ) +#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) * 64 ) /* << 6 */ +#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) * 16384 ) /* << 14 */ +#define INT_TO_FIXED( x ) ( (FT_Long)(x) * 65536 ) /* << 16 */ +#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) * 4 ) /* << 2 */ #define FIXED_TO_INT( x ) ( FT_RoundFix( x ) >> 16 ) #define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \ : ( -( ( 32 - (x) ) & -64 ) ) ) + /* + * The following macros have two purposes. + * + * . Tag places where overflow is expected and harmless. + * + * . Avoid run-time sanitizer errors. + * + * Use with care! + */ +#define ADD_LONG( a, b ) \ + (FT_Long)( (FT_ULong)(a) + (FT_ULong)(b) ) +#define SUB_LONG( a, b ) \ + (FT_Long)( (FT_ULong)(a) - (FT_ULong)(b) ) +#define MUL_LONG( a, b ) \ + (FT_Long)( (FT_ULong)(a) * (FT_ULong)(b) ) +#define NEG_LONG( a ) \ + (FT_Long)( (FT_ULong)0 - (FT_ULong)(a) ) + +#define ADD_INT32( a, b ) \ + (FT_Int32)( (FT_UInt32)(a) + (FT_UInt32)(b) ) +#define SUB_INT32( a, b ) \ + (FT_Int32)( (FT_UInt32)(a) - (FT_UInt32)(b) ) +#define MUL_INT32( a, b ) \ + (FT_Int32)( (FT_UInt32)(a) * (FT_UInt32)(b) ) +#define NEG_INT32( a ) \ + (FT_Int32)( (FT_UInt32)0 - (FT_UInt32)(a) ) + FT_END_HEADER diff --git a/thirdparty/freetype/include/freetype/internal/ftobjs.h b/thirdparty/freetype/include/freetype/internal/ftobjs.h index 558409166d..4231be238a 100644 --- a/thirdparty/freetype/include/freetype/internal/ftobjs.h +++ b/thirdparty/freetype/include/freetype/internal/ftobjs.h @@ -36,6 +36,7 @@ #include FT_INTERNAL_AUTOHINT_H #include FT_INTERNAL_SERVICE_H #include FT_INTERNAL_PIC_H +#include FT_INTERNAL_CALC_H #ifdef FT_CONFIG_OPTION_INCREMENTAL #include FT_INCREMENTAL_H @@ -85,13 +86,29 @@ FT_BEGIN_HEADER /* we use FT_TYPEOF to suppress signedness compilation warnings */ #define FT_PAD_FLOOR( x, n ) ( (x) & ~FT_TYPEOF( x )( (n)-1 ) ) -#define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + ((n)/2), n ) -#define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + ((n)-1), n ) +#define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + (n)/2, n ) +#define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + (n)-1, n ) #define FT_PIX_FLOOR( x ) ( (x) & ~FT_TYPEOF( x )63 ) #define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 ) #define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 ) + /* specialized versions (for signed values) */ + /* that don't produce run-time errors due to integer overflow */ +#define FT_PAD_ROUND_LONG( x, n ) FT_PAD_FLOOR( ADD_LONG( (x), (n) / 2 ), \ + n ) +#define FT_PAD_CEIL_LONG( x, n ) FT_PAD_FLOOR( ADD_LONG( (x), (n) - 1 ), \ + n ) +#define FT_PIX_ROUND_LONG( x ) FT_PIX_FLOOR( ADD_LONG( (x), 32 ) ) +#define FT_PIX_CEIL_LONG( x ) FT_PIX_FLOOR( ADD_LONG( (x), 63 ) ) + +#define FT_PAD_ROUND_INT32( x, n ) FT_PAD_FLOOR( ADD_INT32( (x), (n) / 2 ), \ + n ) +#define FT_PAD_CEIL_INT32( x, n ) FT_PAD_FLOOR( ADD_INT32( (x), (n) - 1 ), \ + n ) +#define FT_PIX_ROUND_INT32( x ) FT_PIX_FLOOR( ADD_INT32( (x), 32 ) ) +#define FT_PIX_CEIL_INT32( x ) FT_PIX_FLOOR( ADD_INT32( (x), 63 ) ) + /* * character classification functions -- since these are used to parse @@ -856,11 +873,6 @@ FT_BEGIN_HEADER /* */ /* auto_hinter :: The auto-hinter module interface. */ /* */ - /* raster_pool :: The raster object's render pool. This can */ - /* ideally be changed dynamically at run-time. */ - /* */ - /* raster_pool_size :: The size of the render pool in bytes. */ - /* */ /* debug_hooks :: An array of four function pointers that allow */ /* debuggers to hook into a font format's */ /* interpreter. Currently, only the TrueType */ @@ -869,9 +881,6 @@ FT_BEGIN_HEADER /* lcd_filter :: If subpixel rendering is activated, the */ /* selected LCD filter mode. */ /* */ - /* lcd_extra :: If subpixel rendering is activated, the number */ - /* of extra pixels needed for the LCD filter. */ - /* */ /* lcd_weights :: If subpixel rendering is activated, the LCD */ /* filter weights, if any. */ /* */ @@ -903,15 +912,10 @@ FT_BEGIN_HEADER FT_Renderer cur_renderer; /* current outline renderer */ FT_Module auto_hinter; - FT_Byte* raster_pool; /* scan-line conversion */ - /* render pool */ - FT_ULong raster_pool_size; /* size of render pool in bytes */ - FT_DebugHook_Func debug_hooks[4]; #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING FT_LcdFilter lcd_filter; - FT_Int lcd_extra; /* number of extra pixels */ FT_LcdFiveTapFilter lcd_weights; /* filter weights, if any */ FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */ #endif diff --git a/thirdparty/freetype/include/freetype/tttags.h b/thirdparty/freetype/include/freetype/tttags.h index 32eb2fdc26..b7d3bac0f1 100644 --- a/thirdparty/freetype/include/freetype/tttags.h +++ b/thirdparty/freetype/include/freetype/tttags.h @@ -106,6 +106,12 @@ FT_BEGIN_HEADER #define TTAG_VVAR FT_MAKE_TAG( 'V', 'V', 'A', 'R' ) #define TTAG_wOFF FT_MAKE_TAG( 'w', 'O', 'F', 'F' ) +/* used by "Keyboard.dfont" on legacy Mac OS X */ +#define TTAG_0xA5kbd FT_MAKE_TAG( 0xA5, 'k', 'b', 'd' ) + +/* used by "LastResort.dfont" on legacy Mac OS X */ +#define TTAG_0xA5lst FT_MAKE_TAG( 0xA5, 'l', 's', 't' ) + FT_END_HEADER diff --git a/thirdparty/freetype/src/autofit/afblue.c b/thirdparty/freetype/src/autofit/afblue.c index a00c3a0765..fedeacf797 100644 --- a/thirdparty/freetype/src/autofit/afblue.c +++ b/thirdparty/freetype/src/autofit/afblue.c @@ -592,9 +592,6 @@ { AF_BLUE_STRING_KAYAH_LI_DESCENDER, 0 }, { AF_BLUE_STRING_KAYAH_LI_LARGE_DESCENDER, 0 }, { AF_BLUE_STRING_MAX, 0 }, - { AF_BLUE_STRING_KANNADA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, - { AF_BLUE_STRING_KANNADA_BOTTOM, 0 }, - { AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_KHMER_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, { AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP, AF_BLUE_PROPERTY_LATIN_SUB_TOP }, @@ -606,6 +603,9 @@ AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, { AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM, 0 }, { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_KANNADA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_KANNADA_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, { AF_BLUE_STRING_LAO_BOTTOM, 0 }, @@ -701,6 +701,9 @@ { AF_BLUE_STRING_TELUGU_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, { AF_BLUE_STRING_TELUGU_BOTTOM, 0 }, { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_TIFINAGH, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_TIFINAGH, 0 }, + { AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_THAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, { AF_BLUE_STRING_THAI_BOTTOM, 0 }, @@ -710,9 +713,6 @@ { AF_BLUE_STRING_THAI_LARGE_DESCENDER, 0 }, { AF_BLUE_STRING_THAI_DIGIT_TOP, 0 }, { AF_BLUE_STRING_MAX, 0 }, - { AF_BLUE_STRING_TIFINAGH, AF_BLUE_PROPERTY_LATIN_TOP }, - { AF_BLUE_STRING_TIFINAGH, 0 }, - { AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_VAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, { AF_BLUE_STRING_VAI_BOTTOM, 0 }, { AF_BLUE_STRING_MAX, 0 }, diff --git a/thirdparty/freetype/src/autofit/afblue.dat b/thirdparty/freetype/src/autofit/afblue.dat index 454923e9ca..f62eb82a1a 100644 --- a/thirdparty/freetype/src/autofit/afblue.dat +++ b/thirdparty/freetype/src/autofit/afblue.dat @@ -872,11 +872,6 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: { AF_BLUE_STRING_KAYAH_LI_LARGE_DESCENDER, 0 } { AF_BLUE_STRING_MAX, 0 } - AF_BLUE_STRINGSET_KNDA - { AF_BLUE_STRING_KANNADA_TOP, AF_BLUE_PROPERTY_LATIN_TOP } - { AF_BLUE_STRING_KANNADA_BOTTOM, 0 } - { AF_BLUE_STRING_MAX, 0 } - AF_BLUE_STRINGSET_KHMR { AF_BLUE_STRING_KHMER_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_X_HEIGHT } @@ -892,6 +887,11 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: { AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM, 0 } { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_KNDA + { AF_BLUE_STRING_KANNADA_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_KANNADA_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_LAO { AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_X_HEIGHT } @@ -1027,6 +1027,11 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: { AF_BLUE_STRING_TELUGU_BOTTOM, 0 } { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_TFNG + { AF_BLUE_STRING_TIFINAGH, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_TIFINAGH, 0 } + { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_THAI { AF_BLUE_STRING_THAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_X_HEIGHT } @@ -1038,11 +1043,6 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: { AF_BLUE_STRING_THAI_DIGIT_TOP, 0 } { AF_BLUE_STRING_MAX, 0 } - AF_BLUE_STRINGSET_TFNG - { AF_BLUE_STRING_TIFINAGH, AF_BLUE_PROPERTY_LATIN_TOP } - { AF_BLUE_STRING_TIFINAGH, 0 } - { AF_BLUE_STRING_MAX, 0 } - AF_BLUE_STRINGSET_VAII { AF_BLUE_STRING_VAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } { AF_BLUE_STRING_VAI_BOTTOM, 0 } diff --git a/thirdparty/freetype/src/autofit/afblue.h b/thirdparty/freetype/src/autofit/afblue.h index e227dbf50b..99ef51cd4a 100644 --- a/thirdparty/freetype/src/autofit/afblue.h +++ b/thirdparty/freetype/src/autofit/afblue.h @@ -344,9 +344,9 @@ FT_BEGIN_HEADER AF_BLUE_STRINGSET_GURU = 116, AF_BLUE_STRINGSET_HEBR = 122, AF_BLUE_STRINGSET_KALI = 126, - AF_BLUE_STRINGSET_KNDA = 132, - AF_BLUE_STRINGSET_KHMR = 135, - AF_BLUE_STRINGSET_KHMS = 141, + AF_BLUE_STRINGSET_KHMR = 132, + AF_BLUE_STRINGSET_KHMS = 138, + AF_BLUE_STRINGSET_KNDA = 141, AF_BLUE_STRINGSET_LAO = 144, AF_BLUE_STRINGSET_LATN = 150, AF_BLUE_STRINGSET_LATB = 157, @@ -367,8 +367,8 @@ FT_BEGIN_HEADER AF_BLUE_STRINGSET_TAML = 222, AF_BLUE_STRINGSET_TAVT = 225, AF_BLUE_STRINGSET_TELU = 228, - AF_BLUE_STRINGSET_THAI = 231, - AF_BLUE_STRINGSET_TFNG = 239, + AF_BLUE_STRINGSET_TFNG = 231, + AF_BLUE_STRINGSET_THAI = 234, AF_BLUE_STRINGSET_VAII = 242, af_blue_2_1 = 245, #ifdef AF_CONFIG_OPTION_CJK diff --git a/thirdparty/freetype/src/autofit/afcjk.c b/thirdparty/freetype/src/autofit/afcjk.c index 61e29cdeda..897533d148 100644 --- a/thirdparty/freetype/src/autofit/afcjk.c +++ b/thirdparty/freetype/src/autofit/afcjk.c @@ -2272,13 +2272,7 @@ goto Exit; /* analyze glyph outline */ -#ifdef AF_CONFIG_OPTION_USE_WARPER - if ( ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && - AF_HINTS_DO_WARP( hints ) ) || - AF_HINTS_DO_HORIZONTAL( hints ) ) -#else if ( AF_HINTS_DO_HORIZONTAL( hints ) ) -#endif { error = af_cjk_hints_detect_features( hints, AF_DIMENSION_HORZ ); if ( error ) @@ -2304,9 +2298,9 @@ { #ifdef AF_CONFIG_OPTION_USE_WARPER - if ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && - AF_HINTS_DO_WARP( hints ) ) + if ( dim == AF_DIMENSION_HORZ && + metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL && + AF_HINTS_DO_WARP( hints ) ) { AF_WarperRec warper; FT_Fixed scale; diff --git a/thirdparty/freetype/src/autofit/afhints.c b/thirdparty/freetype/src/autofit/afhints.c index f1ff0baef8..1b21c06c2c 100644 --- a/thirdparty/freetype/src/autofit/afhints.c +++ b/thirdparty/freetype/src/autofit/afhints.c @@ -507,15 +507,15 @@ return FT_THROW( Invalid_Argument ); seg = &axis->segments[idx]; - *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->ox - : seg->first->oy; + *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->fx + : seg->first->fy; if ( seg->edge ) *is_blue = (FT_Bool)( seg->edge->blue_edge != 0 ); else *is_blue = FALSE; if ( *is_blue ) - *blue_offset = seg->edge->blue_edge->cur; + *blue_offset = seg->edge->blue_edge->org; else *blue_offset = 0; diff --git a/thirdparty/freetype/src/autofit/aflatin.c b/thirdparty/freetype/src/autofit/aflatin.c index 11fa523c83..02b3b8bbd3 100644 --- a/thirdparty/freetype/src/autofit/aflatin.c +++ b/thirdparty/freetype/src/autofit/aflatin.c @@ -1690,9 +1690,11 @@ if ( prev_max_on_coord > max_on_coord ) max_on_coord = prev_max_on_coord; - prev_segment->last = point; - prev_segment->pos = (FT_Short)( ( min_pos + - max_pos ) >> 1 ); + prev_segment->last = point; + prev_segment->pos = (FT_Short)( ( min_pos + + max_pos ) >> 1 ); + prev_segment->delta = (FT_Short)( ( max_pos - + min_pos ) >> 1 ); if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL && ( max_on_coord - min_on_coord ) < flat_threshold ) @@ -1720,9 +1722,11 @@ if ( max_pos > prev_max_pos ) prev_max_pos = max_pos; - prev_segment->last = point; - prev_segment->pos = (FT_Short)( ( prev_min_pos + - prev_max_pos ) >> 1 ); + prev_segment->last = point; + prev_segment->pos = (FT_Short)( ( prev_min_pos + + prev_max_pos ) >> 1 ); + prev_segment->delta = (FT_Short)( ( prev_max_pos - + prev_min_pos ) >> 1 ); } else { @@ -1733,8 +1737,9 @@ if ( prev_max_pos > max_pos ) max_pos = prev_max_pos; - segment->last = point; - segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 ); + segment->last = point; + segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 ); + segment->delta = (FT_Short)( ( max_pos - min_pos ) >> 1 ); if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL && ( max_on_coord - min_on_coord ) < flat_threshold ) @@ -3492,13 +3497,7 @@ goto Exit; /* analyze glyph outline */ -#ifdef AF_CONFIG_OPTION_USE_WARPER - if ( ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && - AF_HINTS_DO_WARP( hints ) ) || - AF_HINTS_DO_HORIZONTAL( hints ) ) -#else if ( AF_HINTS_DO_HORIZONTAL( hints ) ) -#endif { axis = &metrics->axis[AF_DIMENSION_HORZ]; error = af_latin_hints_detect_features( hints, @@ -3528,9 +3527,9 @@ for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { #ifdef AF_CONFIG_OPTION_USE_WARPER - if ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && - AF_HINTS_DO_WARP( hints ) ) + if ( dim == AF_DIMENSION_HORZ && + metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL && + AF_HINTS_DO_WARP( hints ) ) { AF_WarperRec warper; FT_Fixed scale; diff --git a/thirdparty/freetype/src/autofit/aflatin2.c b/thirdparty/freetype/src/autofit/aflatin2.c index 0607278b1e..fb42445116 100644 --- a/thirdparty/freetype/src/autofit/aflatin2.c +++ b/thirdparty/freetype/src/autofit/aflatin2.c @@ -2340,13 +2340,7 @@ goto Exit; /* analyze glyph outline */ -#ifdef AF_CONFIG_OPTION_USE_WARPER - if ( ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && - AF_HINTS_DO_WARP( hints ) ) || - AF_HINTS_DO_HORIZONTAL( hints ) ) -#else if ( AF_HINTS_DO_HORIZONTAL( hints ) ) -#endif { error = af_latin2_hints_detect_features( hints, AF_DIMENSION_HORZ ); if ( error ) @@ -2366,9 +2360,9 @@ for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { #ifdef AF_CONFIG_OPTION_USE_WARPER - if ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && - AF_HINTS_DO_WARP( hints ) ) + if ( dim == AF_DIMENSION_HORZ && + metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL && + AF_HINTS_DO_WARP( hints ) ) { AF_WarperRec warper; FT_Fixed scale; diff --git a/thirdparty/freetype/src/autofit/afloader.c b/thirdparty/freetype/src/autofit/afloader.c index 78c4368b61..067ebd17f6 100644 --- a/thirdparty/freetype/src/autofit/afloader.c +++ b/thirdparty/freetype/src/autofit/afloader.c @@ -483,8 +483,8 @@ FT_Pos pp2x = loader->pp2.x; - loader->pp1.x = FT_PIX_ROUND( pp1x ); - loader->pp2.x = FT_PIX_ROUND( pp2x ); + loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta ); + loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta ); slot->lsb_delta = loader->pp1.x - pp1x; slot->rsb_delta = loader->pp2.x - pp2x; @@ -498,8 +498,8 @@ FT_Pos pp2x = loader->pp2.x; - loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta ); - loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta ); + loader->pp1.x = FT_PIX_ROUND( pp1x ); + loader->pp2.x = FT_PIX_ROUND( pp2x ); slot->lsb_delta = loader->pp1.x - pp1x; slot->rsb_delta = loader->pp2.x - pp2x; diff --git a/thirdparty/freetype/src/autofit/afscript.h b/thirdparty/freetype/src/autofit/afscript.h index 7547a9e6f9..cb815dbb40 100644 --- a/thirdparty/freetype/src/autofit/afscript.h +++ b/thirdparty/freetype/src/autofit/afscript.h @@ -187,12 +187,6 @@ HINTING_BOTTOM_TO_TOP, "\xEA\xA4\x8D \xEA\xA4\x80" ) /* ꤍ ꤀ */ - SCRIPT( knda, KNDA, - "Kannada", - HB_SCRIPT_KANNADA, - HINTING_BOTTOM_TO_TOP, - "\xE0\xB3\xA6 \xE0\xB2\xAC" ) /* ೦ ಬ */ - /* only digit zero has a simple shape in the Khmer script */ SCRIPT( khmr, KHMR, "Khmer", @@ -206,6 +200,12 @@ HINTING_BOTTOM_TO_TOP, "\xE1\xA7\xA1 \xE1\xA7\xAA" ) /* ᧡ ᧪ */ + SCRIPT( knda, KNDA, + "Kannada", + HB_SCRIPT_KANNADA, + HINTING_BOTTOM_TO_TOP, + "\xE0\xB3\xA6 \xE0\xB2\xAC" ) /* ೦ ಬ */ + /* only digit zero has a simple shape in the Lao script */ SCRIPT( lao, LAO, "Lao", @@ -330,18 +330,18 @@ HINTING_BOTTOM_TO_TOP, "\xE0\xB1\xA6 \xE0\xB1\xA7" ) /* ౦ ౧ */ - SCRIPT( thai, THAI, - "Thai", - HB_SCRIPT_THAI, - HINTING_BOTTOM_TO_TOP, - "\xE0\xB8\xB2 \xE0\xB9\x85 \xE0\xB9\x90" ) /* า ๅ ๐ */ - SCRIPT( tfng, TFNG, "Tifinagh", HB_SCRIPT_TIFINAGH, HINTING_BOTTOM_TO_TOP, "\xE2\xB5\x94" ) /* ⵔ */ + SCRIPT( thai, THAI, + "Thai", + HB_SCRIPT_THAI, + HINTING_BOTTOM_TO_TOP, + "\xE0\xB8\xB2 \xE0\xB9\x85 \xE0\xB9\x90" ) /* า ๅ ๐ */ + SCRIPT( vaii, VAII, "Vai", HB_SCRIPT_VAI, diff --git a/thirdparty/freetype/src/autofit/afshaper.c b/thirdparty/freetype/src/autofit/afshaper.c index da92fad3ed..d259964217 100644 --- a/thirdparty/freetype/src/autofit/afshaper.c +++ b/thirdparty/freetype/src/autofit/afshaper.c @@ -18,6 +18,7 @@ #include #include FT_FREETYPE_H +#include FT_ADVANCES_H #include "afglobal.h" #include "aftypes.h" #include "afshaper.h" diff --git a/thirdparty/freetype/src/autofit/afstyles.h b/thirdparty/freetype/src/autofit/afstyles.h index a5e13d8944..281559eea2 100644 --- a/thirdparty/freetype/src/autofit/afstyles.h +++ b/thirdparty/freetype/src/autofit/afstyles.h @@ -255,13 +255,6 @@ AF_BLUE_STRINGSET_KALI, AF_COVERAGE_DEFAULT ) - STYLE( knda_dflt, KNDA_DFLT, - "Kannada default style", - AF_WRITING_SYSTEM_LATIN, - AF_SCRIPT_KNDA, - AF_BLUE_STRINGSET_KNDA, - AF_COVERAGE_DEFAULT ) - STYLE( khmr_dflt, KHMR_DFLT, "Khmer default style", AF_WRITING_SYSTEM_LATIN, @@ -276,6 +269,13 @@ AF_BLUE_STRINGSET_KHMS, AF_COVERAGE_DEFAULT ) + STYLE( knda_dflt, KNDA_DFLT, + "Kannada default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_KNDA, + AF_BLUE_STRINGSET_KNDA, + AF_COVERAGE_DEFAULT ) + STYLE( lao_dflt, LAO_DFLT, "Lao default style", AF_WRITING_SYSTEM_LATIN, @@ -420,13 +420,6 @@ AF_BLUE_STRINGSET_TELU, AF_COVERAGE_DEFAULT ) - STYLE( thai_dflt, THAI_DFLT, - "Thai default style", - AF_WRITING_SYSTEM_LATIN, - AF_SCRIPT_THAI, - AF_BLUE_STRINGSET_THAI, - AF_COVERAGE_DEFAULT ) - STYLE( tfng_dflt, TFNG_DFLT, "Tifinagh default style", AF_WRITING_SYSTEM_LATIN, @@ -434,6 +427,13 @@ AF_BLUE_STRINGSET_TFNG, AF_COVERAGE_DEFAULT ) + STYLE( thai_dflt, THAI_DFLT, + "Thai default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_THAI, + AF_BLUE_STRINGSET_THAI, + AF_COVERAGE_DEFAULT ) + STYLE( vaii_dflt, VAII_DFLT, "Vai default style", AF_WRITING_SYSTEM_LATIN, diff --git a/thirdparty/freetype/src/base/ftbitmap.c b/thirdparty/freetype/src/base/ftbitmap.c index 88c88c4c1b..e567a0453e 100644 --- a/thirdparty/freetype/src/base/ftbitmap.c +++ b/thirdparty/freetype/src/base/ftbitmap.c @@ -226,7 +226,7 @@ } /* otherwise allocate new buffer */ - if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) ) + if ( FT_QALLOC_MULT( buffer, bitmap->rows + ypixels, new_pitch ) ) return error; /* new rows get added at the top of the bitmap, */ @@ -534,8 +534,7 @@ (FT_ULong)target->rows > FT_ULONG_MAX / (FT_ULong)target_pitch ) return FT_THROW( Invalid_Argument ); - if ( target->rows * (FT_ULong)target_pitch > old_size && - FT_QREALLOC( target->buffer, + if ( FT_QREALLOC( target->buffer, old_size, target->rows * (FT_UInt)target_pitch ) ) return error; diff --git a/thirdparty/freetype/src/base/ftcalc.c b/thirdparty/freetype/src/base/ftcalc.c index f0525502f3..00d63c6e6b 100644 --- a/thirdparty/freetype/src/base/ftcalc.c +++ b/thirdparty/freetype/src/base/ftcalc.c @@ -68,14 +68,15 @@ #define FT_COMPONENT trace_calc - /* transfer sign leaving a positive number */ -#define FT_MOVE_SIGN( x, s ) \ - FT_BEGIN_STMNT \ - if ( x < 0 ) \ - { \ - x = -x; \ - s = -s; \ - } \ + /* transfer sign, leaving a positive number; */ + /* we need an unsigned value to safely negate INT_MIN (or LONG_MIN) */ +#define FT_MOVE_SIGN( x, x_unsigned, s ) \ + FT_BEGIN_STMNT \ + if ( x < 0 ) \ + { \ + x_unsigned = 0U - (x_unsigned); \ + s = -s; \ + } \ FT_END_STMNT /* The following three functions are available regardless of whether */ @@ -86,7 +87,7 @@ FT_EXPORT_DEF( FT_Fixed ) FT_RoundFix( FT_Fixed a ) { - return ( a + 0x8000L - ( a < 0 ) ) & ~0xFFFFL; + return ( ADD_LONG( a, 0x8000L - ( a < 0 ) ) ) & ~0xFFFFL; } @@ -95,7 +96,7 @@ FT_EXPORT_DEF( FT_Fixed ) FT_CeilFix( FT_Fixed a ) { - return ( a + 0xFFFFL ) & ~0xFFFFL; + return ( ADD_LONG( a, 0xFFFFL ) ) & ~0xFFFFL; } @@ -179,20 +180,20 @@ FT_Long d_; - FT_MOVE_SIGN( a_, s ); - FT_MOVE_SIGN( b_, s ); - FT_MOVE_SIGN( c_, s ); - a = (FT_UInt64)a_; b = (FT_UInt64)b_; c = (FT_UInt64)c_; + FT_MOVE_SIGN( a_, a, s ); + FT_MOVE_SIGN( b_, b, s ); + FT_MOVE_SIGN( c_, c, s ); + d = c > 0 ? ( a * b + ( c >> 1 ) ) / c : 0x7FFFFFFFUL; d_ = (FT_Long)d; - return s < 0 ? -d_ : d_; + return s < 0 ? NEG_LONG( d_ ) : d_; } @@ -208,20 +209,20 @@ FT_Long d_; - FT_MOVE_SIGN( a_, s ); - FT_MOVE_SIGN( b_, s ); - FT_MOVE_SIGN( c_, s ); - a = (FT_UInt64)a_; b = (FT_UInt64)b_; c = (FT_UInt64)c_; + FT_MOVE_SIGN( a_, a, s ); + FT_MOVE_SIGN( b_, b, s ); + FT_MOVE_SIGN( c_, c, s ); + d = c > 0 ? a * b / c : 0x7FFFFFFFUL; d_ = (FT_Long)d; - return s < 0 ? -d_ : d_; + return s < 0 ? NEG_LONG( d_ ) : d_; } @@ -257,18 +258,18 @@ FT_Long q_; - FT_MOVE_SIGN( a_, s ); - FT_MOVE_SIGN( b_, s ); - a = (FT_UInt64)a_; b = (FT_UInt64)b_; + FT_MOVE_SIGN( a_, a, s ); + FT_MOVE_SIGN( b_, b, s ); + q = b > 0 ? ( ( a << 16 ) + ( b >> 1 ) ) / b : 0x7FFFFFFFUL; q_ = (FT_Long)q; - return s < 0 ? -q_ : q_; + return s < 0 ? NEG_LONG( q_ ) : q_; } @@ -422,14 +423,14 @@ /* XXX: this function does not allow 64-bit arguments */ - FT_MOVE_SIGN( a_, s ); - FT_MOVE_SIGN( b_, s ); - FT_MOVE_SIGN( c_, s ); - a = (FT_UInt32)a_; b = (FT_UInt32)b_; c = (FT_UInt32)c_; + FT_MOVE_SIGN( a_, a, s ); + FT_MOVE_SIGN( b_, b, s ); + FT_MOVE_SIGN( c_, c, s ); + if ( c == 0 ) a = 0x7FFFFFFFUL; @@ -455,7 +456,7 @@ a_ = (FT_Long)a; - return s < 0 ? -a_ : a_; + return s < 0 ? NEG_LONG( a_ ) : a_; } @@ -470,14 +471,14 @@ /* XXX: this function does not allow 64-bit arguments */ - FT_MOVE_SIGN( a_, s ); - FT_MOVE_SIGN( b_, s ); - FT_MOVE_SIGN( c_, s ); - a = (FT_UInt32)a_; b = (FT_UInt32)b_; c = (FT_UInt32)c_; + FT_MOVE_SIGN( a_, a, s ); + FT_MOVE_SIGN( b_, b, s ); + FT_MOVE_SIGN( c_, c, s ); + if ( c == 0 ) a = 0x7FFFFFFFUL; @@ -498,7 +499,7 @@ a_ = (FT_Long)a; - return s < 0 ? -a_ : a_; + return s < 0 ? NEG_LONG( a_ ) : a_; } @@ -575,12 +576,12 @@ /* XXX: this function does not allow 64-bit arguments */ - FT_MOVE_SIGN( a_, s ); - FT_MOVE_SIGN( b_, s ); - a = (FT_UInt32)a_; b = (FT_UInt32)b_; + FT_MOVE_SIGN( a_, a, s ); + FT_MOVE_SIGN( b_, b, s ); + if ( a + ( b >> 8 ) <= 8190UL ) a = ( a * b + 0x8000UL ) >> 16; else @@ -594,7 +595,7 @@ a_ = (FT_Long)a; - return s < 0 ? -a_ : a_; + return s < 0 ? NEG_LONG( a_ ) : a_; #endif /* 0 */ @@ -614,12 +615,12 @@ /* XXX: this function does not allow 64-bit arguments */ - FT_MOVE_SIGN( a_, s ); - FT_MOVE_SIGN( b_, s ); - a = (FT_UInt32)a_; b = (FT_UInt32)b_; + FT_MOVE_SIGN( a_, a, s ); + FT_MOVE_SIGN( b_, b, s ); + if ( b == 0 ) { /* check for division by 0 */ @@ -647,7 +648,7 @@ q_ = (FT_Long)q; - return s < 0 ? -q_ : q_; + return s < 0 ? NEG_LONG( q_ ) : q_; } @@ -666,13 +667,19 @@ if ( !a || !b ) return; - xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); - xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); - yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); - yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); - - b->xx = xx; b->xy = xy; - b->yx = yx; b->yy = yy; + xx = ADD_LONG( FT_MulFix( a->xx, b->xx ), + FT_MulFix( a->xy, b->yx ) ); + xy = ADD_LONG( FT_MulFix( a->xx, b->xy ), + FT_MulFix( a->xy, b->yy ) ); + yx = ADD_LONG( FT_MulFix( a->yx, b->xx ), + FT_MulFix( a->yy, b->yx ) ); + yy = ADD_LONG( FT_MulFix( a->yx, b->xy ), + FT_MulFix( a->yy, b->yy ) ); + + b->xx = xx; + b->xy = xy; + b->yx = yx; + b->yy = yy; } @@ -722,13 +729,19 @@ if ( !a || !b ) return; - xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val ); - xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val ); - yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val ); - yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val ); - - b->xx = xx; b->xy = xy; - b->yx = yx; b->yy = yy; + xx = ADD_LONG( FT_MulDiv( a->xx, b->xx, val ), + FT_MulDiv( a->xy, b->yx, val ) ); + xy = ADD_LONG( FT_MulDiv( a->xx, b->xy, val ), + FT_MulDiv( a->xy, b->yy, val ) ); + yx = ADD_LONG( FT_MulDiv( a->yx, b->xx, val ), + FT_MulDiv( a->yy, b->yx, val ) ); + yy = ADD_LONG( FT_MulDiv( a->yx, b->xy, val ), + FT_MulDiv( a->yy, b->yy, val ) ); + + b->xx = xx; + b->xy = xy; + b->yx = yx; + b->yy = yy; } @@ -747,11 +760,10 @@ if ( !vector || !matrix ) return; - xz = FT_MulDiv( vector->x, matrix->xx, val ) + - FT_MulDiv( vector->y, matrix->xy, val ); - - yz = FT_MulDiv( vector->x, matrix->yx, val ) + - FT_MulDiv( vector->y, matrix->yy, val ); + xz = ADD_LONG( FT_MulDiv( vector->x, matrix->xx, val ), + FT_MulDiv( vector->y, matrix->xy, val ) ); + yz = ADD_LONG( FT_MulDiv( vector->x, matrix->yx, val ), + FT_MulDiv( vector->y, matrix->yy, val ) ); vector->x = xz; vector->y = yz; @@ -770,12 +782,12 @@ FT_Int sx = 1, sy = 1, shift; - FT_MOVE_SIGN( x_, sx ); - FT_MOVE_SIGN( y_, sy ); - x = (FT_UInt32)x_; y = (FT_UInt32)y_; + FT_MOVE_SIGN( x_, x, sx ); + FT_MOVE_SIGN( y_, y, sy ); + /* trivial cases */ if ( x == 0 ) { @@ -913,11 +925,13 @@ FT_Int result; - if ( (FT_ULong)FT_ABS( in_x ) + (FT_ULong)FT_ABS( out_y ) <= 131071UL && - (FT_ULong)FT_ABS( in_y ) + (FT_ULong)FT_ABS( out_x ) <= 131071UL ) + /* we silently ignore overflow errors, since such large values */ + /* lead to even more (harmless) rendering errors later on */ + if ( ADD_LONG( FT_ABS( in_x ), FT_ABS( out_y ) ) <= 131071L && + ADD_LONG( FT_ABS( in_y ), FT_ABS( out_x ) ) <= 131071L ) { - FT_Long z1 = in_x * out_y; - FT_Long z2 = in_y * out_x; + FT_Long z1 = MUL_LONG( in_x, out_y ); + FT_Long z2 = MUL_LONG( in_y, out_x ); if ( z1 > z2 ) diff --git a/thirdparty/freetype/src/base/ftglyph.c b/thirdparty/freetype/src/base/ftglyph.c index 9bfb330508..3f78a8c36b 100644 --- a/thirdparty/freetype/src/base/ftglyph.c +++ b/thirdparty/freetype/src/base/ftglyph.c @@ -408,12 +408,28 @@ goto Exit; /* copy advance while converting 26.6 to 16.16 format */ + if ( slot->advance.x >= 0x8000L * 64 || + slot->advance.x <= -0x8000L * 64 ) + { + FT_ERROR(( "FT_Get_Glyph: advance width too large\n" )); + error = FT_THROW( Invalid_Argument ); + goto Exit2; + } + if ( slot->advance.y >= 0x8000L * 64 || + slot->advance.y <= -0x8000L * 64 ) + { + FT_ERROR(( "FT_Get_Glyph: advance height too large\n" )); + error = FT_THROW( Invalid_Argument ); + goto Exit2; + } + 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 ); + Exit2: /* if an error occurred, destroy the glyph */ if ( error ) FT_Done_Glyph( glyph ); diff --git a/thirdparty/freetype/src/base/ftlcdfil.c b/thirdparty/freetype/src/base/ftlcdfil.c index 611b39f570..60c813fd9e 100644 --- a/thirdparty/freetype/src/base/ftlcdfil.c +++ b/thirdparty/freetype/src/base/ftlcdfil.c @@ -29,141 +29,107 @@ /* define USE_LEGACY to implement the legacy filter */ #define USE_LEGACY +#define FT_SHIFTCLAMP( x ) ( x >>= 8, (FT_Byte)( x > 255 ? 255 : x ) ) + /* FIR filter used by the default and light filters */ FT_BASE( void ) ft_lcd_filter_fir( FT_Bitmap* bitmap, FT_Render_Mode mode, FT_LcdFiveTapFilter weights ) { - FT_UInt width = (FT_UInt)bitmap->width; - FT_UInt height = (FT_UInt)bitmap->rows; + FT_UInt width = (FT_UInt)bitmap->width; + FT_UInt height = (FT_UInt)bitmap->rows; + FT_Int pitch = bitmap->pitch; + FT_Byte* origin = bitmap->buffer; + + /* take care of bitmap flow */ + if ( pitch > 0 ) + origin += pitch * (FT_Int)( height - 1 ); /* horizontal in-place FIR filter */ - if ( mode == FT_RENDER_MODE_LCD && width >= 4 ) + if ( mode == FT_RENDER_MODE_LCD && width >= 2 ) { - FT_Byte* line = bitmap->buffer; - + FT_Byte* line = origin; - /* take care of bitmap flow */ - if ( bitmap->pitch < 0 ) - line -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); - /* `fir' and `pix' must be at least 32 bit wide, since the sum of */ - /* the values in `weights' can exceed 0xFF */ + /* `fir' must be at least 32 bit wide, since the sum of */ + /* the values in `weights' can exceed 0xFF */ - for ( ; height > 0; height--, line += bitmap->pitch ) + for ( ; height > 0; height--, line -= pitch ) { - FT_UInt fir[4]; /* below, `pix' is used as the 5th element */ - FT_UInt val1, xx; + FT_UInt fir[5]; + FT_UInt val, xx; - val1 = line[0]; - fir[0] = weights[2] * val1; - fir[1] = weights[3] * val1; - fir[2] = weights[4] * val1; - fir[3] = 0; + val = line[0]; + fir[2] = weights[2] * val; + fir[3] = weights[3] * val; + fir[4] = weights[4] * val; - val1 = line[1]; - fir[0] += weights[1] * val1; - fir[1] += weights[2] * val1; - fir[2] += weights[3] * val1; - fir[3] += weights[4] * val1; + val = line[1]; + fir[1] = fir[2] + weights[1] * val; + fir[2] = fir[3] + weights[2] * val; + fir[3] = fir[4] + weights[3] * val; + fir[4] = weights[4] * val; for ( xx = 2; xx < width; xx++ ) { - FT_UInt val, pix; - - val = line[xx]; - pix = fir[0] + weights[0] * val; - fir[0] = fir[1] + weights[1] * val; - fir[1] = fir[2] + weights[2] * val; - fir[2] = fir[3] + weights[3] * val; - fir[3] = weights[4] * val; - - pix >>= 8; - pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); - line[xx - 2] = (FT_Byte)pix; - } + fir[0] = fir[1] + weights[0] * val; + fir[1] = fir[2] + weights[1] * val; + fir[2] = fir[3] + weights[2] * val; + fir[3] = fir[4] + weights[3] * val; + fir[4] = weights[4] * val; - { - FT_UInt pix; - - - pix = fir[0] >> 8; - pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); - line[xx - 2] = (FT_Byte)pix; - - pix = fir[1] >> 8; - pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); - line[xx - 1] = (FT_Byte)pix; + line[xx - 2] = FT_SHIFTCLAMP( fir[0] ); } + + line[xx - 2] = FT_SHIFTCLAMP( fir[1] ); + line[xx - 1] = FT_SHIFTCLAMP( fir[2] ); } } /* vertical in-place FIR filter */ - else if ( mode == FT_RENDER_MODE_LCD_V && height >= 4 ) + else if ( mode == FT_RENDER_MODE_LCD_V && height >= 2 ) { - FT_Byte* column = bitmap->buffer; - FT_Int pitch = bitmap->pitch; - + FT_Byte* column = origin; - /* take care of bitmap flow */ - if ( bitmap->pitch < 0 ) - column -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); for ( ; width > 0; width--, column++ ) { FT_Byte* col = column; - FT_UInt fir[4]; /* below, `pix' is used as the 5th element */ - FT_UInt val1, yy; + FT_UInt fir[5]; + FT_UInt val, yy; - val1 = col[0]; - fir[0] = weights[2] * val1; - fir[1] = weights[3] * val1; - fir[2] = weights[4] * val1; - fir[3] = 0; - col += pitch; + val = col[0]; + fir[2] = weights[2] * val; + fir[3] = weights[3] * val; + fir[4] = weights[4] * val; + col -= pitch; - val1 = col[0]; - fir[0] += weights[1] * val1; - fir[1] += weights[2] * val1; - fir[2] += weights[3] * val1; - fir[3] += weights[4] * val1; - col += pitch; + val = col[0]; + fir[1] = fir[2] + weights[1] * val; + fir[2] = fir[3] + weights[2] * val; + fir[3] = fir[4] + weights[3] * val; + fir[4] = weights[4] * val; + col -= pitch; - for ( yy = 2; yy < height; yy++ ) + for ( yy = 2; yy < height; yy++, col -= pitch ) { - FT_UInt val, pix; - - val = col[0]; - pix = fir[0] + weights[0] * val; - fir[0] = fir[1] + weights[1] * val; - fir[1] = fir[2] + weights[2] * val; - fir[2] = fir[3] + weights[3] * val; - fir[3] = weights[4] * val; - - pix >>= 8; - pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); - col[-2 * pitch] = (FT_Byte)pix; - col += pitch; - } - - { - FT_UInt pix; - + fir[0] = fir[1] + weights[0] * val; + fir[1] = fir[2] + weights[1] * val; + fir[2] = fir[3] + weights[2] * val; + fir[3] = fir[4] + weights[3] * val; + fir[4] = weights[4] * val; - pix = fir[0] >> 8; - pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); - col[-2 * pitch] = (FT_Byte)pix; - - pix = fir[1] >> 8; - pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); - col[-pitch] = (FT_Byte)pix; + col[pitch * 2] = FT_SHIFTCLAMP( fir[0] ); } + + col[pitch * 2] = FT_SHIFTCLAMP( fir[1] ); + col[pitch] = FT_SHIFTCLAMP( fir[2] ); } } } @@ -177,9 +143,10 @@ FT_Render_Mode mode, FT_Byte* weights ) { - FT_UInt width = (FT_UInt)bitmap->width; - FT_UInt height = (FT_UInt)bitmap->rows; - FT_Int pitch = bitmap->pitch; + FT_UInt width = (FT_UInt)bitmap->width; + FT_UInt height = (FT_UInt)bitmap->rows; + FT_Int pitch = bitmap->pitch; + FT_Byte* origin = bitmap->buffer; static const unsigned int filters[3][3] = { @@ -191,33 +158,31 @@ FT_UNUSED( weights ); + /* take care of bitmap flow */ + if ( pitch > 0 ) + origin += pitch * (FT_Int)( height - 1 ); + /* horizontal in-place intra-pixel filter */ if ( mode == FT_RENDER_MODE_LCD && width >= 3 ) { - FT_Byte* line = bitmap->buffer; + FT_Byte* line = origin; - /* take care of bitmap flow */ - if ( bitmap->pitch < 0 ) - line -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); - - for ( ; height > 0; height--, line += pitch ) + for ( ; height > 0; height--, line -= pitch ) { FT_UInt xx; for ( xx = 0; xx < width; xx += 3 ) { - FT_UInt r = 0; - FT_UInt g = 0; - FT_UInt b = 0; + FT_UInt r, g, b; FT_UInt p; p = line[xx]; - r += filters[0][0] * p; - g += filters[0][1] * p; - b += filters[0][2] * p; + r = filters[0][0] * p; + g = filters[0][1] * p; + b = filters[0][2] * p; p = line[xx + 1]; r += filters[1][0] * p; @@ -237,31 +202,24 @@ } else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 ) { - FT_Byte* column = bitmap->buffer; - + FT_Byte* column = origin; - /* take care of bitmap flow */ - if ( bitmap->pitch < 0 ) - column -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); for ( ; width > 0; width--, column++ ) { - FT_Byte* col = column; - FT_Byte* col_end = col + (FT_Int)height * pitch; + FT_Byte* col = column - 2 * pitch; - for ( ; col < col_end; col += 3 * pitch ) + for ( ; height > 0; height -= 3, col -= 3 * pitch ) { - FT_UInt r = 0; - FT_UInt g = 0; - FT_UInt b = 0; + FT_UInt r, g, b; FT_UInt p; p = col[0]; - r += filters[0][0] * p; - g += filters[0][1] * p; - b += filters[0][2] * p; + r = filters[0][0] * p; + g = filters[0][1] * p; + b = filters[0][2] * p; p = col[pitch]; r += filters[1][0] * p; @@ -275,7 +233,7 @@ col[0] = (FT_Byte)( r / 65536 ); col[pitch] = (FT_Byte)( g / 65536 ); - col[2 * pitch] = (FT_Byte)( b / 65536 ); + col[pitch * 2] = (FT_Byte)( b / 65536 ); } } } @@ -296,7 +254,6 @@ ft_memcpy( library->lcd_weights, weights, FT_LCD_FILTER_FIVE_TAPS ); library->lcd_filter_func = ft_lcd_filter_fir; - library->lcd_extra = 2; return FT_Err_Ok; } @@ -319,7 +276,6 @@ { case FT_LCD_FILTER_NONE: library->lcd_filter_func = NULL; - library->lcd_extra = 0; break; case FT_LCD_FILTER_DEFAULT: @@ -327,7 +283,6 @@ default_weights, FT_LCD_FILTER_FIVE_TAPS ); library->lcd_filter_func = ft_lcd_filter_fir; - library->lcd_extra = 2; break; case FT_LCD_FILTER_LIGHT: @@ -335,7 +290,6 @@ light_weights, FT_LCD_FILTER_FIVE_TAPS ); library->lcd_filter_func = ft_lcd_filter_fir; - library->lcd_extra = 2; break; #ifdef USE_LEGACY @@ -343,7 +297,6 @@ case FT_LCD_FILTER_LEGACY: case FT_LCD_FILTER_LEGACY1: library->lcd_filter_func = _ft_lcd_filter_legacy; - library->lcd_extra = 0; break; #endif diff --git a/thirdparty/freetype/src/base/ftmac.c b/thirdparty/freetype/src/base/ftmac.c index 4b92066da3..4e76585e5f 100644 --- a/thirdparty/freetype/src/base/ftmac.c +++ b/thirdparty/freetype/src/base/ftmac.c @@ -1005,7 +1005,7 @@ /* accepts an FSRef instead of a path. */ /* */ /* This function is deprecated because Carbon data types (FSRef) */ - /* are not cross-platform, and thus not suitable for the freetype API. */ + /* are not cross-platform, and thus not suitable for the FreeType API. */ FT_EXPORT_DEF( FT_Error ) FT_New_Face_From_FSRef( FT_Library library, const FSRef* ref, diff --git a/thirdparty/freetype/src/base/ftmm.c b/thirdparty/freetype/src/base/ftmm.c index 2cb56a39be..43877ece45 100644 --- a/thirdparty/freetype/src/base/ftmm.c +++ b/thirdparty/freetype/src/base/ftmm.c @@ -158,7 +158,7 @@ /* check of `face' delayed to `ft_face_get_mm_service' */ - if ( !coords ) + if ( num_coords && !coords ) return FT_THROW( Invalid_Argument ); error = ft_face_get_mm_service( face, &service ); @@ -194,7 +194,7 @@ /* check of `face' delayed to `ft_face_get_mm_service' */ - if ( !coords ) + if ( num_coords && !coords ) return FT_THROW( Invalid_Argument ); error = ft_face_get_mm_service( face, &service_mm ); @@ -266,7 +266,7 @@ /* check of `face' delayed to `ft_face_get_mm_service' */ - if ( !coords ) + if ( num_coords && !coords ) return FT_THROW( Invalid_Argument ); error = ft_face_get_mm_service( face, &service_mm ); @@ -313,7 +313,7 @@ /* check of `face' delayed to `ft_face_get_mm_service' */ - if ( !coords ) + if ( num_coords && !coords ) return FT_THROW( Invalid_Argument ); error = ft_face_get_mm_service( face, &service_mm ); @@ -402,4 +402,28 @@ } + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Var_Axis_Flags( FT_MM_Var* master, + FT_UInt axis_index, + FT_UInt* flags ) + { + FT_UShort* axis_flags; + + + if ( !master || !flags ) + return FT_THROW( Invalid_Argument ); + + if ( axis_index >= master->num_axis ) + return FT_THROW( Invalid_Argument ); + + /* the axis flags array immediately follows the data of `master' */ + axis_flags = (FT_UShort*)&( master[1] ); + *flags = axis_flags[axis_index]; + + return FT_Err_Ok; + } + + /* END */ diff --git a/thirdparty/freetype/src/base/ftobjs.c b/thirdparty/freetype/src/base/ftobjs.c index 539116e85c..6db8136cfc 100644 --- a/thirdparty/freetype/src/base/ftobjs.c +++ b/thirdparty/freetype/src/base/ftobjs.c @@ -579,34 +579,42 @@ if ( vertical ) { metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); - metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY ); + metrics->horiBearingY = FT_PIX_CEIL_LONG( metrics->horiBearingY ); - right = FT_PIX_CEIL( metrics->vertBearingX + metrics->width ); - bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height ); + right = FT_PIX_CEIL_LONG( ADD_LONG( metrics->vertBearingX, + metrics->width ) ); + bottom = FT_PIX_CEIL_LONG( ADD_LONG( metrics->vertBearingY, + metrics->height ) ); metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); - metrics->width = right - metrics->vertBearingX; - metrics->height = bottom - metrics->vertBearingY; + metrics->width = SUB_LONG( right, + metrics->vertBearingX ); + metrics->height = SUB_LONG( bottom, + metrics->vertBearingY ); } else { metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); - right = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width ); - bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height ); + right = FT_PIX_CEIL_LONG( ADD_LONG( metrics->horiBearingX, + metrics->width ) ); + bottom = FT_PIX_FLOOR( SUB_LONG( metrics->horiBearingY, + metrics->height ) ); metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); - metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY ); + metrics->horiBearingY = FT_PIX_CEIL_LONG( metrics->horiBearingY ); - metrics->width = right - metrics->horiBearingX; - metrics->height = metrics->horiBearingY - bottom; + metrics->width = SUB_LONG( right, + metrics->horiBearingX ); + metrics->height = SUB_LONG( metrics->horiBearingY, + bottom ); } - metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); - metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); + metrics->horiAdvance = FT_PIX_ROUND_LONG( metrics->horiAdvance ); + metrics->vertAdvance = FT_PIX_ROUND_LONG( metrics->vertAdvance ); } #endif /* GRID_FIT_METRICS */ @@ -4549,7 +4557,7 @@ if ( !clazz ) return FT_THROW( Invalid_Argument ); - /* check freetype version */ + /* check FreeType version */ if ( clazz->module_requires > FREETYPE_VER_FIXED ) return FT_THROW( Invalid_Version ); @@ -4973,10 +4981,6 @@ goto Fail; #endif - /* we don't use raster_pool anymore. */ - library->raster_pool_size = 0; - library->raster_pool = NULL; - library->version_major = FREETYPE_MAJOR; library->version_minor = FREETYPE_MINOR; library->version_patch = FREETYPE_PATCH; diff --git a/thirdparty/freetype/src/base/ftoutln.c b/thirdparty/freetype/src/base/ftoutln.c index 464a066dcc..9ceb9cf1ba 100644 --- a/thirdparty/freetype/src/base/ftoutln.c +++ b/thirdparty/freetype/src/base/ftoutln.c @@ -1088,7 +1088,8 @@ 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 ); + area = ADD_LONG( area, + ( v_cur.y - v_prev.y ) * ( v_cur.x + v_prev.x ) ); v_prev = v_cur; } diff --git a/thirdparty/freetype/src/base/ftrfork.c b/thirdparty/freetype/src/base/ftrfork.c index f7b81375dd..f5ad2874d8 100644 --- a/thirdparty/freetype/src/base/ftrfork.c +++ b/thirdparty/freetype/src/base/ftrfork.c @@ -271,7 +271,13 @@ if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ goto Exit; - if ( ref[j].res_id < 0 || temp < 0 ) + /* + * According to Inside Macintosh: More Macintosh Toolbox, + * "Resource IDs" (1-46), there are some reserved IDs. + * However, FreeType2 is not a font synthesizer, no need + * to check the acceptable resource ID. + */ + if ( temp < 0 ) { error = FT_THROW( Invalid_Table ); goto Exit; @@ -281,7 +287,7 @@ FT_TRACE3(( " [%d]:" " resource_id=0x%04x, offset=0x%08x\n", - j, ref[j].res_id, ref[j].offset )); + j, (FT_UShort)ref[j].res_id, ref[j].offset )); } if ( sort_by_res_id ) diff --git a/thirdparty/freetype/src/base/ftsynth.c b/thirdparty/freetype/src/base/ftsynth.c index 66dae6037a..5cf386f48d 100644 --- a/thirdparty/freetype/src/base/ftsynth.c +++ b/thirdparty/freetype/src/base/ftsynth.c @@ -123,7 +123,7 @@ /* * XXX: overflow check for 16-bit system, for compatibility - * with FT_GlyphSlot_Embolden() since freetype-2.1.10. + * with FT_GlyphSlot_Embolden() since FreeType 2.1.10. * unfortunately, this function return no informations * about the cause of error. */ diff --git a/thirdparty/freetype/src/base/ftutil.c b/thirdparty/freetype/src/base/ftutil.c index dccc209f4d..7bd5bee87c 100644 --- a/thirdparty/freetype/src/base/ftutil.c +++ b/thirdparty/freetype/src/base/ftutil.c @@ -135,7 +135,7 @@ ft_mem_free( memory, block ); block = NULL; } - else if ( new_count > FT_INT_MAX/item_size ) + else if ( new_count > FT_INT_MAX / item_size ) { error = FT_THROW( Array_Too_Large ); } @@ -143,13 +143,15 @@ { FT_ASSERT( !block ); - block = ft_mem_alloc( memory, new_count*item_size, &error ); + block = memory->alloc( memory, new_count * item_size ); + if ( block == NULL ) + error = FT_THROW( Out_Of_Memory ); } else { FT_Pointer block2; - FT_Long cur_size = cur_count*item_size; - FT_Long new_size = new_count*item_size; + FT_Long cur_size = cur_count * item_size; + FT_Long new_size = new_count * item_size; block2 = memory->realloc( memory, cur_size, new_size, block ); diff --git a/thirdparty/freetype/src/bdf/bdfdrivr.c b/thirdparty/freetype/src/bdf/bdfdrivr.c index a2242be014..fb77810007 100644 --- a/thirdparty/freetype/src/bdf/bdfdrivr.c +++ b/thirdparty/freetype/src/bdf/bdfdrivr.c @@ -373,7 +373,7 @@ THE SOFTWARE. /* we have a bdf font: let's construct the face object */ face->bdffont = font; - /* BDF could not have multiple face in single font file. + /* BDF cannot have multiple faces in a single font file. * XXX: non-zero face_index is already invalid argument, but * Type1, Type42 driver has a convention to return * an invalid argument error when the font could be @@ -437,46 +437,156 @@ THE SOFTWARE. { FT_Bitmap_Size* bsize = bdfface->available_sizes; FT_Short resolution_x = 0, resolution_y = 0; + long value; FT_ZERO( bsize ); + /* sanity checks */ + if ( font->font_ascent > 0x7FFF || font->font_ascent < -0x7FFF ) + { + font->font_ascent = font->font_ascent < 0 ? -0x7FFF : 0x7FFF; + FT_TRACE0(( "BDF_Face_Init: clamping font ascent to value %d\n", + font->font_ascent )); + } + if ( font->font_descent > 0x7FFF || font->font_descent < -0x7FFF ) + { + font->font_descent = font->font_descent < 0 ? -0x7FFF : 0x7FFF; + FT_TRACE0(( "BDF_Face_Init: clamping font descent to value %d\n", + font->font_descent )); + } + bsize->height = (FT_Short)( font->font_ascent + font->font_descent ); prop = bdf_get_font_property( font, "AVERAGE_WIDTH" ); if ( prop ) - bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 ); + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( prop->value.l < 0 ) + FT_TRACE0(( "BDF_Face_Init: negative average width\n" )); +#endif + if ( prop->value.l > 0x7FFFL * 10 - 5 || + prop->value.l < -( 0x7FFFL * 10 - 5 ) ) + { + bsize->width = 0x7FFF; + FT_TRACE0(( "BDF_Face_Init: clamping average width to value %d\n", + bsize->width )); + } + else + bsize->width = FT_ABS( (FT_Short)( ( prop->value.l + 5 ) / 10 ) ); + } else - bsize->width = (FT_Short)( bsize->height * 2/3 ); + { + /* this is a heuristical value */ + bsize->width = (FT_Short)FT_MulDiv( bsize->height, 2, 3 ); + } prop = bdf_get_font_property( font, "POINT_SIZE" ); if ( prop ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( prop->value.l < 0 ) + FT_TRACE0(( "BDF_Face_Init: negative point size\n" )); +#endif /* convert from 722.7 decipoints to 72 points per inch */ - bsize->size = - (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L ); + if ( prop->value.l > 0x504C2L || /* 0x7FFF * 72270/7200 */ + prop->value.l < -0x504C2L ) + { + bsize->size = 0x7FFF; + FT_TRACE0(( "BDF_Face_Init: clamping point size to value %d\n", + bsize->size )); + } + else + bsize->size = FT_MulDiv( FT_ABS( prop->value.l ), + 64 * 7200, + 72270L ); + } + else if ( font->point_size ) + { + if ( font->point_size > 0x7FFF ) + { + bsize->size = 0x7FFF; + FT_TRACE0(( "BDF_Face_Init: clamping point size to value %d\n", + bsize->size )); + } + else + bsize->size = (FT_Pos)font->point_size << 6; + } else - bsize->size = bsize->width << 6; + { + /* this is a heuristical value */ + bsize->size = bsize->width * 64; + } prop = bdf_get_font_property( font, "PIXEL_SIZE" ); if ( prop ) - bsize->y_ppem = (FT_Short)prop->value.l << 6; + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( prop->value.l < 0 ) + FT_TRACE0(( "BDF_Face_Init: negative pixel size\n" )); +#endif + if ( prop->value.l > 0x7FFF || prop->value.l < -0x7FFF ) + { + bsize->y_ppem = 0x7FFF << 6; + FT_TRACE0(( "BDF_Face_Init: clamping pixel size to value %d\n", + bsize->y_ppem )); + } + else + bsize->y_ppem = FT_ABS( (FT_Short)prop->value.l ) << 6; + } prop = bdf_get_font_property( font, "RESOLUTION_X" ); if ( prop ) - resolution_x = (FT_Short)prop->value.l; + value = prop->value.l; + else + value = (long)font->resolution_x; + if ( value ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( value < 0 ) + FT_TRACE0(( "BDF_Face_Init: negative X resolution\n" )); +#endif + if ( value > 0x7FFF || value < -0x7FFF ) + { + resolution_x = 0x7FFF; + FT_TRACE0(( "BDF_Face_Init: clamping X resolution to value %d\n", + resolution_x )); + } + else + resolution_x = FT_ABS( (FT_Short)value ); + } prop = bdf_get_font_property( font, "RESOLUTION_Y" ); if ( prop ) - resolution_y = (FT_Short)prop->value.l; + value = prop->value.l; + else + value = (long)font->resolution_y; + if ( value ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( value < 0 ) + FT_TRACE0(( "BDF_Face_Init: negative Y resolution\n" )); +#endif + if ( value > 0x7FFF || value < -0x7FFF ) + { + resolution_y = 0x7FFF; + FT_TRACE0(( "BDF_Face_Init: clamping Y resolution to value %d\n", + resolution_y )); + } + else + resolution_y = FT_ABS( (FT_Short)value ); + } if ( bsize->y_ppem == 0 ) { bsize->y_ppem = bsize->size; if ( resolution_y ) - bsize->y_ppem = bsize->y_ppem * resolution_y / 72; + bsize->y_ppem = FT_MulDiv( bsize->y_ppem, resolution_y, 72 ); } if ( resolution_x && resolution_y ) - bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; + bsize->x_ppem = FT_MulDiv( bsize->y_ppem, + resolution_x, + resolution_y ); else bsize->x_ppem = bsize->y_ppem; } @@ -545,7 +655,11 @@ THE SOFTWARE. if ( !ft_strcmp( s, "10646" ) || ( !ft_strcmp( s, "8859" ) && !ft_strcmp( face->charset_encoding, "1" ) ) ) - unicode_charmap = 1; + unicode_charmap = 1; + /* another name for ASCII */ + else if ( !ft_strcmp( s, "646.1991" ) && + !ft_strcmp( face->charset_encoding, "IRV" ) ) + unicode_charmap = 1; } { @@ -566,12 +680,6 @@ THE SOFTWARE. } error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL ); - -#if 0 - /* Select default charmap */ - if ( bdfface->num_charmaps ) - bdfface->charmap = bdfface->charmaps[0]; -#endif } goto Exit; diff --git a/thirdparty/freetype/src/bdf/bdflib.c b/thirdparty/freetype/src/bdf/bdflib.c index 7fd95a7385..bf10887fd4 100644 --- a/thirdparty/freetype/src/bdf/bdflib.c +++ b/thirdparty/freetype/src/bdf/bdflib.c @@ -704,7 +704,15 @@ return 0; for ( v = 0; sbitset( ddigits, *s ); s++ ) - v = v * 10 + a2i[(int)*s]; + { + if ( v < ( ULONG_MAX - 9 ) / 10 ) + v = v * 10 + a2i[(int)*s]; + else + { + v = ULONG_MAX; + break; + } + } return v; } @@ -729,7 +737,15 @@ } for ( v = 0; sbitset( ddigits, *s ); s++ ) - v = v * 10 + a2i[(int)*s]; + { + if ( v < ( LONG_MAX - 9 ) / 10 ) + v = v * 10 + a2i[(int)*s]; + else + { + v = LONG_MAX; + break; + } + } return ( !neg ) ? v : -v; } @@ -746,7 +762,15 @@ return 0; for ( v = 0; sbitset( ddigits, *s ); s++ ) - v = (unsigned short)( v * 10 + a2i[(int)*s] ); + { + if ( v < ( USHRT_MAX - 9 ) / 10 ) + v = (unsigned short)( v * 10 + a2i[(int)*s] ); + else + { + v = USHRT_MAX; + break; + } + } return v; } @@ -771,7 +795,15 @@ } for ( v = 0; sbitset( ddigits, *s ); s++ ) - v = (short)( v * 10 + a2i[(int)*s] ); + { + if ( v < ( SHRT_MAX - 9 ) / 10 ) + v = (short)( v * 10 + a2i[(int)*s] ); + else + { + v = SHRT_MAX; + break; + } + } return (short)( ( !neg ) ? v : -v ); } diff --git a/thirdparty/freetype/src/cache/ftcbasic.c b/thirdparty/freetype/src/cache/ftcbasic.c index 289bd5c430..e804776ab4 100644 --- a/thirdparty/freetype/src/cache/ftcbasic.c +++ b/thirdparty/freetype/src/cache/ftcbasic.c @@ -304,10 +304,18 @@ if ( anode ) *anode = NULL; - if ( (FT_ULong)( type->flags - FT_INT_MIN ) > FT_UINT_MAX ) + /* + * Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt', + * but public `FT_ImageType->flags' is of type `FT_Int32'. + * + * On 16bit systems, higher bits of type->flags cannot be handled. + */ +#if 0xFFFFFFFFUL > FT_UINT_MAX + if ( (type->flags & (FT_ULong)FT_UINT_MAX) ) FT_TRACE1(( "FTC_ImageCache_Lookup:" " higher bits in load_flags 0x%x are dropped\n", (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) )); +#endif query.attrs.scaler.face_id = type->face_id; query.attrs.scaler.width = type->width; @@ -377,11 +385,18 @@ if ( anode ) *anode = NULL; - /* `FT_Load_Glyph' and `FT_Load_Char' take FT_UInt flags */ + /* + * Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt', + * but public `FT_Face->face_flags' is of type `FT_Long'. + * + * On long > int systems, higher bits of load_flags cannot be handled. + */ +#if FT_ULONG_MAX > FT_UINT_MAX if ( load_flags > FT_UINT_MAX ) FT_TRACE1(( "FTC_ImageCache_LookupScaler:" " higher bits in load_flags 0x%x are dropped\n", load_flags & ~((FT_ULong)FT_UINT_MAX) )); +#endif query.attrs.scaler = scaler[0]; query.attrs.load_flags = (FT_UInt)load_flags; @@ -487,10 +502,18 @@ *ansbit = NULL; - if ( (FT_ULong)( type->flags - FT_INT_MIN ) > FT_UINT_MAX ) + /* + * Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt', + * but public `FT_ImageType->flags' is of type `FT_Int32'. + * + * On 16bit systems, higher bits of type->flags cannot be handled. + */ +#if 0xFFFFFFFFUL > FT_UINT_MAX + if ( (type->flags & (FT_ULong)FT_UINT_MAX) ) FT_TRACE1(( "FTC_ImageCache_Lookup:" " higher bits in load_flags 0x%x are dropped\n", (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) )); +#endif query.attrs.scaler.face_id = type->face_id; query.attrs.scaler.width = type->width; @@ -562,11 +585,18 @@ *ansbit = NULL; - /* `FT_Load_Glyph' and `FT_Load_Char' take FT_UInt flags */ + /* + * Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt', + * but public `FT_Face->face_flags' is of type `FT_Long'. + * + * On long > int systems, higher bits of load_flags cannot be handled. + */ +#if FT_ULONG_MAX > FT_UINT_MAX if ( load_flags > FT_UINT_MAX ) FT_TRACE1(( "FTC_ImageCache_LookupScaler:" " higher bits in load_flags 0x%x are dropped\n", load_flags & ~((FT_ULong)FT_UINT_MAX) )); +#endif query.attrs.scaler = scaler[0]; query.attrs.load_flags = (FT_UInt)load_flags; diff --git a/thirdparty/freetype/src/cff/cf2blues.c b/thirdparty/freetype/src/cff/cf2blues.c index 250f89e0df..c491f2f9e5 100644 --- a/thirdparty/freetype/src/cff/cf2blues.c +++ b/thirdparty/freetype/src/cff/cf2blues.c @@ -194,8 +194,8 @@ blues->zone[blues->count].csTopEdge = cf2_blueToFixed( blueValues[i + 1] ); - zoneHeight = blues->zone[blues->count].csTopEdge - - blues->zone[blues->count].csBottomEdge; + zoneHeight = SUB_INT32( blues->zone[blues->count].csTopEdge, + blues->zone[blues->count].csBottomEdge ); if ( zoneHeight < 0 ) { @@ -243,8 +243,8 @@ blues->zone[blues->count].csTopEdge = cf2_blueToFixed( otherBlues[i + 1] ); - zoneHeight = blues->zone[blues->count].csTopEdge - - blues->zone[blues->count].csBottomEdge; + zoneHeight = SUB_INT32( blues->zone[blues->count].csTopEdge, + blues->zone[blues->count].csBottomEdge ); if ( zoneHeight < 0 ) { @@ -301,7 +301,7 @@ /* top edge */ flatFamilyEdge = cf2_blueToFixed( familyOtherBlues[j + 1] ); - diff = cf2_fixedAbs( flatEdge - flatFamilyEdge ); + diff = cf2_fixedAbs( SUB_INT32( flatEdge, flatFamilyEdge ) ); if ( diff < minDiff && diff < csUnitsPerPixel ) { @@ -319,7 +319,7 @@ /* top edge */ flatFamilyEdge = cf2_blueToFixed( familyBlues[1] ); - diff = cf2_fixedAbs( flatEdge - flatFamilyEdge ); + diff = cf2_fixedAbs( SUB_INT32( flatEdge, flatFamilyEdge ) ); if ( diff < minDiff && diff < csUnitsPerPixel ) blues->zone[i].csFlatEdge = flatFamilyEdge; @@ -342,7 +342,7 @@ /* adjust edges of top zone upward by twice darkening amount */ flatFamilyEdge += 2 * font->darkenY; /* bottom edge */ - diff = cf2_fixedAbs( flatEdge - flatFamilyEdge ); + diff = cf2_fixedAbs( SUB_INT32( flatEdge, flatFamilyEdge ) ); if ( diff < minDiff && diff < csUnitsPerPixel ) { @@ -408,8 +408,8 @@ /* Note: constant changed from 0.5 to 0.6 to avoid a problem with */ /* 10ppem Arial */ - blues->boost = cf2_floatToFixed( .6 ) - - FT_MulDiv( cf2_floatToFixed ( .6 ), + blues->boost = cf2_doubleToFixed( .6 ) - + FT_MulDiv( cf2_doubleToFixed ( .6 ), blues->scale, blues->blueScale ); if ( blues->boost > 0x7FFF ) @@ -489,17 +489,18 @@ if ( blues->zone[i].bottomZone && cf2_hint_isBottom( bottomHintEdge ) ) { - if ( ( blues->zone[i].csBottomEdge - csFuzz ) <= - bottomHintEdge->csCoord && + if ( SUB_INT32( blues->zone[i].csBottomEdge, csFuzz ) <= + bottomHintEdge->csCoord && bottomHintEdge->csCoord <= - ( blues->zone[i].csTopEdge + csFuzz ) ) + ADD_INT32( blues->zone[i].csTopEdge, csFuzz ) ) { /* bottom edge captured by bottom zone */ if ( blues->suppressOvershoot ) dsNew = blues->zone[i].dsFlatEdge; - else if ( ( blues->zone[i].csTopEdge - bottomHintEdge->csCoord ) >= + else if ( SUB_INT32( blues->zone[i].csTopEdge, + bottomHintEdge->csCoord ) >= blues->blueShift ) { /* guarantee minimum of 1 pixel overshoot */ @@ -514,7 +515,7 @@ dsNew = cf2_fixedRound( bottomHintEdge->dsCoord ); } - dsMove = dsNew - bottomHintEdge->dsCoord; + dsMove = SUB_INT32( dsNew, bottomHintEdge->dsCoord ); captured = TRUE; break; @@ -523,17 +524,18 @@ if ( !blues->zone[i].bottomZone && cf2_hint_isTop( topHintEdge ) ) { - if ( ( blues->zone[i].csBottomEdge - csFuzz ) <= - topHintEdge->csCoord && + if ( SUB_INT32( blues->zone[i].csBottomEdge, csFuzz ) <= + topHintEdge->csCoord && topHintEdge->csCoord <= - ( blues->zone[i].csTopEdge + csFuzz ) ) + ADD_INT32( blues->zone[i].csTopEdge, csFuzz ) ) { /* top edge captured by top zone */ if ( blues->suppressOvershoot ) dsNew = blues->zone[i].dsFlatEdge; - else if ( ( topHintEdge->csCoord - blues->zone[i].csBottomEdge ) >= + else if ( SUB_INT32( topHintEdge->csCoord, + blues->zone[i].csBottomEdge ) >= blues->blueShift ) { /* guarantee minimum of 1 pixel overshoot */ @@ -548,7 +550,7 @@ dsNew = cf2_fixedRound( topHintEdge->dsCoord ); } - dsMove = dsNew - topHintEdge->dsCoord; + dsMove = SUB_INT32( dsNew, topHintEdge->dsCoord ); captured = TRUE; break; @@ -561,13 +563,14 @@ /* move both edges and flag them `locked' */ if ( cf2_hint_isValid( bottomHintEdge ) ) { - bottomHintEdge->dsCoord += dsMove; + bottomHintEdge->dsCoord = ADD_INT32( bottomHintEdge->dsCoord, + dsMove ); cf2_hint_lock( bottomHintEdge ); } if ( cf2_hint_isValid( topHintEdge ) ) { - topHintEdge->dsCoord += dsMove; + topHintEdge->dsCoord = ADD_INT32( topHintEdge->dsCoord, dsMove ); cf2_hint_lock( topHintEdge ); } } diff --git a/thirdparty/freetype/src/cff/cf2blues.h b/thirdparty/freetype/src/cff/cf2blues.h index 96fb60f38d..a6bcd9de57 100644 --- a/thirdparty/freetype/src/cff/cf2blues.h +++ b/thirdparty/freetype/src/cff/cf2blues.h @@ -111,7 +111,7 @@ FT_BEGIN_HEADER * Constant used for hint adjustment and for synthetic em box hint * placement. */ -#define CF2_MIN_COUNTER cf2_floatToFixed( 0.5 ) +#define CF2_MIN_COUNTER cf2_doubleToFixed( 0.5 ) /* shared typedef is in cf2glue.h */ diff --git a/thirdparty/freetype/src/cff/cf2fixed.h b/thirdparty/freetype/src/cff/cf2fixed.h index 2e4b5032fa..a041184bda 100644 --- a/thirdparty/freetype/src/cff/cf2fixed.h +++ b/thirdparty/freetype/src/cff/cf2fixed.h @@ -63,10 +63,10 @@ FT_BEGIN_HEADER ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) #define cf2_fixedRound( x ) \ ( (CF2_Fixed)( ( (FT_UInt32)(x) + 0x8000U ) & 0xFFFF0000UL ) ) -#define cf2_floatToFixed( f ) \ +#define cf2_doubleToFixed( f ) \ ( (CF2_Fixed)( (f) * 65536.0 + 0.5 ) ) #define cf2_fixedAbs( x ) \ - ( (x) < 0 ? -(x) : (x) ) + ( (x) < 0 ? NEG_INT32( x ) : (x) ) #define cf2_fixedFloor( x ) \ ( (CF2_Fixed)( (FT_UInt32)(x) & 0xFFFF0000UL ) ) #define cf2_fixedFraction( x ) \ diff --git a/thirdparty/freetype/src/cff/cf2font.c b/thirdparty/freetype/src/cff/cf2font.c index a86e3619b4..4ac71a8d71 100644 --- a/thirdparty/freetype/src/cff/cf2font.c +++ b/thirdparty/freetype/src/cff/cf2font.c @@ -117,7 +117,7 @@ return; /* protect against range problems and divide by zero */ - if ( emRatio < cf2_floatToFixed( .01 ) ) + if ( emRatio < cf2_doubleToFixed( .01 ) ) return; if ( stemDarkened ) @@ -447,7 +447,7 @@ /* choose a constant for StdHW that depends on font contrast */ stdHW = cf2_getStdHW( decoder ); - if ( stdHW > 0 && font->stdVW > 2 * stdHW ) + if ( stdHW > 0 && font->stdVW > MUL_INT32( 2, stdHW ) ) font->stdHW = FT_DivFix( cf2_intToFixed( 75 ), emRatio ); else { diff --git a/thirdparty/freetype/src/cff/cf2ft.c b/thirdparty/freetype/src/cff/cf2ft.c index eb8472f119..c6c00d1623 100644 --- a/thirdparty/freetype/src/cff/cf2ft.c +++ b/thirdparty/freetype/src/cff/cf2ft.c @@ -267,8 +267,8 @@ if ( *hinted ) { - *x_scale = ( decoder->builder.glyph->x_scale + 32 ) / 64; - *y_scale = ( decoder->builder.glyph->y_scale + 32 ) / 64; + *x_scale = ADD_INT32( decoder->builder.glyph->x_scale, 32 ) / 64; + *y_scale = ADD_INT32( decoder->builder.glyph->y_scale, 32 ) / 64; } else { diff --git a/thirdparty/freetype/src/cff/cf2hints.c b/thirdparty/freetype/src/cff/cf2hints.c index c8f7dfeba6..656eb2cff1 100644 --- a/thirdparty/freetype/src/cff/cf2hints.c +++ b/thirdparty/freetype/src/cff/cf2hints.c @@ -74,8 +74,8 @@ /* cross product of pt1 position from origin with pt2 position from */ /* pt1; we reduce the precision so that the result fits into 32 bits */ - return ( x1 >> 16 ) * ( ( y2 - y1 ) >> 16 ) - - ( y1 >> 16 ) * ( ( x2 - x1 ) >> 16 ); + return ( x1 >> 16 ) * ( SUB_INT32( y2, y1 ) >> 16 ) - + ( y1 >> 16 ) * ( SUB_INT32( x2, x1 ) >> 16 ); } @@ -105,7 +105,7 @@ stemHintArray, indexStemHint ); - width = stemHint->max - stemHint->min; + width = SUB_INT32( stemHint->max, stemHint->min ); if ( width == cf2_intToFixed( -21 ) ) { @@ -185,11 +185,11 @@ /* darkening. Bottoms are not changed; tops are incremented by twice */ /* `darkenY'. */ if ( cf2_hint_isTop( hint ) ) - hint->csCoord += 2 * font->darkenY; + hint->csCoord = ADD_INT32( hint->csCoord, 2 * font->darkenY ); - hint->csCoord += hintOrigin; - hint->scale = scale; - hint->index = indexStemHint; /* index in original stem hint array */ + hint->csCoord = ADD_INT32( hint->csCoord, hintOrigin ); + hint->scale = scale; + hint->index = indexStemHint; /* index in original stem hint array */ /* if original stem hint has been used, use the same position */ if ( hint->flags != 0 && stemHint->used ) @@ -314,6 +314,7 @@ /* start linear search from last hit */ CF2_UInt i = hintmap->lastIndex; + FT_ASSERT( hintmap->lastIndex < CF2_MAX_HINT_EDGES ); /* search up */ @@ -330,9 +331,10 @@ if ( i == 0 && csCoord < hintmap->edge[0].csCoord ) { /* special case for points below first edge: use uniform scale */ - return FT_MulFix( csCoord - hintmap->edge[0].csCoord, - hintmap->scale ) + - hintmap->edge[0].dsCoord; + return ADD_INT32( FT_MulFix( SUB_INT32( csCoord, + hintmap->edge[0].csCoord ), + hintmap->scale ), + hintmap->edge[0].dsCoord ); } else { @@ -340,9 +342,10 @@ * Note: entries with duplicate csCoord are allowed. * Use edge[i], the highest entry where csCoord >= entry[i].csCoord */ - return FT_MulFix( csCoord - hintmap->edge[i].csCoord, - hintmap->edge[i].scale ) + - hintmap->edge[i].dsCoord; + return ADD_INT32( FT_MulFix( SUB_INT32( csCoord, + hintmap->edge[i].csCoord ), + hintmap->edge[i].scale ), + hintmap->edge[i].dsCoord ); } } } @@ -437,14 +440,16 @@ /* is there room to move up? */ /* there is if we are at top of array or the next edge is at or */ /* beyond proposed move up? */ - if ( j >= hintmap->count - 1 || + if ( j >= hintmap->count - 1 || hintmap->edge[j + 1].dsCoord >= - hintmap->edge[j].dsCoord + moveUp + upMinCounter ) + ADD_INT32( hintmap->edge[j].dsCoord, + moveUp + upMinCounter ) ) { /* there is room to move up; is there also room to move down? */ - if ( i == 0 || + if ( i == 0 || hintmap->edge[i - 1].dsCoord <= - hintmap->edge[i].dsCoord + moveDown - downMinCounter ) + ADD_INT32( hintmap->edge[i].dsCoord, + moveDown - downMinCounter ) ) { /* move smaller absolute amount */ move = ( -moveDown < moveUp ) ? moveDown : moveUp; /* optimum */ @@ -455,9 +460,10 @@ else { /* is there room to move down? */ - if ( i == 0 || + if ( i == 0 || hintmap->edge[i - 1].dsCoord <= - hintmap->edge[i].dsCoord + moveDown - downMinCounter ) + ADD_INT32( hintmap->edge[i].dsCoord, + moveDown - downMinCounter ) ) { move = moveDown; /* true if non-optimum move */ @@ -491,9 +497,11 @@ } /* move the edge(s) */ - hintmap->edge[i].dsCoord += move; + hintmap->edge[i].dsCoord = ADD_INT32( hintmap->edge[i].dsCoord, + move ); if ( isPair ) - hintmap->edge[j].dsCoord += move; + hintmap->edge[j].dsCoord = ADD_INT32( hintmap->edge[j].dsCoord, + move ); } /* assert there are no overlaps in device space */ @@ -507,18 +515,20 @@ { if ( hintmap->edge[i].csCoord != hintmap->edge[i - 1].csCoord ) hintmap->edge[i - 1].scale = - FT_DivFix( - hintmap->edge[i].dsCoord - hintmap->edge[i - 1].dsCoord, - hintmap->edge[i].csCoord - hintmap->edge[i - 1].csCoord ); + FT_DivFix( SUB_INT32( hintmap->edge[i].dsCoord, + hintmap->edge[i - 1].dsCoord ), + SUB_INT32( hintmap->edge[i].csCoord, + hintmap->edge[i - 1].csCoord ) ); } if ( isPair ) { if ( hintmap->edge[j].csCoord != hintmap->edge[j - 1].csCoord ) hintmap->edge[j - 1].scale = - FT_DivFix( - hintmap->edge[j].dsCoord - hintmap->edge[j - 1].dsCoord, - hintmap->edge[j].csCoord - hintmap->edge[j - 1].csCoord ); + FT_DivFix( SUB_INT32( hintmap->edge[j].dsCoord, + hintmap->edge[j - 1].dsCoord ), + SUB_INT32( hintmap->edge[j].csCoord, + hintmap->edge[j - 1].csCoord ) ); i += 1; /* skip upper edge on next loop */ } @@ -539,15 +549,18 @@ /* is there room to move up? */ if ( hintmap->edge[j + 1].dsCoord >= - hintmap->edge[j].dsCoord + hintMove->moveUp + CF2_MIN_COUNTER ) + ADD_INT32( hintmap->edge[j].dsCoord, + hintMove->moveUp + CF2_MIN_COUNTER ) ) { /* there is more room now, move edge up */ - hintmap->edge[j].dsCoord += hintMove->moveUp; + hintmap->edge[j].dsCoord = ADD_INT32( hintmap->edge[j].dsCoord, + hintMove->moveUp ); if ( cf2_hint_isPair( &hintmap->edge[j] ) ) { FT_ASSERT( j > 0 ); - hintmap->edge[j - 1].dsCoord += hintMove->moveUp; + hintmap->edge[j - 1].dsCoord = + ADD_INT32( hintmap->edge[j - 1].dsCoord, hintMove->moveUp ); } } } @@ -635,18 +648,19 @@ { /* Use hint map to position the center of stem, and nominal scale */ /* to position the two edges. This preserves the stem width. */ - CF2_Fixed midpoint = cf2_hintmap_map( - hintmap->initialHintMap, - ( secondHintEdge->csCoord + - firstHintEdge->csCoord ) / 2 ); - CF2_Fixed halfWidth = FT_MulFix( - ( secondHintEdge->csCoord - - firstHintEdge->csCoord ) / 2, - hintmap->scale ); - - - firstHintEdge->dsCoord = midpoint - halfWidth; - secondHintEdge->dsCoord = midpoint + halfWidth; + CF2_Fixed midpoint = + cf2_hintmap_map( + hintmap->initialHintMap, + ADD_INT32( secondHintEdge->csCoord, + firstHintEdge->csCoord ) / 2 ); + CF2_Fixed halfWidth = + FT_MulFix( SUB_INT32( secondHintEdge->csCoord, + firstHintEdge->csCoord ) / 2, + hintmap->scale ); + + + firstHintEdge->dsCoord = SUB_INT32( midpoint, halfWidth ); + secondHintEdge->dsCoord = ADD_INT32( midpoint, halfWidth ); } else firstHintEdge->dsCoord = cf2_hintmap_map( hintmap->initialHintMap, @@ -715,7 +729,7 @@ /* insert first edge */ hintmap->edge[indexInsert] = *firstHintEdge; /* copy struct */ - hintmap->count += 1; + hintmap->count += 1; if ( isPair ) { @@ -781,7 +795,7 @@ cf2_arrstack_size( hStemHintArray ) + cf2_arrstack_size( vStemHintArray ) ); if ( !cf2_hintmask_isValid( hintMask ) ) - return; /* too many stem hints */ + return; /* too many stem hints */ } /* begin by clearing the map */ @@ -797,7 +811,7 @@ /* Defense-in-depth. Should never return here. */ if ( bitCount > hintMask->bitCount ) - return; + return; /* synthetic embox hints get highest priority */ if ( font->blues.doEmBoxHints ) @@ -1063,7 +1077,7 @@ cf2_fixedAbs( glyphpath->yOffset ) ); /* .1 character space unit */ - glyphpath->snapThreshold = cf2_floatToFixed( 0.1f ); + glyphpath->snapThreshold = cf2_doubleToFixed( 0.1 ); glyphpath->moveIsPending = TRUE; glyphpath->pathIsOpen = FALSE; @@ -1095,16 +1109,20 @@ FT_Vector pt; /* hinted point in upright DS */ - pt.x = FT_MulFix( glyphpath->scaleX, x ) + - FT_MulFix( glyphpath->scaleC, y ); + pt.x = ADD_INT32( FT_MulFix( glyphpath->scaleX, x ), + FT_MulFix( glyphpath->scaleC, y ) ); pt.y = cf2_hintmap_map( hintmap, y ); - ppt->x = FT_MulFix( glyphpath->font->outerTransform.a, pt.x ) + - FT_MulFix( glyphpath->font->outerTransform.c, pt.y ) + - glyphpath->fractionalTranslation.x; - ppt->y = FT_MulFix( glyphpath->font->outerTransform.b, pt.x ) + - FT_MulFix( glyphpath->font->outerTransform.d, pt.y ) + - glyphpath->fractionalTranslation.y; + ppt->x = ADD_INT32( + FT_MulFix( glyphpath->font->outerTransform.a, pt.x ), + ADD_INT32( + FT_MulFix( glyphpath->font->outerTransform.c, pt.y ), + glyphpath->fractionalTranslation.x ) ); + ppt->y = ADD_INT32( + FT_MulFix( glyphpath->font->outerTransform.b, pt.x ), + ADD_INT32( + FT_MulFix( glyphpath->font->outerTransform.d, pt.y ), + glyphpath->fractionalTranslation.y ) ); } @@ -1154,12 +1172,12 @@ CF2_Fixed denominator, s; - u.x = CF2_CS_SCALE( u2->x - u1->x ); - u.y = CF2_CS_SCALE( u2->y - u1->y ); - v.x = CF2_CS_SCALE( v2->x - v1->x ); - v.y = CF2_CS_SCALE( v2->y - v1->y ); - w.x = CF2_CS_SCALE( v1->x - u1->x ); - w.y = CF2_CS_SCALE( v1->y - u1->y ); + u.x = CF2_CS_SCALE( SUB_INT32( u2->x, u1->x ) ); + u.y = CF2_CS_SCALE( SUB_INT32( u2->y, u1->y ) ); + v.x = CF2_CS_SCALE( SUB_INT32( v2->x, v1->x ) ); + v.y = CF2_CS_SCALE( SUB_INT32( v2->y, v1->y ) ); + w.x = CF2_CS_SCALE( SUB_INT32( v1->x, u1->x ) ); + w.y = CF2_CS_SCALE( SUB_INT32( v1->y, u1->y ) ); denominator = cf2_perp( u, v ); @@ -1168,8 +1186,11 @@ s = FT_DivFix( cf2_perp( w, v ), denominator ); - intersection->x = u1->x + FT_MulFix( s, u2->x - u1->x ); - intersection->y = u1->y + FT_MulFix( s, u2->y - u1->y ); + intersection->x = ADD_INT32( u1->x, + FT_MulFix( s, SUB_INT32( u2->x, u1->x ) ) ); + intersection->y = ADD_INT32( u1->y, + FT_MulFix( s, SUB_INT32( u2->y, u1->y ) ) ); + /* * Special case snapping for horizontal and vertical lines. @@ -1180,25 +1201,29 @@ * */ - if ( u1->x == u2->x && - cf2_fixedAbs( intersection->x - u1->x ) < glyphpath->snapThreshold ) + if ( u1->x == u2->x && + cf2_fixedAbs( SUB_INT32( intersection->x, + u1->x ) ) < glyphpath->snapThreshold ) intersection->x = u1->x; - if ( u1->y == u2->y && - cf2_fixedAbs( intersection->y - u1->y ) < glyphpath->snapThreshold ) + if ( u1->y == u2->y && + cf2_fixedAbs( SUB_INT32( intersection->y, + u1->y ) ) < glyphpath->snapThreshold ) intersection->y = u1->y; - if ( v1->x == v2->x && - cf2_fixedAbs( intersection->x - v1->x ) < glyphpath->snapThreshold ) + if ( v1->x == v2->x && + cf2_fixedAbs( SUB_INT32( intersection->x, + v1->x ) ) < glyphpath->snapThreshold ) intersection->x = v1->x; - if ( v1->y == v2->y && - cf2_fixedAbs( intersection->y - v1->y ) < glyphpath->snapThreshold ) + if ( v1->y == v2->y && + cf2_fixedAbs( SUB_INT32( intersection->y, + v1->y ) ) < glyphpath->snapThreshold ) intersection->y = v1->y; /* limit the intersection distance from midpoint of u2 and v1 */ - if ( cf2_fixedAbs( intersection->x - ( u2->x + v1->x ) / 2 ) > - glyphpath->miterLimit || - cf2_fixedAbs( intersection->y - ( u2->y + v1->y ) / 2 ) > - glyphpath->miterLimit ) + if ( cf2_fixedAbs( intersection->x - ADD_INT32( u2->x, v1->x ) / 2 ) > + glyphpath->miterLimit || + cf2_fixedAbs( intersection->y - ADD_INT32( u2->y, v1->y ) / 2 ) > + glyphpath->miterLimit ) return FALSE; return TRUE; @@ -1446,16 +1471,16 @@ CF2_Fixed* x, CF2_Fixed* y ) { - CF2_Fixed dx = x2 - x1; - CF2_Fixed dy = y2 - y1; + CF2_Fixed dx = SUB_INT32( x2, x1 ); + CF2_Fixed dy = SUB_INT32( y2, y1 ); /* note: negative offsets don't work here; negate deltas to change */ /* quadrants, below */ if ( glyphpath->font->reverseWinding ) { - dx = -dx; - dy = -dy; + dx = NEG_INT32( dx ); + dy = NEG_INT32( dy ); } *x = *y = 0; @@ -1464,8 +1489,9 @@ return; /* add momentum for this path element */ - glyphpath->callbacks->windingMomentum += - cf2_getWindingMomentum( x1, y1, x2, y2 ); + glyphpath->callbacks->windingMomentum = + ADD_INT32( glyphpath->callbacks->windingMomentum, + cf2_getWindingMomentum( x1, y1, x2, y2 ) ); /* note: allow mixed integer and fixed multiplication here */ if ( dx >= 0 ) @@ -1474,13 +1500,13 @@ { /* first quadrant, +x +y */ - if ( dx > 2 * dy ) + if ( dx > MUL_INT32( 2, dy ) ) { /* +x */ *x = 0; *y = 0; } - else if ( dy > 2 * dx ) + else if ( dy > MUL_INT32( 2, dx ) ) { /* +y */ *x = glyphpath->xOffset; @@ -1489,9 +1515,9 @@ else { /* +x +y */ - *x = FT_MulFix( cf2_floatToFixed( 0.7 ), + *x = FT_MulFix( cf2_doubleToFixed( 0.7 ), glyphpath->xOffset ); - *y = FT_MulFix( cf2_floatToFixed( 1.0 - 0.7 ), + *y = FT_MulFix( cf2_doubleToFixed( 1.0 - 0.7 ), glyphpath->yOffset ); } } @@ -1499,24 +1525,24 @@ { /* fourth quadrant, +x -y */ - if ( dx > -2 * dy ) + if ( dx > MUL_INT32( -2, dy ) ) { /* +x */ *x = 0; *y = 0; } - else if ( -dy > 2 * dx ) + else if ( NEG_INT32( dy ) > MUL_INT32( 2, dx ) ) { /* -y */ - *x = -glyphpath->xOffset; + *x = NEG_INT32( glyphpath->xOffset ); *y = glyphpath->yOffset; } else { /* +x -y */ - *x = FT_MulFix( cf2_floatToFixed( -0.7 ), + *x = FT_MulFix( cf2_doubleToFixed( -0.7 ), glyphpath->xOffset ); - *y = FT_MulFix( cf2_floatToFixed( 1.0 - 0.7 ), + *y = FT_MulFix( cf2_doubleToFixed( 1.0 - 0.7 ), glyphpath->yOffset ); } } @@ -1527,13 +1553,13 @@ { /* second quadrant, -x +y */ - if ( -dx > 2 * dy ) + if ( NEG_INT32( dx ) > MUL_INT32( 2, dy ) ) { /* -x */ *x = 0; - *y = 2 * glyphpath->yOffset; + *y = MUL_INT32( 2, glyphpath->yOffset ); } - else if ( dy > -2 * dx ) + else if ( dy > MUL_INT32( -2, dx ) ) { /* +y */ *x = glyphpath->xOffset; @@ -1542,9 +1568,9 @@ else { /* -x +y */ - *x = FT_MulFix( cf2_floatToFixed( 0.7 ), + *x = FT_MulFix( cf2_doubleToFixed( 0.7 ), glyphpath->xOffset ); - *y = FT_MulFix( cf2_floatToFixed( 1.0 + 0.7 ), + *y = FT_MulFix( cf2_doubleToFixed( 1.0 + 0.7 ), glyphpath->yOffset ); } } @@ -1552,24 +1578,24 @@ { /* third quadrant, -x -y */ - if ( -dx > -2 * dy ) + if ( NEG_INT32( dx ) > MUL_INT32( -2, dy ) ) { /* -x */ *x = 0; - *y = 2 * glyphpath->yOffset; + *y = MUL_INT32( 2, glyphpath->yOffset ); } - else if ( -dy > -2 * dx ) + else if ( NEG_INT32( dy ) > MUL_INT32( -2, dx ) ) { /* -y */ - *x = -glyphpath->xOffset; + *x = NEG_INT32( glyphpath->xOffset ); *y = glyphpath->yOffset; } else { /* -x -y */ - *x = FT_MulFix( cf2_floatToFixed( -0.7 ), + *x = FT_MulFix( cf2_doubleToFixed( -0.7 ), glyphpath->xOffset ); - *y = FT_MulFix( cf2_floatToFixed( 1.0 + 0.7 ), + *y = FT_MulFix( cf2_doubleToFixed( 1.0 + 0.7 ), glyphpath->yOffset ); } } @@ -1675,10 +1701,10 @@ &yOffset ); /* construct offset points */ - P0.x = glyphpath->currentCS.x + xOffset; - P0.y = glyphpath->currentCS.y + yOffset; - P1.x = x + xOffset; - P1.y = y + yOffset; + P0.x = ADD_INT32( glyphpath->currentCS.x, xOffset ); + P0.y = ADD_INT32( glyphpath->currentCS.y, yOffset ); + P1.x = ADD_INT32( x, xOffset ); + P1.y = ADD_INT32( y, yOffset ); if ( glyphpath->moveIsPending ) { @@ -1753,19 +1779,20 @@ &yOffset3 ); /* add momentum from the middle segment */ - glyphpath->callbacks->windingMomentum += - cf2_getWindingMomentum( x1, y1, x2, y2 ); + glyphpath->callbacks->windingMomentum = + ADD_INT32( glyphpath->callbacks->windingMomentum, + cf2_getWindingMomentum( x1, y1, x2, y2 ) ); /* construct offset points */ - P0.x = glyphpath->currentCS.x + xOffset1; - P0.y = glyphpath->currentCS.y + yOffset1; - P1.x = x1 + xOffset1; - P1.y = y1 + yOffset1; + P0.x = ADD_INT32( glyphpath->currentCS.x, xOffset1 ); + P0.y = ADD_INT32( glyphpath->currentCS.y, yOffset1 ); + P1.x = ADD_INT32( x1, xOffset1 ); + P1.y = ADD_INT32( y1, yOffset1 ); /* note: preserve angle of final segment by using offset3 at both ends */ - P2.x = x2 + xOffset3; - P2.y = y2 + yOffset3; - P3.x = x3 + xOffset3; - P3.y = y3 + yOffset3; + P2.x = ADD_INT32( x2, xOffset3 ); + P2.y = ADD_INT32( y2, yOffset3 ); + P3.x = ADD_INT32( x3, xOffset3 ); + P3.y = ADD_INT32( y3, yOffset3 ); if ( glyphpath->moveIsPending ) { diff --git a/thirdparty/freetype/src/cff/cf2intrp.c b/thirdparty/freetype/src/cff/cf2intrp.c index 40bd9059a1..a816280748 100644 --- a/thirdparty/freetype/src/cff/cf2intrp.c +++ b/thirdparty/freetype/src/cff/cf2intrp.c @@ -304,10 +304,12 @@ CF2_StemHintRec stemhint; - stemhint.min = - position += cf2_stack_getReal( opStack, i ); - stemhint.max = - position += cf2_stack_getReal( opStack, i + 1 ); + stemhint.min = + position = ADD_INT32( position, + cf2_stack_getReal( opStack, i ) ); + stemhint.max = + position = ADD_INT32( position, + cf2_stack_getReal( opStack, i + 1 ) ); stemhint.used = FALSE; stemhint.maxDS = @@ -348,7 +350,8 @@ { vals[i + 2] = vals[i]; if ( readFromStack[i] ) - vals[i + 2] += cf2_stack_getReal( opStack, idx++ ); + vals[i + 2] = ADD_INT32( vals[i + 2], cf2_stack_getReal( opStack, + idx++ ) ); } if ( isHFlex ) @@ -356,31 +359,34 @@ if ( doConditionalLastRead ) { - FT_Bool lastIsX = (FT_Bool)( cf2_fixedAbs( vals[10] - *curX ) > - cf2_fixedAbs( vals[11] - *curY ) ); + FT_Bool lastIsX = (FT_Bool)( + cf2_fixedAbs( SUB_INT32( vals[10], *curX ) ) > + cf2_fixedAbs( SUB_INT32( vals[11], *curY ) ) ); CF2_Fixed lastVal = cf2_stack_getReal( opStack, idx ); if ( lastIsX ) { - vals[12] = vals[10] + lastVal; + vals[12] = ADD_INT32( vals[10], lastVal ); vals[13] = *curY; } else { vals[12] = *curX; - vals[13] = vals[11] + lastVal; + vals[13] = ADD_INT32( vals[11], lastVal ); } } else { if ( readFromStack[10] ) - vals[12] = vals[10] + cf2_stack_getReal( opStack, idx++ ); + vals[12] = ADD_INT32( vals[10], + cf2_stack_getReal( opStack, idx++ ) ); else vals[12] = *curX; if ( readFromStack[11] ) - vals[13] = vals[11] + cf2_stack_getReal( opStack, idx ); + vals[13] = ADD_INT32( vals[11], + cf2_stack_getReal( opStack, idx ) ); else vals[13] = *curY; } @@ -426,7 +432,10 @@ for ( j = 1; j < blend->lenBV; j++ ) - sum += FT_MulFix( *weight++, cf2_stack_getReal( opStack, delta++ ) ); + sum = ADD_INT32( sum, + FT_MulFix( *weight++, + cf2_stack_getReal( opStack, + delta++ ) ) ); /* store blended result */ cf2_stack_setReal( opStack, i + base, sum ); @@ -759,7 +768,8 @@ FT_TRACE4(( " vmoveto\n" )); if ( cf2_stack_count( opStack ) > 1 && !haveWidth ) - *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX; + *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ), + nominalWidthX ); /* width is defined or default after this */ haveWidth = TRUE; @@ -767,7 +777,7 @@ if ( font->decoder->width_only ) goto exit; - curY += cf2_stack_popFixed( opStack ); + curY = ADD_INT32( curY, cf2_stack_popFixed( opStack ) ); cf2_glyphpath_moveTo( &glyphPath, curX, curY ); @@ -783,8 +793,10 @@ for ( idx = 0; idx < count; idx += 2 ) { - curX += cf2_stack_getReal( opStack, idx + 0 ); - curY += cf2_stack_getReal( opStack, idx + 1 ); + curX = ADD_INT32( curX, cf2_stack_getReal( opStack, + idx + 0 ) ); + curY = ADD_INT32( curY, cf2_stack_getReal( opStack, + idx + 1 ) ); cf2_glyphpath_lineTo( &glyphPath, curX, curY ); } @@ -810,9 +822,9 @@ if ( isX ) - curX += v; + curX = ADD_INT32( curX, v ); else - curY += v; + curY = ADD_INT32( curY, v ); isX = !isX; @@ -835,13 +847,15 @@ while ( idx + 6 <= count ) { - CF2_Fixed x1 = cf2_stack_getReal( opStack, idx + 0 ) + curX; - CF2_Fixed y1 = cf2_stack_getReal( opStack, idx + 1 ) + curY; - CF2_Fixed x2 = cf2_stack_getReal( opStack, idx + 2 ) + x1; - CF2_Fixed y2 = cf2_stack_getReal( opStack, idx + 3 ) + y1; - CF2_Fixed x3 = cf2_stack_getReal( opStack, idx + 4 ) + x2; - CF2_Fixed y3 = cf2_stack_getReal( opStack, idx + 5 ) + y2; + CF2_Fixed x1, y1, x2, y2, x3, y3; + + x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX ); + y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), curY ); + x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), x1 ); + y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y1 ); + x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), x2 ); + y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 5 ), y2 ); cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); @@ -852,8 +866,10 @@ if ( op1 == cf2_cmdRCURVELINE ) { - curX += cf2_stack_getReal( opStack, idx + 0 ); - curY += cf2_stack_getReal( opStack, idx + 1 ); + curX = ADD_INT32( curX, cf2_stack_getReal( opStack, + idx + 0 ) ); + curY = ADD_INT32( curY, cf2_stack_getReal( opStack, + idx + 1 ) ); cf2_glyphpath_lineTo( &glyphPath, curX, curY ); } @@ -1129,7 +1145,10 @@ arg = cf2_stack_popFixed( opStack ); - cf2_stack_pushFixed( opStack, FT_ABS( arg ) ); + if ( arg < -CF2_FIXED_MAX ) + cf2_stack_pushFixed( opStack, CF2_FIXED_MAX ); + else + cf2_stack_pushFixed( opStack, FT_ABS( arg ) ); } continue; /* do not clear the stack */ @@ -1144,7 +1163,9 @@ summand2 = cf2_stack_popFixed( opStack ); summand1 = cf2_stack_popFixed( opStack ); - cf2_stack_pushFixed( opStack, summand1 + summand2 ); + cf2_stack_pushFixed( opStack, + ADD_INT32( summand1, + summand2 ) ); } continue; /* do not clear the stack */ @@ -1159,7 +1180,8 @@ subtrahend = cf2_stack_popFixed( opStack ); minuend = cf2_stack_popFixed( opStack ); - cf2_stack_pushFixed( opStack, minuend - subtrahend ); + cf2_stack_pushFixed( opStack, + SUB_INT32( minuend, subtrahend ) ); } continue; /* do not clear the stack */ @@ -1174,7 +1196,8 @@ divisor = cf2_stack_popFixed( opStack ); dividend = cf2_stack_popFixed( opStack ); - cf2_stack_pushFixed( opStack, FT_DivFix( dividend, divisor ) ); + cf2_stack_pushFixed( opStack, + FT_DivFix( dividend, divisor ) ); } continue; /* do not clear the stack */ @@ -1187,7 +1210,10 @@ arg = cf2_stack_popFixed( opStack ); - cf2_stack_pushFixed( opStack, -arg ); + if ( arg < -CF2_FIXED_MAX ) + cf2_stack_pushFixed( opStack, CF2_FIXED_MAX ); + else + cf2_stack_pushFixed( opStack, -arg ); } continue; /* do not clear the stack */ @@ -1257,7 +1283,8 @@ arg2 = cf2_stack_popFixed( opStack ); arg1 = cf2_stack_popFixed( opStack ); - cf2_stack_pushFixed( opStack, cond1 <= cond2 ? arg1 : arg2 ); + cf2_stack_pushFixed( opStack, + cond1 <= cond2 ? arg1 : arg2 ); } continue; /* do not clear the stack */ @@ -1291,7 +1318,8 @@ factor2 = cf2_stack_popFixed( opStack ); factor1 = cf2_stack_popFixed( opStack ); - cf2_stack_pushFixed( opStack, FT_MulFix( factor1, factor2 ) ); + cf2_stack_pushFixed( opStack, + FT_MulFix( factor1, factor2 ) ); } continue; /* do not clear the stack */ @@ -1305,7 +1333,9 @@ arg = cf2_stack_popFixed( opStack ); if ( arg > 0 ) { - FT_Fixed root = arg; + /* use a start value that doesn't make */ + /* the algorithm's addition overflow */ + FT_Fixed root = arg < 10 ? arg : arg >> 1; FT_Fixed new_root; @@ -1369,7 +1399,8 @@ if ( size > 0 ) { - /* for `cf2_stack_getReal', index 0 is bottom of stack */ + /* for `cf2_stack_getReal', */ + /* index 0 is bottom of stack */ CF2_UInt gr_idx; @@ -1381,7 +1412,8 @@ gr_idx = size - 1 - (CF2_UInt)idx; cf2_stack_pushFixed( opStack, - cf2_stack_getReal( opStack, gr_idx ) ); + cf2_stack_getReal( opStack, + gr_idx ) ); } } continue; /* do not clear the stack */ @@ -1416,7 +1448,8 @@ cf2_stack_count( opStack ) == 5 ) { if ( !haveWidth ) - *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX; + *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ), + nominalWidthX ); } /* width is defined or default after this */ @@ -1564,7 +1597,8 @@ FT_TRACE4(( " rmoveto\n" )); if ( cf2_stack_count( opStack ) > 2 && !haveWidth ) - *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX; + *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ), + nominalWidthX ); /* width is defined or default after this */ haveWidth = TRUE; @@ -1572,8 +1606,8 @@ if ( font->decoder->width_only ) goto exit; - curY += cf2_stack_popFixed( opStack ); - curX += cf2_stack_popFixed( opStack ); + curY = ADD_INT32( curY, cf2_stack_popFixed( opStack ) ); + curX = ADD_INT32( curX, cf2_stack_popFixed( opStack ) ); cf2_glyphpath_moveTo( &glyphPath, curX, curY ); @@ -1583,7 +1617,8 @@ FT_TRACE4(( " hmoveto\n" )); if ( cf2_stack_count( opStack ) > 1 && !haveWidth ) - *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX; + *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ), + nominalWidthX ); /* width is defined or default after this */ haveWidth = TRUE; @@ -1591,7 +1626,7 @@ if ( font->decoder->width_only ) goto exit; - curX += cf2_stack_popFixed( opStack ); + curX = ADD_INT32( curX, cf2_stack_popFixed( opStack ) ); cf2_glyphpath_moveTo( &glyphPath, curX, curY ); @@ -1607,8 +1642,10 @@ while ( idx + 6 < count ) { - curX += cf2_stack_getReal( opStack, idx + 0 ); - curY += cf2_stack_getReal( opStack, idx + 1 ); + curX = ADD_INT32( curX, cf2_stack_getReal( opStack, + idx + 0 ) ); + curY = ADD_INT32( curY, cf2_stack_getReal( opStack, + idx + 1 ) ); cf2_glyphpath_lineTo( &glyphPath, curX, curY ); idx += 2; @@ -1616,13 +1653,15 @@ while ( idx < count ) { - CF2_Fixed x1 = cf2_stack_getReal( opStack, idx + 0 ) + curX; - CF2_Fixed y1 = cf2_stack_getReal( opStack, idx + 1 ) + curY; - CF2_Fixed x2 = cf2_stack_getReal( opStack, idx + 2 ) + x1; - CF2_Fixed y2 = cf2_stack_getReal( opStack, idx + 3 ) + y1; - CF2_Fixed x3 = cf2_stack_getReal( opStack, idx + 4 ) + x2; - CF2_Fixed y3 = cf2_stack_getReal( opStack, idx + 5 ) + y2; + CF2_Fixed x1, y1, x2, y2, x3, y3; + + x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX ); + y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), curY ); + x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), x1 ); + y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y1 ); + x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), x2 ); + y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 5 ), y2 ); cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); @@ -1656,18 +1695,18 @@ if ( ( count - idx ) & 1 ) { - x1 = cf2_stack_getReal( opStack, idx ) + curX; + x1 = ADD_INT32( cf2_stack_getReal( opStack, idx ), curX ); idx++; } else x1 = curX; - y1 = cf2_stack_getReal( opStack, idx + 0 ) + curY; - x2 = cf2_stack_getReal( opStack, idx + 1 ) + x1; - y2 = cf2_stack_getReal( opStack, idx + 2 ) + y1; + y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curY ); + x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 ); + y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 ); x3 = x2; - y3 = cf2_stack_getReal( opStack, idx + 3 ) + y2; + y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y2 ); cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); @@ -1701,17 +1740,17 @@ if ( ( count - idx ) & 1 ) { - y1 = cf2_stack_getReal( opStack, idx ) + curY; + y1 = ADD_INT32( cf2_stack_getReal( opStack, idx ), curY ); idx++; } else y1 = curY; - x1 = cf2_stack_getReal( opStack, idx + 0 ) + curX; - x2 = cf2_stack_getReal( opStack, idx + 1 ) + x1; - y2 = cf2_stack_getReal( opStack, idx + 2 ) + y1; - x3 = cf2_stack_getReal( opStack, idx + 3 ) + x2; + x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX ); + x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 ); + y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 ); + x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), x2 ); y3 = y2; cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); @@ -1750,15 +1789,15 @@ if ( alternate ) { - x1 = cf2_stack_getReal( opStack, idx + 0 ) + curX; + x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX ); y1 = curY; - x2 = cf2_stack_getReal( opStack, idx + 1 ) + x1; - y2 = cf2_stack_getReal( opStack, idx + 2 ) + y1; - y3 = cf2_stack_getReal( opStack, idx + 3 ) + y2; + x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 ); + y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 ); + y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y2 ); if ( count - idx == 5 ) { - x3 = cf2_stack_getReal( opStack, idx + 4 ) + x2; + x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), x2 ); idx++; } @@ -1770,14 +1809,14 @@ else { x1 = curX; - y1 = cf2_stack_getReal( opStack, idx + 0 ) + curY; - x2 = cf2_stack_getReal( opStack, idx + 1 ) + x1; - y2 = cf2_stack_getReal( opStack, idx + 2 ) + y1; - x3 = cf2_stack_getReal( opStack, idx + 3 ) + x2; + y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curY ); + x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 ); + y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 ); + x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), x2 ); if ( count - idx == 5 ) { - y3 = cf2_stack_getReal( opStack, idx + 4 ) + y2; + y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), y2 ); idx++; } diff --git a/thirdparty/freetype/src/cff/cffgload.c b/thirdparty/freetype/src/cff/cffgload.c index 940804850e..20f3a2c28e 100644 --- a/thirdparty/freetype/src/cff/cffgload.c +++ b/thirdparty/freetype/src/cff/cffgload.c @@ -20,6 +20,7 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_CALC_H #include FT_OUTLINE_H #include FT_CFF_DRIVER_H @@ -1450,8 +1451,8 @@ cff_builder_close_contour( builder ); builder->path_begun = 0; - x += args[-2]; - y += args[-1]; + x = ADD_LONG( x, args[-2] ); + y = ADD_LONG( y, args[-1] ); args = stack; break; @@ -1460,7 +1461,7 @@ cff_builder_close_contour( builder ); builder->path_begun = 0; - y += args[-1]; + y = ADD_LONG( y, args[-1] ); args = stack; break; @@ -1469,7 +1470,7 @@ cff_builder_close_contour( builder ); builder->path_begun = 0; - x += args[-1]; + x = ADD_LONG( x, args[-1] ); args = stack; break; @@ -1486,8 +1487,8 @@ args -= num_args & ~1; while ( args < decoder->top ) { - x += args[0]; - y += args[1]; + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); cff_builder_add_point( builder, x, y, 1 ); args += 2; } @@ -1519,9 +1520,9 @@ while ( args < decoder->top ) { if ( phase ) - x += args[0]; + x = ADD_LONG( x, args[0] ); else - y += args[0]; + y = ADD_LONG( y, args[0] ); if ( cff_builder_add_point1( builder, x, y ) ) goto Fail; @@ -1552,15 +1553,18 @@ args -= nargs; while ( args < decoder->top ) { - x += args[0]; - y += args[1]; + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); cff_builder_add_point( builder, x, y, 0 ); - x += args[2]; - y += args[3]; + + x = ADD_LONG( x, args[2] ); + y = ADD_LONG( y, args[3] ); cff_builder_add_point( builder, x, y, 0 ); - x += args[4]; - y += args[5]; + + x = ADD_LONG( x, args[4] ); + y = ADD_LONG( y, args[5] ); cff_builder_add_point( builder, x, y, 1 ); + args += 6; } args = stack; @@ -1589,7 +1593,7 @@ if ( nargs & 1 ) { - x += args[0]; + x = ADD_LONG( x, args[0] ); args++; nargs--; } @@ -1599,13 +1603,16 @@ while ( args < decoder->top ) { - y += args[0]; + y = ADD_LONG( y, args[0] ); cff_builder_add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; + + x = ADD_LONG( x, args[1] ); + y = ADD_LONG( y, args[2] ); cff_builder_add_point( builder, x, y, 0 ); - y += args[3]; + + y = ADD_LONG( y, args[3] ); cff_builder_add_point( builder, x, y, 1 ); + args += 4; } args = stack; @@ -1633,7 +1640,7 @@ args -= nargs; if ( nargs & 1 ) { - y += args[0]; + y = ADD_LONG( y, args[0] ); args++; nargs--; } @@ -1643,13 +1650,16 @@ while ( args < decoder->top ) { - x += args[0]; + x = ADD_LONG( x, args[0] ); cff_builder_add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; + + x = ADD_LONG( x, args[1] ); + y = ADD_LONG( y, args[2] ); cff_builder_add_point( builder, x, y, 0 ); - x += args[3]; + + x = ADD_LONG( x, args[3] ); cff_builder_add_point( builder, x, y, 1 ); + args += 4; } args = stack; @@ -1688,26 +1698,30 @@ nargs -= 4; if ( phase ) { - x += args[0]; + x = ADD_LONG( x, args[0] ); cff_builder_add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; + + x = ADD_LONG( x, args[1] ); + y = ADD_LONG( y, args[2] ); cff_builder_add_point( builder, x, y, 0 ); - y += args[3]; + + y = ADD_LONG( y, args[3] ); if ( nargs == 1 ) - x += args[4]; + x = ADD_LONG( x, args[4] ); cff_builder_add_point( builder, x, y, 1 ); } else { - y += args[0]; + y = ADD_LONG( y, args[0] ); cff_builder_add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; + + x = ADD_LONG( x, args[1] ); + y = ADD_LONG( y, args[2] ); cff_builder_add_point( builder, x, y, 0 ); - x += args[3]; + + x = ADD_LONG( x, args[3] ); if ( nargs == 1 ) - y += args[4]; + y = ADD_LONG( y, args[4] ); cff_builder_add_point( builder, x, y, 1 ); } args += 4; @@ -1740,23 +1754,27 @@ /* first, add the line segments */ while ( num_lines > 0 ) { - x += args[0]; - y += args[1]; + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); cff_builder_add_point( builder, x, y, 1 ); + args += 2; num_lines--; } /* then the curve */ - x += args[0]; - y += args[1]; + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); cff_builder_add_point( builder, x, y, 0 ); - x += args[2]; - y += args[3]; + + x = ADD_LONG( x, args[2] ); + y = ADD_LONG( y, args[3] ); cff_builder_add_point( builder, x, y, 0 ); - x += args[4]; - y += args[5]; + + x = ADD_LONG( x, args[4] ); + y = ADD_LONG( y, args[5] ); cff_builder_add_point( builder, x, y, 1 ); + args = stack; } break; @@ -1785,23 +1803,27 @@ /* first, add the curves */ while ( num_curves > 0 ) { - x += args[0]; - y += args[1]; + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); cff_builder_add_point( builder, x, y, 0 ); - x += args[2]; - y += args[3]; + + x = ADD_LONG( x, args[2] ); + y = ADD_LONG( y, args[3] ); cff_builder_add_point( builder, x, y, 0 ); - x += args[4]; - y += args[5]; + + x = ADD_LONG( x, args[4] ); + y = ADD_LONG( y, args[5] ); cff_builder_add_point( builder, x, y, 1 ); + args += 6; num_curves--; } /* then the final line */ - x += args[0]; - y += args[1]; + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); cff_builder_add_point( builder, x, y, 1 ); + args = stack; } break; @@ -1824,33 +1846,33 @@ start_y = y; /* first control point */ - x += args[0]; - y += args[1]; + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); cff_builder_add_point( builder, x, y, 0 ); /* second control point */ - x += args[2]; - y += args[3]; + x = ADD_LONG( x, args[2] ); + y = ADD_LONG( y, args[3] ); cff_builder_add_point( builder, x, y, 0 ); /* join point; on curve, with y-value the same as the last */ /* control point's y-value */ - x += args[4]; + x = ADD_LONG( x, args[4] ); cff_builder_add_point( builder, x, y, 1 ); /* third control point, with y-value the same as the join */ /* point's y-value */ - x += args[5]; + x = ADD_LONG( x, args[5] ); cff_builder_add_point( builder, x, y, 0 ); /* fourth control point */ - x += args[6]; - y += args[7]; + x = ADD_LONG( x, args[6] ); + y = ADD_LONG( y, args[7] ); cff_builder_add_point( builder, x, y, 0 ); /* ending point, with y-value the same as the start */ - x += args[8]; - y = start_y; + x = ADD_LONG( x, args[8] ); + y = start_y; cff_builder_add_point( builder, x, y, 1 ); args = stack; @@ -1873,32 +1895,32 @@ start_y = y; /* first control point */ - x += args[0]; + x = ADD_LONG( x, args[0] ); cff_builder_add_point( builder, x, y, 0 ); /* second control point */ - x += args[1]; - y += args[2]; + x = ADD_LONG( x, args[1] ); + y = ADD_LONG( y, args[2] ); cff_builder_add_point( builder, x, y, 0 ); /* join point; on curve, with y-value the same as the last */ /* control point's y-value */ - x += args[3]; + x = ADD_LONG( x, args[3] ); cff_builder_add_point( builder, x, y, 1 ); /* third control point, with y-value the same as the join */ /* point's y-value */ - x += args[4]; + x = ADD_LONG( x, args[4] ); cff_builder_add_point( builder, x, y, 0 ); /* fourth control point */ - x += args[5]; - y = start_y; + x = ADD_LONG( x, args[5] ); + y = start_y; cff_builder_add_point( builder, x, y, 0 ); /* ending point, with y-value the same as the start point's */ /* y-value -- we don't add this point, though */ - x += args[6]; + x = ADD_LONG( x, args[6] ); cff_builder_add_point( builder, x, y, 1 ); args = stack; @@ -1934,8 +1956,8 @@ /* grab up to the last argument */ for ( count = 5; count > 0; count-- ) { - dx += temp[0]; - dy += temp[1]; + dx = ADD_LONG( dx, temp[0] ); + dy = ADD_LONG( dy, temp[1] ); temp += 2; } @@ -1949,8 +1971,8 @@ for ( count = 5; count > 0; count-- ) { - x += args[0]; - y += args[1]; + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); cff_builder_add_point( builder, x, y, (FT_Bool)( count == 3 ) ); args += 2; @@ -1959,13 +1981,13 @@ /* is last operand an x- or y-delta? */ if ( horizontal ) { - x += args[0]; - y = start_y; + x = ADD_LONG( x, args[0] ); + y = start_y; } else { - x = start_x; - y += args[0]; + x = start_x; + y = ADD_LONG( y, args[0] ); } cff_builder_add_point( builder, x, y, 1 ); @@ -1987,8 +2009,8 @@ for ( count = 6; count > 0; count-- ) { - x += args[0]; - y += args[1]; + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); cff_builder_add_point( builder, x, y, (FT_Bool)( count == 4 || count == 1 ) ); args += 2; @@ -2066,21 +2088,26 @@ FT_TRACE4(( " abs\n" )); if ( args[0] < 0 ) - args[0] = -args[0]; + { + if ( args[0] == FT_LONG_MIN ) + args[0] = FT_LONG_MAX; + else + args[0] = -args[0]; + } args++; break; case cff_op_add: FT_TRACE4(( " add\n" )); - args[0] += args[1]; + args[0] = ADD_LONG( args[0], args[1] ); args++; break; case cff_op_sub: FT_TRACE4(( " sub\n" )); - args[0] -= args[1]; + args[0] = SUB_LONG( args[0], args[1] ); args++; break; @@ -2094,6 +2121,8 @@ case cff_op_neg: FT_TRACE4(( " neg\n" )); + if ( args[0] == FT_LONG_MIN ) + args[0] = FT_LONG_MAX; args[0] = -args[0]; args++; break; @@ -2350,12 +2379,13 @@ FT_TRACE4(( " hsbw (invalid op)\n" )); - decoder->glyph_width = decoder->nominal_width + ( args[1] >> 16 ); + decoder->glyph_width = + ADD_LONG( decoder->nominal_width, ( args[1] >> 16 ) ); decoder->builder.left_bearing.x = args[0]; decoder->builder.left_bearing.y = 0; - x = decoder->builder.pos_x + args[0]; + x = ADD_LONG( decoder->builder.pos_x, args[0] ); y = decoder->builder.pos_y; args = stack; break; @@ -2367,13 +2397,14 @@ FT_TRACE4(( " sbw (invalid op)\n" )); - decoder->glyph_width = decoder->nominal_width + ( args[2] >> 16 ); + decoder->glyph_width = + ADD_LONG( decoder->nominal_width, ( args[2] >> 16 ) ); decoder->builder.left_bearing.x = args[0]; decoder->builder.left_bearing.y = args[1]; - x = decoder->builder.pos_x + args[0]; - y = decoder->builder.pos_y + args[1]; + x = ADD_LONG( decoder->builder.pos_x, args[0] ); + y = ADD_LONG( decoder->builder.pos_y, args[1] ); args = stack; break; @@ -2384,8 +2415,8 @@ FT_TRACE4(( " setcurrentpoint (invalid op)\n" )); - x = decoder->builder.pos_x + args[0]; - y = decoder->builder.pos_y + args[1]; + x = ADD_LONG( decoder->builder.pos_x, args[0] ); + y = ADD_LONG( decoder->builder.pos_y, args[1] ); args = stack; break; diff --git a/thirdparty/freetype/src/cff/cffload.c b/thirdparty/freetype/src/cff/cffload.c index 3beaeb1c8e..12420384af 100644 --- a/thirdparty/freetype/src/cff/cffload.c +++ b/thirdparty/freetype/src/cff/cffload.c @@ -1352,9 +1352,12 @@ 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 ); + sum = ADD_INT32( + 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; diff --git a/thirdparty/freetype/src/cff/cffparse.c b/thirdparty/freetype/src/cff/cffparse.c index e1511bdbd1..9d7bf6d22c 100644 --- a/thirdparty/freetype/src/cff/cffparse.c +++ b/thirdparty/freetype/src/cff/cffparse.c @@ -20,6 +20,7 @@ #include "cffparse.h" #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H #include "cfferrs.h" #include "cffpic.h" @@ -156,6 +157,22 @@ 1000000000L }; + /* maximum values allowed for multiplying */ + /* with the corresponding `power_tens' element */ + static const FT_Long power_ten_limits[] = + { + FT_LONG_MAX / 1L, + FT_LONG_MAX / 10L, + FT_LONG_MAX / 100L, + FT_LONG_MAX / 1000L, + FT_LONG_MAX / 10000L, + FT_LONG_MAX / 100000L, + FT_LONG_MAX / 1000000L, + FT_LONG_MAX / 10000000L, + FT_LONG_MAX / 100000000L, + FT_LONG_MAX / 1000000000L, + }; + /* read a real */ static FT_Fixed @@ -484,7 +501,15 @@ if ( scaling ) + { + if ( FT_ABS( val ) > power_ten_limits[scaling] ) + { + val = val > 0 ? 0x7FFFFFFFL : -0x7FFFFFFFL; + goto Overflow; + } + val *= power_tens[scaling]; + } if ( val > 0x7FFF ) { @@ -1585,7 +1610,7 @@ val = 0; while ( num_args > 0 ) { - val += cff_parse_num( parser, data++ ); + val = ADD_LONG( val, cff_parse_num( parser, data++ ) ); switch ( field->size ) { case (8 / FT_CHAR_BIT): diff --git a/thirdparty/freetype/src/gxvalid/README b/thirdparty/freetype/src/gxvalid/README index 7201459aaf..200f66cb12 100644 --- a/thirdparty/freetype/src/gxvalid/README +++ b/thirdparty/freetype/src/gxvalid/README @@ -9,7 +9,7 @@ gxvalid: TrueType GX validator additional tables in TrueType font which are used by `QuickDraw GX Text', Apple Advanced Typography (AAT). In addition, gxvalid can validates `kern' tables which have been extended for AAT. Like the - otvalid module, gxvalid uses Freetype 2's validator framework + otvalid module, gxvalid uses FreeType 2's validator framework (ftvalid). You can link gxvalid with your program; before running your own layout diff --git a/thirdparty/freetype/src/pcf/README b/thirdparty/freetype/src/pcf/README index 10eff15fbe..09ea970eda 100644 --- a/thirdparty/freetype/src/pcf/README +++ b/thirdparty/freetype/src/pcf/README @@ -41,8 +41,8 @@ value given as argument into the corresponding glyph number. Known problems ************** -- dealing explicitly with encodings breaks the uniformity of freetype2 - api. +- dealing explicitly with encodings breaks the uniformity of FreeType 2 + API. - except for encodings properties, client applications have no visibility of the PCF_Face object. This means that applications diff --git a/thirdparty/freetype/src/pcf/pcfdrivr.c b/thirdparty/freetype/src/pcf/pcfdrivr.c index 9f4d36d111..169f75e950 100644 --- a/thirdparty/freetype/src/pcf/pcfdrivr.c +++ b/thirdparty/freetype/src/pcf/pcfdrivr.c @@ -387,7 +387,11 @@ THE SOFTWARE. if ( !ft_strcmp( s, "10646" ) || ( !ft_strcmp( s, "8859" ) && !ft_strcmp( face->charset_encoding, "1" ) ) ) - unicode_charmap = 1; + unicode_charmap = 1; + /* another name for ASCII */ + else if ( !ft_strcmp( s, "646.1991" ) && + !ft_strcmp( face->charset_encoding, "IRV" ) ) + unicode_charmap = 1; } } @@ -409,12 +413,6 @@ THE SOFTWARE. } error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL ); - -#if 0 - /* Select default charmap */ - if ( pcfface->num_charmaps ) - pcfface->charmap = pcfface->charmaps[0]; -#endif } } diff --git a/thirdparty/freetype/src/pcf/pcfread.c b/thirdparty/freetype/src/pcf/pcfread.c index 3eacf2baf6..da216b05f4 100644 --- a/thirdparty/freetype/src/pcf/pcfread.c +++ b/thirdparty/freetype/src/pcf/pcfread.c @@ -1162,6 +1162,20 @@ THE SOFTWARE. accel->fontDescent, accel->maxOverlap )); + /* sanity checks */ + if ( FT_ABS( accel->fontAscent ) > 0x7FFF ) + { + accel->fontAscent = accel->fontAscent < 0 ? -0x7FFF : 0x7FFF; + FT_TRACE0(( "pfc_get_accel: clamping font ascent to value %d\n", + accel->fontAscent )); + } + if ( FT_ABS( accel->fontDescent ) > 0x7FFF ) + { + accel->fontDescent = accel->fontDescent < 0 ? -0x7FFF : 0x7FFF; + FT_TRACE0(( "pfc_get_accel: clamping font descent to value %d\n", + accel->fontDescent )); + } + FT_TRACE5(( " minbounds:" )); error = pcf_get_metric( stream, format & ( ~PCF_FORMAT_MASK ), @@ -1496,8 +1510,16 @@ THE SOFTWARE. if ( face->accel.fontAscent + face->accel.fontDescent < 0 ) FT_TRACE0(( "pcf_load_font: negative height\n" )); #endif - bsize->height = FT_ABS( (FT_Short)( face->accel.fontAscent + - face->accel.fontDescent ) ); + if ( FT_ABS( face->accel.fontAscent + + face->accel.fontDescent ) > 0x7FFF ) + { + bsize->height = 0x7FFF; + FT_TRACE0(( "pcf_load_font: clamping height to value %d\n", + bsize->height )); + } + else + bsize->height = FT_ABS( (FT_Short)( face->accel.fontAscent + + face->accel.fontDescent ) ); prop = pcf_find_property( face, "AVERAGE_WIDTH" ); if ( prop ) @@ -1506,10 +1528,20 @@ THE SOFTWARE. if ( prop->value.l < 0 ) FT_TRACE0(( "pcf_load_font: negative average width\n" )); #endif - bsize->width = FT_ABS( (FT_Short)( ( prop->value.l ) + 5 ) / 10 ); + if ( ( FT_ABS( prop->value.l ) > 0x7FFFL * 10 - 5 ) ) + { + bsize->width = 0x7FFF; + FT_TRACE0(( "pcf_load_font: clamping average width to value %d\n", + bsize->width )); + } + else + bsize->width = FT_ABS( (FT_Short)( ( prop->value.l + 5 ) / 10 ) ); } else + { + /* this is a heuristical value */ bsize->width = (FT_Short)FT_MulDiv( bsize->height, 2, 3 ); + } prop = pcf_find_property( face, "POINT_SIZE" ); if ( prop ) @@ -1519,9 +1551,16 @@ THE SOFTWARE. FT_TRACE0(( "pcf_load_font: negative point size\n" )); #endif /* convert from 722.7 decipoints to 72 points per inch */ - bsize->size = FT_MulDiv( FT_ABS( prop->value.l ), - 64 * 7200, - 72270L ); + if ( FT_ABS( prop->value.l ) > 0x504C2L ) /* 0x7FFF * 72270/7200 */ + { + bsize->size = 0x7FFF; + FT_TRACE0(( "pcf_load_font: clamping point size to value %d\n", + bsize->size )); + } + else + bsize->size = FT_MulDiv( FT_ABS( prop->value.l ), + 64 * 7200, + 72270L ); } prop = pcf_find_property( face, "PIXEL_SIZE" ); @@ -1531,7 +1570,14 @@ THE SOFTWARE. if ( prop->value.l < 0 ) FT_TRACE0(( "pcf_load_font: negative pixel size\n" )); #endif - bsize->y_ppem = FT_ABS( (FT_Short)prop->value.l ) << 6; + if ( FT_ABS( prop->value.l ) > 0x7FFF ) + { + bsize->y_ppem = 0x7FFF << 6; + FT_TRACE0(( "pcf_load_font: clamping pixel size to value %d\n", + bsize->y_ppem )); + } + else + bsize->y_ppem = FT_ABS( (FT_Short)prop->value.l ) << 6; } prop = pcf_find_property( face, "RESOLUTION_X" ); @@ -1541,7 +1587,14 @@ THE SOFTWARE. if ( prop->value.l < 0 ) FT_TRACE0(( "pcf_load_font: negative X resolution\n" )); #endif - resolution_x = FT_ABS( (FT_Short)prop->value.l ); + if ( FT_ABS( prop->value.l ) > 0x7FFF ) + { + resolution_x = 0x7FFF; + FT_TRACE0(( "pcf_load_font: clamping X resolution to value %d\n", + resolution_x )); + } + else + resolution_x = FT_ABS( (FT_Short)prop->value.l ); } prop = pcf_find_property( face, "RESOLUTION_Y" ); @@ -1551,7 +1604,14 @@ THE SOFTWARE. if ( prop->value.l < 0 ) FT_TRACE0(( "pcf_load_font: negative Y resolution\n" )); #endif - resolution_y = FT_ABS( (FT_Short)prop->value.l ); + if ( FT_ABS( prop->value.l ) > 0x7FFF ) + { + resolution_y = 0x7FFF; + FT_TRACE0(( "pcf_load_font: clamping Y resolution to value %d\n", + resolution_y )); + } + else + resolution_y = FT_ABS( (FT_Short)prop->value.l ); } if ( bsize->y_ppem == 0 ) diff --git a/thirdparty/freetype/src/pfr/pfrobjs.c b/thirdparty/freetype/src/pfr/pfrobjs.c index 4b1703f51c..514af8050d 100644 --- a/thirdparty/freetype/src/pfr/pfrobjs.c +++ b/thirdparty/freetype/src/pfr/pfrobjs.c @@ -264,12 +264,6 @@ charmap.encoding = FT_ENCODING_UNICODE; error = FT_CMap_New( &pfr_cmap_class_rec, NULL, &charmap, NULL ); - -#if 0 - /* select default charmap */ - if ( pfrface->num_charmaps ) - pfrface->charmap = pfrface->charmaps[0]; -#endif } /* check whether we have loaded any kerning pairs */ diff --git a/thirdparty/freetype/src/psaux/psconv.c b/thirdparty/freetype/src/psaux/psconv.c index b092482194..d125b0834a 100644 --- a/thirdparty/freetype/src/psaux/psconv.c +++ b/thirdparty/freetype/src/psaux/psconv.c @@ -111,6 +111,10 @@ p++; if ( p == limit ) goto Bad; + + /* only a single sign is allowed */ + if ( *p == '-' || *p == '+' ) + return 0; } num_limit = 0x7FFFFFFFL / base; @@ -215,6 +219,10 @@ p++; if ( p == limit ) goto Bad; + + /* only a single sign is allowed */ + if ( *p == '-' || *p == '+' ) + return 0; } /* read the integer part */ diff --git a/thirdparty/freetype/src/psaux/t1decode.c b/thirdparty/freetype/src/psaux/t1decode.c index 7dd45135de..1250b53f5d 100644 --- a/thirdparty/freetype/src/psaux/t1decode.c +++ b/thirdparty/freetype/src/psaux/t1decode.c @@ -864,7 +864,9 @@ for ( mm = 1; mm < blend->num_designs; mm++ ) - tmp += FT_MulFix( *delta++, blend->weight_vector[mm] ); + tmp = ADD_LONG( tmp, + FT_MulFix( *delta++, + blend->weight_vector[mm] ) ); *values++ = tmp; } @@ -904,7 +906,7 @@ if ( arg_cnt != 2 ) goto Unexpected_OtherSubr; - top[0] += top[1]; /* XXX (over|under)flow */ + top[0] = ADD_LONG( top[0], top[1] ); known_othersubr_result_cnt = 1; break; @@ -915,7 +917,7 @@ if ( arg_cnt != 2 ) goto Unexpected_OtherSubr; - top[0] -= top[1]; /* XXX (over|under)flow */ + top[0] = SUB_LONG( top[0], top[1] ); known_othersubr_result_cnt = 1; break; @@ -1147,11 +1149,13 @@ builder->parse_state = T1_Parse_Have_Width; - builder->left_bearing.x += top[0]; - builder->advance.x = top[1]; - builder->advance.y = 0; + builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, + top[0] ); - orig_x = x = builder->pos_x + top[0]; + builder->advance.x = top[1]; + builder->advance.y = 0; + + orig_x = x = ADD_LONG( builder->pos_x, top[0] ); orig_y = y = builder->pos_y; FT_UNUSED( orig_y ); @@ -1177,13 +1181,16 @@ builder->parse_state = T1_Parse_Have_Width; - builder->left_bearing.x += top[0]; - builder->left_bearing.y += top[1]; - builder->advance.x = top[2]; - builder->advance.y = top[3]; + builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, + top[0] ); + builder->left_bearing.y = ADD_LONG( builder->left_bearing.y, + top[1] ); + + builder->advance.x = top[2]; + builder->advance.y = top[3]; - x = builder->pos_x + top[0]; - y = builder->pos_y + top[1]; + x = ADD_LONG( builder->pos_x, top[0] ); + y = ADD_LONG( builder->pos_y, top[1] ); /* the `metrics_only' indicates that we only want to compute */ /* the glyph's metrics (lsb + advance width), not load the */ @@ -1210,13 +1217,14 @@ if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) goto Fail; - x += top[0]; + x = ADD_LONG( x, top[0] ); goto Add_Line; case op_hmoveto: FT_TRACE4(( " hmoveto" )); - x += top[0]; + x = ADD_LONG( x, top[0] ); + if ( !decoder->flex_state ) { if ( builder->parse_state == T1_Parse_Start ) @@ -1232,12 +1240,14 @@ FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) goto Fail; - x += top[0]; + x = ADD_LONG( x, top[0] ); t1_builder_add_point( builder, x, y, 0 ); - x += top[1]; - y += top[2]; + + x = ADD_LONG( x, top[1] ); + y = ADD_LONG( y, top[2] ); t1_builder_add_point( builder, x, y, 0 ); - y += top[3]; + + y = ADD_LONG( y, top[3] ); t1_builder_add_point( builder, x, y, 1 ); break; @@ -1247,8 +1257,8 @@ if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) goto Fail; - x += top[0]; - y += top[1]; + x = ADD_LONG( x, top[0] ); + y = ADD_LONG( y, top[1] ); Add_Line: if ( FT_SET_ERROR( t1_builder_add_point1( builder, x, y ) ) ) @@ -1258,8 +1268,9 @@ case op_rmoveto: FT_TRACE4(( " rmoveto" )); - x += top[0]; - y += top[1]; + x = ADD_LONG( x, top[0] ); + y = ADD_LONG( y, top[1] ); + if ( !decoder->flex_state ) { if ( builder->parse_state == T1_Parse_Start ) @@ -1275,16 +1286,16 @@ FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) goto Fail; - x += top[0]; - y += top[1]; + x = ADD_LONG( x, top[0] ); + y = ADD_LONG( y, top[1] ); t1_builder_add_point( builder, x, y, 0 ); - x += top[2]; - y += top[3]; + x = ADD_LONG( x, top[2] ); + y = ADD_LONG( y, top[3] ); t1_builder_add_point( builder, x, y, 0 ); - x += top[4]; - y += top[5]; + x = ADD_LONG( x, top[4] ); + y = ADD_LONG( y, top[5] ); t1_builder_add_point( builder, x, y, 1 ); break; @@ -1295,12 +1306,14 @@ FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) goto Fail; - y += top[0]; + y = ADD_LONG( y, top[0] ); t1_builder_add_point( builder, x, y, 0 ); - x += top[1]; - y += top[2]; + + x = ADD_LONG( x, top[1] ); + y = ADD_LONG( y, top[2] ); t1_builder_add_point( builder, x, y, 0 ); - x += top[3]; + + x = ADD_LONG( x, top[3] ); t1_builder_add_point( builder, x, y, 1 ); break; @@ -1310,13 +1323,14 @@ if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) goto Fail; - y += top[0]; + y = ADD_LONG( y, top[0] ); goto Add_Line; case op_vmoveto: FT_TRACE4(( " vmoveto" )); - y += top[0]; + y = ADD_LONG( y, top[0] ); + if ( !decoder->flex_state ) { if ( builder->parse_state == T1_Parse_Start ) @@ -1473,7 +1487,7 @@ /* record vertical hint */ if ( hinter ) { - top[0] += orig_x; + top[0] = ADD_LONG( top[0], orig_x ); hinter->stem( hinter->hints, 0, top ); } break; @@ -1487,9 +1501,9 @@ FT_Pos dx = orig_x; - top[0] += dx; - top[2] += dx; - top[4] += dx; + top[0] = ADD_LONG( top[0], dx ); + top[2] = ADD_LONG( top[2], dx ); + top[4] = ADD_LONG( top[4], dx ); hinter->stem3( hinter->hints, 0, top ); } break; diff --git a/thirdparty/freetype/src/psnames/psmodule.c b/thirdparty/freetype/src/psnames/psmodule.c index 3ff8cb911b..44ba9ec6ab 100644 --- a/thirdparty/freetype/src/psnames/psmodule.c +++ b/thirdparty/freetype/src/psnames/psmodule.c @@ -23,8 +23,21 @@ #include "psmodule.h" + /* + * The file `pstables.h' with its arrays and its function + * `ft_get_adobe_glyph_index' is useful for other projects also (for + * example, `pdfium' is using it). However, if used as a C++ header, + * including it in two different source files makes it necessary to use + * `extern const' for the declaration of its arrays, otherwise the data + * would be duplicated as mandated by the C++ standard. + * + * For this reason, we use `DEFINE_PS_TABLES' to guard the function + * definitions, and `DEFINE_PS_TABLES_DATA' to provide both proper array + * declarations and definitions. + */ #include "pstables.h" #define DEFINE_PS_TABLES +#define DEFINE_PS_TABLES_DATA #include "pstables.h" #include "psnamerr.h" diff --git a/thirdparty/freetype/src/psnames/pstables.h b/thirdparty/freetype/src/psnames/pstables.h index e0f5e30804..2a2b717d8f 100644 --- a/thirdparty/freetype/src/psnames/pstables.h +++ b/thirdparty/freetype/src/psnames/pstables.h @@ -19,7 +19,7 @@ /* This file has been generated automatically -- do not edit! */ -#ifndef DEFINE_PS_TABLES +#ifndef DEFINE_PS_TABLES_DATA #ifdef __cplusplus extern "C" #else @@ -27,7 +27,7 @@ #endif #endif const char ft_standard_glyph_names[3696] -#ifdef DEFINE_PS_TABLES +#ifdef DEFINE_PS_TABLES_DATA = { '.','n','u','l','l', 0, @@ -451,7 +451,7 @@ 'R','o','m','a','n', 0, 'S','e','m','i','b','o','l','d', 0, } -#endif /* DEFINE_PS_TABLES */ +#endif /* DEFINE_PS_TABLES_DATA */ ; @@ -459,7 +459,7 @@ /* Values are offsets into the `ft_standard_glyph_names' table */ -#ifndef DEFINE_PS_TABLES +#ifndef DEFINE_PS_TABLES_DATA #ifdef __cplusplus extern "C" #else @@ -467,7 +467,7 @@ #endif #endif const short ft_mac_names[FT_NUM_MAC_NAMES] -#ifdef DEFINE_PS_TABLES +#ifdef DEFINE_PS_TABLES_DATA = { 253, 0, 6, 261, 267, 274, 283, 294, 301, 309, 758, 330, 340, 351, @@ -490,7 +490,7 @@ 1270,1313,1323,1171,1290,1332,1211,1235,1276, 169, 175, 182, 189, 200, 209, 218, 225, 232, 239, 246 } -#endif /* DEFINE_PS_TABLES */ +#endif /* DEFINE_PS_TABLES_DATA */ ; @@ -498,7 +498,7 @@ /* Values are offsets into the `ft_standard_glyph_names' table */ -#ifndef DEFINE_PS_TABLES +#ifndef DEFINE_PS_TABLES_DATA #ifdef __cplusplus extern "C" #else @@ -506,7 +506,7 @@ #endif #endif const short ft_sid_names[FT_NUM_SID_NAMES] -#ifdef DEFINE_PS_TABLES +#ifdef DEFINE_PS_TABLES_DATA = { 253, 261, 267, 274, 283, 294, 301, 309, 319, 330, 340, 351, 360, 365, @@ -538,12 +538,12 @@ 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 */ +#endif /* DEFINE_PS_TABLES_DATA */ ; /* the following are indices into the SID name table */ -#ifndef DEFINE_PS_TABLES +#ifndef DEFINE_PS_TABLES_DATA #ifdef __cplusplus extern "C" #else @@ -551,7 +551,7 @@ #endif #endif const unsigned short t1_standard_encoding[256] -#ifdef DEFINE_PS_TABLES +#ifdef DEFINE_PS_TABLES_DATA = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -571,12 +571,12 @@ 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 */ +#endif /* DEFINE_PS_TABLES_DATA */ ; /* the following are indices into the SID name table */ -#ifndef DEFINE_PS_TABLES +#ifndef DEFINE_PS_TABLES_DATA #ifdef __cplusplus extern "C" #else @@ -584,7 +584,7 @@ #endif #endif const unsigned short t1_expert_encoding[256] -#ifdef DEFINE_PS_TABLES +#ifdef DEFINE_PS_TABLES_DATA = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -604,7 +604,7 @@ 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 */ +#endif /* DEFINE_PS_TABLES_DATA */ ; @@ -619,7 +619,7 @@ #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST -#ifndef DEFINE_PS_TABLES +#ifndef DEFINE_PS_TABLES_DATA #ifdef __cplusplus extern "C" #else @@ -627,7 +627,7 @@ #endif #endif const unsigned char ft_adobe_glyph_list[55997L] -#ifdef DEFINE_PS_TABLES +#ifdef DEFINE_PS_TABLES_DATA = { 0, 52, 0,106, 2,167, 3, 63, 4,220, 6,125, 9,143, 10, 23, @@ -4131,7 +4131,7 @@ 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 */ +#endif /* DEFINE_PS_TABLES_DATA */ ; diff --git a/thirdparty/freetype/src/raster/ftrend1.c b/thirdparty/freetype/src/raster/ftrend1.c index 1a83e9e477..185a7f6fc2 100644 --- a/thirdparty/freetype/src/raster/ftrend1.c +++ b/thirdparty/freetype/src/raster/ftrend1.c @@ -31,12 +31,7 @@ static FT_Error ft_raster1_init( FT_Renderer render ) { - FT_Library library = FT_MODULE_LIBRARY( render ); - - - render->clazz->raster_class->raster_reset( render->raster, - library->raster_pool, - library->raster_pool_size ); + render->clazz->raster_class->raster_reset( render->raster, NULL, 0 ); return FT_Err_Ok; } @@ -194,7 +189,7 @@ bitmap->rows = height; bitmap->pitch = (int)pitch; - if ( FT_ALLOC_MULT( bitmap->buffer, pitch, height ) ) + if ( FT_ALLOC_MULT( bitmap->buffer, height, pitch ) ) goto Exit; slot->internal->flags |= FT_GLYPH_OWN_BITMAP; diff --git a/thirdparty/freetype/src/sfnt/pngshim.c b/thirdparty/freetype/src/sfnt/pngshim.c index b9b296ea5f..560db4835a 100644 --- a/thirdparty/freetype/src/sfnt/pngshim.c +++ b/thirdparty/freetype/src/sfnt/pngshim.c @@ -49,18 +49,82 @@ } - /* Premultiplies data and converts RGBA bytes => native endian. */ + /* Premultiplies data and converts RGBA bytes => BGRA. */ static void premultiply_data( png_structp png, png_row_infop row_info, png_bytep data ) { - unsigned int i; + unsigned int i = 0, limit; + + /* The `vector_size' attribute was introduced in gcc 3.1, which */ + /* predates clang; the `__BYTE_ORDER__' preprocessor symbol was */ + /* introduced in gcc 4.6 and clang 3.2, respectively. */ + /* `__builtin_shuffle' for gcc was introduced in gcc 4.7.0. */ +#if ( ( defined( __GNUC__ ) && \ + ( ( __GNUC__ >= 5 ) || \ + ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 7 ) ) ) ) || \ + ( defined( __clang__ ) && \ + ( ( __clang_major__ >= 4 ) || \ + ( ( __clang_major__ == 3 ) && ( __clang_minor__ >= 2 ) ) ) ) ) && \ + defined( __OPTIMIZE__ ) && \ + __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + +#ifdef __clang__ + /* the clang documentation doesn't cover the two-argument case of */ + /* `__builtin_shufflevector'; however, it is is implemented since */ + /* version 2.8 */ +#define vector_shuffle __builtin_shufflevector +#else +#define vector_shuffle __builtin_shuffle +#endif - FT_UNUSED( png ); + typedef unsigned short v82 __attribute__(( vector_size( 16 ) )); - for ( i = 0; i < row_info->rowbytes; i += 4 ) + /* process blocks of 16 bytes in one rush, which gives a nice speed-up */ + limit = row_info->rowbytes - 16 + 1; + for ( ; i < limit; i += 16 ) + { + unsigned char* base = &data[i]; + + v82 s, s0, s1, a; + + /* clang <= 3.9 can't apply scalar values to vectors */ + /* (or rather, it needs a different syntax) */ + v82 n0x80 = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }; + v82 n0xFF = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + v82 n8 = { 8, 8, 8, 8, 8, 8, 8, 8 }; + + v82 ma = { 1, 1, 3, 3, 5, 5, 7, 7 }; + v82 o1 = { 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF }; + v82 m0 = { 1, 0, 3, 2, 5, 4, 7, 6 }; + + + memcpy( &s, base, 16 ); /* RGBA RGBA RGBA RGBA */ + s0 = s & n0xFF; /* R B R B R B R B */ + s1 = s >> n8; /* G A G A G A G A */ + + a = vector_shuffle( s1, ma ); /* A A A A A A A A */ + s1 |= o1; /* G 1 G 1 G 1 G 1 */ + s0 = vector_shuffle( s0, m0 ); /* B R B R B R B R */ + + s0 *= a; + s1 *= a; + s0 += n0x80; + s1 += n0x80; + s0 = ( s0 + ( s0 >> n8 ) ) >> n8; + s1 = ( s1 + ( s1 >> n8 ) ) >> n8; + + s = s0 | ( s1 << n8 ); + memcpy( base, &s, 16 ); + } +#endif /* use `vector_size' */ + + FT_UNUSED( png ); + + limit = row_info->rowbytes; + for ( ; i < limit; i += 4 ) { unsigned char* base = &data[i]; unsigned int alpha = base[3]; diff --git a/thirdparty/freetype/src/sfnt/sfobjs.c b/thirdparty/freetype/src/sfnt/sfobjs.c index ac2e620e5d..69bf0a5c3d 100644 --- a/thirdparty/freetype/src/sfnt/sfobjs.c +++ b/thirdparty/freetype/src/sfnt/sfobjs.c @@ -787,6 +787,8 @@ tag != TTAG_OTTO && tag != TTAG_true && tag != TTAG_typ1 && + tag != TTAG_0xA5kbd && + tag != TTAG_0xA5lst && tag != 0x00020000UL ) { FT_TRACE2(( " not a font using the SFNT container format\n" )); @@ -1224,7 +1226,10 @@ goto Exit; } - if ( face->header.Units_Per_EM == 0 ) + /* OpenType 1.8.2 introduced limits to this value; */ + /* however, they make sense for older SFNT fonts also */ + if ( face->header.Units_Per_EM < 16 || + face->header.Units_Per_EM > 16384 ) { error = FT_THROW( Invalid_Table ); @@ -1464,7 +1469,8 @@ /* Polish the charmaps. */ /* */ /* Try to set the charmap encoding according to the platform & */ - /* encoding ID of each charmap. */ + /* encoding ID of each charmap. Emulate Unicode charmap if one */ + /* is missing. */ /* */ tt_face_build_cmaps( face ); /* ignore errors */ @@ -1472,7 +1478,10 @@ /* set the encoding fields */ { - FT_Int m; + FT_Int m; +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + FT_Bool has_unicode = FALSE; +#endif for ( m = 0; m < root->num_charmaps; m++ ) @@ -1483,14 +1492,34 @@ charmap->encoding = sfnt_find_encoding( charmap->platform_id, charmap->encoding_id ); -#if 0 - if ( !root->charmap && - charmap->encoding == FT_ENCODING_UNICODE ) - { - /* set 'root->charmap' to the first Unicode encoding we find */ - root->charmap = charmap; - } -#endif +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + if ( charmap->encoding == FT_ENCODING_UNICODE || + charmap->encoding == FT_ENCODING_MS_SYMBOL ) /* PUA */ + has_unicode = TRUE; + } + + /* synthesize Unicode charmap if one is missing */ + if ( !has_unicode ) + { + FT_CharMapRec cmaprec; + + + cmaprec.face = root; + cmaprec.platform_id = TT_PLATFORM_MICROSOFT; + cmaprec.encoding_id = TT_MS_ID_UNICODE_CS; + cmaprec.encoding = FT_ENCODING_UNICODE; + + + error = FT_CMap_New( (FT_CMap_Class)&tt_cmap_unicode_class_rec, + NULL, &cmaprec, NULL ); + if ( error && + FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) ) + goto Exit; + error = FT_Err_Ok; + +#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + } } diff --git a/thirdparty/freetype/src/sfnt/ttcmap.c b/thirdparty/freetype/src/sfnt/ttcmap.c index 5afa6ae4b7..b995e5c050 100644 --- a/thirdparty/freetype/src/sfnt/ttcmap.c +++ b/thirdparty/freetype/src/sfnt/ttcmap.c @@ -23,8 +23,10 @@ #include FT_INTERNAL_VALIDATE_H #include FT_INTERNAL_STREAM_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H #include "ttload.h" #include "ttcmap.h" +#include "ttpost.h" #include "sfntpic.h" @@ -3622,6 +3624,110 @@ #endif /* TT_CONFIG_CMAP_FORMAT_14 */ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SYNTHETIC UNICODE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* This charmap is generated using postscript glyph names. */ + +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + FT_CALLBACK_DEF( const char * ) + tt_get_glyph_name( TT_Face face, + FT_UInt idx ) + { + FT_String* PSname; + + + tt_face_get_ps_name( face, idx, &PSname ); + + return PSname; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap_unicode_init( PS_Unicodes unicodes, + FT_Pointer pointer ) + { + TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + + FT_UNUSED( pointer ); + + + return psnames->unicodes_init( memory, + unicodes, + face->root.num_glyphs, + (PS_GetGlyphNameFunc)&tt_get_glyph_name, + (PS_FreeGlyphNameFunc)NULL, + (FT_Pointer)face ); + } + + + FT_CALLBACK_DEF( void ) + tt_cmap_unicode_done( PS_Unicodes unicodes ) + { + FT_Face face = FT_CMAP_FACE( unicodes ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( unicodes->maps ); + unicodes->num_maps = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap_unicode_char_index( PS_Unicodes unicodes, + FT_UInt32 char_code ) + { + TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + + + return psnames->unicodes_char_index( unicodes, char_code ); + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap_unicode_char_next( PS_Unicodes unicodes, + FT_UInt32 *pchar_code ) + { + TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + + + return psnames->unicodes_char_next( unicodes, pchar_code ); + } + + + FT_DEFINE_TT_CMAP( + tt_cmap_unicode_class_rec, + + sizeof ( PS_UnicodesRec ), + + (FT_CMap_InitFunc) tt_cmap_unicode_init, /* init */ + (FT_CMap_DoneFunc) tt_cmap_unicode_done, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap_unicode_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap_unicode_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 */ + + ~0U, + (TT_CMap_ValidateFunc)NULL, /* validate */ + (TT_CMap_Info_GetFunc)NULL /* get_cmap_info */ + ) + +#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + #ifndef FT_CONFIG_OPTION_PIC static const TT_CMap_Class tt_cmap_classes[] = @@ -3801,8 +3907,10 @@ FT_CMap cmap = (FT_CMap)charmap; TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz; - - return clazz->get_cmap_info( charmap, cmap_info ); + if ( clazz->get_cmap_info ) + return clazz->get_cmap_info( charmap, cmap_info ); + else + return FT_THROW( Invalid_CharMap_Format ); } diff --git a/thirdparty/freetype/src/sfnt/ttcmap.h b/thirdparty/freetype/src/sfnt/ttcmap.h index 83f12df241..f7de0437b0 100644 --- a/thirdparty/freetype/src/sfnt/ttcmap.h +++ b/thirdparty/freetype/src/sfnt/ttcmap.h @@ -141,6 +141,8 @@ FT_BEGIN_HEADER #define TT_VALID_GLYPH_COUNT( x ) TT_VALIDATOR( x )->num_glyphs + FT_CALLBACK_TABLE const TT_CMap_ClassRec tt_cmap_unicode_class_rec; + FT_LOCAL( FT_Error ) tt_face_build_cmaps( TT_Face face ); diff --git a/thirdparty/freetype/src/sfnt/ttkern.c b/thirdparty/freetype/src/sfnt/ttkern.c index c97e5789ac..53d2436ae5 100644 --- a/thirdparty/freetype/src/sfnt/ttkern.c +++ b/thirdparty/freetype/src/sfnt/ttkern.c @@ -85,7 +85,7 @@ for ( nn = 0; nn < num_tables; nn++ ) { - FT_UInt num_pairs, length, coverage; + FT_UInt num_pairs, length, coverage, format; FT_Byte* p_next; FT_UInt32 mask = (FT_UInt32)1UL << nn; @@ -107,6 +107,12 @@ if ( p_next > p_limit ) /* handle broken table */ p_next = p_limit; + format = coverage >> 8; + + /* we currently only support format 0 kerning tables */ + if ( format != 0 ) + goto NextTable; + /* only use horizontal kerning tables */ if ( ( coverage & 3U ) != 0x0001 || p + 8 > p_next ) diff --git a/thirdparty/freetype/src/sfnt/ttpost.c b/thirdparty/freetype/src/sfnt/ttpost.c index 540d5f2546..69929c8d45 100644 --- a/thirdparty/freetype/src/sfnt/ttpost.c +++ b/thirdparty/freetype/src/sfnt/ttpost.c @@ -325,7 +325,6 @@ FT_UNUSED( post_limit ); - /* UNDOCUMENTED! This value appears only in the Apple TT specs. */ if ( FT_READ_USHORT( num_glyphs ) ) goto Exit; @@ -408,7 +407,7 @@ /* now read postscript table */ if ( format == 0x00020000L ) error = load_format_20( face, stream, post_limit ); - else if ( format == 0x00028000L ) + else if ( format == 0x00025000L ) error = load_format_25( face, stream, post_limit ); else error = FT_THROW( Invalid_File_Format ); @@ -447,7 +446,7 @@ FT_FREE( table->glyph_names ); table->num_names = 0; } - else if ( format == 0x00028000L ) + else if ( format == 0x00025000L ) { TT_Post_25 table = &names->names.format_25; @@ -543,7 +542,7 @@ *PSname = (FT_String*)table->glyph_names[name_index - 258]; } } - else if ( format == 0x00028000L ) + else if ( format == 0x00025000L ) { TT_Post_25 table = &names->names.format_25; diff --git a/thirdparty/freetype/src/sfnt/ttsbit.c b/thirdparty/freetype/src/sfnt/ttsbit.c index 0c76a55779..f41847b0af 100644 --- a/thirdparty/freetype/src/sfnt/ttsbit.c +++ b/thirdparty/freetype/src/sfnt/ttsbit.c @@ -448,6 +448,15 @@ metrics->max_advance = FT_MulDiv( hori->advance_Width_Max, ppem_ * 64, upem ); + /* set the scale values (in 16.16 units) so advances */ + /* from the hmtx and vmtx table are scaled correctly */ + metrics->x_scale = FT_MulDiv( metrics->x_ppem, + 64 * 0x10000, + face->header.Units_Per_EM ); + metrics->y_scale = FT_MulDiv( metrics->y_ppem, + 64 * 0x10000, + face->header.Units_Per_EM ); + return error; } @@ -1439,10 +1448,17 @@ return FT_THROW( Invalid_Table ); NoBitmap: + if ( recurse_count ) + { + FT_TRACE4(( "tt_sbit_decoder_load_image:" + " missing subglyph sbit with glyph index %d\n", + glyph_index )); + return FT_THROW( Invalid_Composite ); + } + FT_TRACE4(( "tt_sbit_decoder_load_image:" " no sbit found for glyph index %d\n", glyph_index )); - - return FT_THROW( Invalid_Argument ); + return FT_THROW( Missing_Bitmap ); } diff --git a/thirdparty/freetype/src/smooth/ftgrays.c b/thirdparty/freetype/src/smooth/ftgrays.c index e9a3ce7a7c..df645e66c9 100644 --- a/thirdparty/freetype/src/smooth/ftgrays.c +++ b/thirdparty/freetype/src/smooth/ftgrays.c @@ -141,6 +141,16 @@ #define FT_INT_MAX INT_MAX #define FT_ULONG_MAX ULONG_MAX +#define ADD_LONG( a, b ) \ + (long)( (unsigned long)(a) + (unsigned long)(b) ) +#define SUB_LONG( a, b ) \ + (long)( (unsigned long)(a) - (unsigned long)(b) ) +#define MUL_LONG( a, b ) \ + (long)( (unsigned long)(a) * (unsigned long)(b) ) +#define NEG_LONG( a ) \ + (long)( -(unsigned long)(a) ) + + #define ft_memset memset #define ft_setjmp setjmp @@ -264,6 +274,7 @@ typedef ptrdiff_t FT_PtrDist; #include "ftgrays.h" #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H #include FT_OUTLINE_H #include "ftsmerrs.h" @@ -1135,7 +1146,7 @@ typedef ptrdiff_t FT_PtrDist; /* 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 = FT_ABS( SUB_LONG( MUL_LONG( dy, dx1 ), MUL_LONG( dx, dy1 ) ) ); if ( s > s_limit ) goto Split; @@ -1143,7 +1154,7 @@ typedef ptrdiff_t FT_PtrDist; /* 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 ); + s = FT_ABS( SUB_LONG( MUL_LONG( dy, dx2 ), MUL_LONG( dx, dy2 ) ) ); if ( s > s_limit ) goto Split; diff --git a/thirdparty/freetype/src/smooth/ftsmooth.c b/thirdparty/freetype/src/smooth/ftsmooth.c index 435854e673..963435de15 100644 --- a/thirdparty/freetype/src/smooth/ftsmooth.c +++ b/thirdparty/freetype/src/smooth/ftsmooth.c @@ -31,12 +31,7 @@ static FT_Error ft_smooth_init( FT_Renderer render ) { - FT_Library library = FT_MODULE_LIBRARY( render ); - - - render->clazz->raster_class->raster_reset( render->raster, - library->raster_pool, - library->raster_pool_size ); + render->clazz->raster_class->raster_reset( render->raster, NULL, 0 ); return 0; } @@ -111,9 +106,6 @@ FT_Pos y_shift = 0; FT_Pos x_left, y_top; FT_Pos width, height, pitch; -#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 ); @@ -124,7 +116,6 @@ #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - FT_Int lcd_extra = 0; FT_LcdFiveTapFilter lcd_weights = { 0 }; FT_Bool have_custom_weight = FALSE; FT_Bitmap_LcdFilterFunc lcd_filter_func = NULL; @@ -152,13 +143,12 @@ { /* * A per-font filter is set. It always uses the default 5-tap - * in-place FIR filter that needs 2 extra pixels. + * in-place FIR filter. */ ft_memcpy( lcd_weights, slot->face->internal->lcd_weights, FT_LCD_FILTER_FIVE_TAPS ); lcd_filter_func = ft_lcd_filter_fir; - lcd_extra = 2; } else { @@ -172,7 +162,6 @@ slot->library->lcd_weights, FT_LCD_FILTER_FIVE_TAPS ); lcd_filter_func = slot->library->lcd_filter_func; - lcd_extra = slot->library->lcd_extra; } #endif /*FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ @@ -201,6 +190,45 @@ /* taking into account the origin shift */ FT_Outline_Get_CBox( outline, &cbox ); +#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + + /* add minimal padding for LCD rendering */ + if ( hmul ) + { + cbox.xMax += 21; + cbox.xMin -= 21; + } + + if ( vmul ) + { + cbox.yMax += 21; + cbox.yMin -= 21; + } + +#else /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + /* add minimal padding for LCD filter depending on specific weights */ + if ( lcd_filter_func ) + { + if ( hmul ) + { + cbox.xMax += lcd_weights[4] ? 43 + : lcd_weights[3] ? 22 : 0; + cbox.xMin -= lcd_weights[0] ? 43 + : lcd_weights[1] ? 22 : 0; + } + + if ( vmul ) + { + cbox.yMax += lcd_weights[4] ? 43 + : lcd_weights[3] ? 22 : 0; + cbox.yMin -= lcd_weights[0] ? 43 + : lcd_weights[1] ? 22 : 0; + } + } + +#endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + cbox.xMin = FT_PIX_FLOOR( cbox.xMin + x_shift ); cbox.yMin = FT_PIX_FLOOR( cbox.yMin + y_shift ); cbox.xMax = FT_PIX_CEIL( cbox.xMax + x_shift ); @@ -215,11 +243,6 @@ width = (FT_ULong)( cbox.xMax - cbox.xMin ) >> 6; height = (FT_ULong)( cbox.yMax - cbox.yMin ) >> 6; -#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - width_org = width; - height_org = height; -#endif - pitch = width; if ( hmul ) { @@ -230,26 +253,6 @@ if ( vmul ) height *= 3; -#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - if ( lcd_filter_func ) - { - if ( hmul ) - { - x_shift += 64 * ( lcd_extra >> 1 ); - x_left -= lcd_extra >> 1; - width += 3 * lcd_extra; - pitch = FT_PAD_CEIL( width, 4 ); - } - - if ( vmul ) - { - y_shift += 64 * ( lcd_extra >> 1 ); - y_top += lcd_extra >> 1; - height += 3 * lcd_extra; - } - } -#endif - /* * XXX: on 16bit system, we return an error for huge bitmap * to prevent an overflow. @@ -353,57 +356,98 @@ #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - /* render outline into bitmap */ - error = render->raster_render( render->raster, ¶ms ); - if ( error ) - goto Exit; - - /* expand it horizontally */ - if ( hmul ) + if ( hmul ) /* lcd */ { - FT_Byte* line = bitmap->buffer; - FT_UInt hh; + FT_Byte* line; + FT_Byte* temp; + FT_Int i, j; - for ( hh = height_org; hh > 0; hh--, line += pitch ) - { - FT_UInt xx; - FT_Byte* end = line + width; + /* Render 3 separate monochrome bitmaps, shifting the outline */ + /* by 1/3 pixel. */ + width /= 3; + FT_Outline_Translate( outline, 21, 0 ); - for ( xx = width_org; xx > 0; xx-- ) - { - FT_UInt pixel = line[xx-1]; + error = render->raster_render( render->raster, ¶ms ); + if ( error ) + goto Exit; + + FT_Outline_Translate( outline, -21, 0 ); + bitmap->buffer += width; + + error = render->raster_render( render->raster, ¶ms ); + if ( error ) + goto Exit; + + FT_Outline_Translate( outline, -21, 0 ); + bitmap->buffer += width; + error = render->raster_render( render->raster, ¶ms ); + if ( error ) + goto Exit; - end[-3] = (FT_Byte)pixel; - end[-2] = (FT_Byte)pixel; - end[-1] = (FT_Byte)pixel; - end -= 3; + FT_Outline_Translate( outline, 21, 0 ); + bitmap->buffer -= 2 * width; + + /* XXX: Rearrange the bytes according to FT_PIXEL_MODE_LCD. */ + /* XXX: It is more efficient to render every third byte above. */ + + if ( FT_ALLOC( temp, (FT_ULong)pitch ) ) + goto Exit; + + for ( i = 0; i < height; i++ ) + { + line = bitmap->buffer + i * pitch; + for ( j = 0; j < width; j++ ) + { + temp[3 * j ] = line[j]; + temp[3 * j + 1] = line[j + width]; + temp[3 * j + 2] = line[j + width + width]; } + FT_MEM_COPY( line, temp, pitch ); } - } - /* expand it vertically */ - if ( vmul ) + FT_FREE( temp ); + } + else if ( vmul ) /* lcd_v */ { - FT_Byte* read = bitmap->buffer + ( height - height_org ) * pitch; - FT_Byte* write = bitmap->buffer; - FT_UInt hh; + /* Render 3 separate monochrome bitmaps, shifting the outline */ + /* by 1/3 pixel. Triple the pitch to render on each third row. */ + bitmap->pitch *= 3; + bitmap->rows /= 3; + FT_Outline_Translate( outline, 0, 21 ); + bitmap->buffer += 2 * pitch; - for ( hh = height_org; hh > 0; hh-- ) - { - ft_memcpy( write, read, pitch ); - write += pitch; + error = render->raster_render( render->raster, ¶ms ); + if ( error ) + goto Exit; - ft_memcpy( write, read, pitch ); - write += pitch; + FT_Outline_Translate( outline, 0, -21 ); + bitmap->buffer -= pitch; - ft_memcpy( write, read, pitch ); - write += pitch; - read += pitch; - } + error = render->raster_render( render->raster, ¶ms ); + if ( error ) + goto Exit; + + FT_Outline_Translate( outline, 0, -21 ); + bitmap->buffer -= pitch; + + error = render->raster_render( render->raster, ¶ms ); + if ( error ) + goto Exit; + + FT_Outline_Translate( outline, 0, 21 ); + + bitmap->pitch /= 3; + bitmap->rows *= 3; + } + else /* grayscale */ + { + error = render->raster_render( render->raster, ¶ms ); + if ( error ) + goto Exit; } #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ diff --git a/thirdparty/freetype/src/truetype/ttgload.c b/thirdparty/freetype/src/truetype/ttgload.c index b7a844a6c7..5e102c6151 100644 --- a/thirdparty/freetype/src/truetype/ttgload.c +++ b/thirdparty/freetype/src/truetype/ttgload.c @@ -87,7 +87,7 @@ /*************************************************************************/ /* */ /* Return the vertical metrics in font units for a given glyph. */ - /* See macro `TT_LOADER_SET_PP' below for explanations. */ + /* See function `tt_loader_set_pp' below for explanations. */ /* */ FT_LOCAL_DEF( void ) TT_Get_VMetrics( TT_Face face, @@ -825,7 +825,7 @@ /* 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->backward_compatibility ) ) + loader->exec->backward_compatibility ) ) { #endif loader->pp1 = zone->cur[zone->n_points - 4]; @@ -1686,7 +1686,7 @@ /***********************************************************************/ /* otherwise, load a composite! */ - else if ( loader->n_contours == -1 ) + else if ( loader->n_contours < 0 ) { FT_Memory memory = face->root.memory; @@ -1697,6 +1697,9 @@ FT_ListNode node, node2; + /* normalize the `n_contours' value */ + loader->n_contours = -1; + /* * We store the glyph index directly in the `node->data' pointer, * following the glib solution (cf. macro `GUINT_TO_POINTER') with a @@ -1991,12 +1994,6 @@ } } } - else - { - /* invalid composite count (negative but not -1) */ - error = FT_THROW( Invalid_Outline ); - goto Exit; - } /***********************************************************************/ /***********************************************************************/ @@ -2100,8 +2097,8 @@ } /* set glyph dimensions */ - glyph->metrics.width = bbox.xMax - bbox.xMin; - glyph->metrics.height = bbox.yMax - bbox.yMin; + glyph->metrics.width = SUB_LONG( bbox.xMax, bbox.xMin ); + glyph->metrics.height = SUB_LONG( bbox.yMax, bbox.yMin ); /* Now take care of vertical metrics. In the case where there is */ /* no vertical information within the font (relatively common), */ @@ -2137,7 +2134,8 @@ /* table in the font. Otherwise, we use the */ /* values defined in the horizontal header. */ - height = (FT_Short)FT_DivFix( bbox.yMax - bbox.yMin, + height = (FT_Short)FT_DivFix( SUB_LONG( bbox.yMax, + bbox.yMin ), y_scale ); if ( face->os2.version != 0xFFFFU ) advance = (FT_Pos)( face->os2.sTypoAscender - @@ -2339,13 +2337,19 @@ #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 ); + subpixel_hinting_lean = + FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != + FT_RENDER_MODE_MONO ); + grayscale_cleartype = + FT_BOOL( subpixel_hinting_lean && + !( ( load_flags & + FT_LOAD_TARGET_LCD ) || + ( load_flags & + FT_LOAD_TARGET_LCD_V ) ) ); + exec->vertical_lcd_lean = + FT_BOOL( subpixel_hinting_lean && + ( load_flags & + FT_LOAD_TARGET_LCD_V ) ); } else { @@ -2621,7 +2625,64 @@ IS_DEFAULT_INSTANCE ) { error = load_sbit_image( size, glyph, glyph_index, load_flags ); - if ( !error ) + if ( FT_ERR_EQ( error, Missing_Bitmap ) ) + { + /* the bitmap strike is incomplete and misses the requested glyph; */ + /* if we have a bitmap-only font, return an empty glyph */ + if ( !FT_IS_SCALABLE( glyph->face ) ) + { + TT_Face face = (TT_Face)glyph->face; + FT_Short left_bearing = 0, top_bearing = 0; + FT_UShort advance_width = 0, advance_height = 0; + + + /* to return an empty glyph, however, we need metrics data */ + /* from the `hmtx' (or `vmtx') table; the assumption is that */ + /* empty glyphs are missing intentionally, representing */ + /* whitespace - not having at least horizontal metrics is */ + /* thus considered an error */ + if ( !face->horz_metrics_size ) + return error; + + /* we now construct an empty bitmap glyph */ + TT_Get_HMetrics( face, glyph_index, + &left_bearing, + &advance_width ); + TT_Get_VMetrics( face, glyph_index, + 0, + &top_bearing, + &advance_height ); + + glyph->outline.n_points = 0; + glyph->outline.n_contours = 0; + + glyph->metrics.width = 0; + glyph->metrics.height = 0; + + glyph->metrics.horiBearingX = left_bearing; + glyph->metrics.horiBearingY = 0; + glyph->metrics.horiAdvance = advance_width; + + glyph->metrics.vertBearingX = 0; + glyph->metrics.vertBearingY = top_bearing; + glyph->metrics.vertAdvance = advance_height; + + glyph->format = FT_GLYPH_FORMAT_BITMAP; + glyph->bitmap.pixel_mode = FT_PIXEL_MODE_MONO; + + glyph->bitmap_left = 0; + glyph->bitmap_top = 0; + + return FT_Err_Ok; + } + } + else if ( error ) + { + /* return error if font is not scalable */ + if ( !FT_IS_SCALABLE( glyph->face ) ) + return error; + } + else { if ( FT_IS_SCALABLE( glyph->face ) ) { diff --git a/thirdparty/freetype/src/truetype/ttgxvar.c b/thirdparty/freetype/src/truetype/ttgxvar.c index 0cedb6bdfa..49aa53a687 100644 --- a/thirdparty/freetype/src/truetype/ttgxvar.c +++ b/thirdparty/freetype/src/truetype/ttgxvar.c @@ -60,8 +60,11 @@ #define FT_Stream_FTell( stream ) \ (FT_ULong)( (stream)->cursor - (stream)->base ) -#define FT_Stream_SeekSet( stream, off ) \ - ( (stream)->cursor = (stream)->base + (off) ) +#define FT_Stream_SeekSet( stream, off ) \ + (stream)->cursor = \ + ( (off) < (FT_ULong)( (stream)->limit - (stream)->base ) ) \ + ? (stream)->base + (off) \ + : (stream)->limit /*************************************************************************/ @@ -392,14 +395,14 @@ /* some macros we need */ - #define FT_FIXED_ONE ( (FT_Fixed)0x10000 ) +#define FT_FIXED_ONE ( (FT_Fixed)0x10000 ) - #define FT_fdot14ToFixed( x ) \ - ( (FT_Fixed)( (FT_ULong)(x) << 2 ) ) - #define FT_intToFixed( i ) \ - ( (FT_Fixed)( (FT_ULong)(i) << 16 ) ) - #define FT_fixedToInt( x ) \ - ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) +#define FT_fdot14ToFixed( x ) \ + ( (FT_Fixed)( (FT_ULong)(x) << 2 ) ) +#define FT_intToFixed( i ) \ + ( (FT_Fixed)( (FT_ULong)(i) << 16 ) ) +#define FT_fixedToInt( x ) \ + ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) static FT_Error @@ -1953,6 +1956,7 @@ GX_FVar_Head fvar_head; FT_Bool usePsName; FT_UInt num_instances; + FT_UShort* axis_flags; static const FT_Frame_Field fvar_fields[] = { @@ -2038,14 +2042,16 @@ /* in fvar's table of named instances */ num_instances = face->root.style_flags >> 16; - /* cannot overflow 32-bit arithmetic because of the size limits */ - /* used in the `fvar' table validity check in `sfnt_init_face' */ + /* prepare storage area for MM data; this cannot overflow */ + /* 32-bit arithmetic because of the size limits used in the */ + /* `fvar' table validity check in `sfnt_init_face' */ face->blend->mmvar_len = sizeof ( FT_MM_Var ) + + fvar_head.axisCount * sizeof ( FT_UShort ) + fvar_head.axisCount * sizeof ( FT_Var_Axis ) + num_instances * sizeof ( FT_Var_Named_Style ) + num_instances * fvar_head.axisCount * sizeof ( FT_Fixed ) + - 5 * fvar_head.axisCount; + fvar_head.axisCount * 5; if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) goto Exit; @@ -2062,8 +2068,12 @@ /* (or tuples, as called by Apple) */ mmvar->num_namedstyles = num_instances; + + /* alas, no public field in `FT_Var_Axis' for axis flags */ + axis_flags = + (FT_UShort*)&( mmvar[1] ); mmvar->axis = - (FT_Var_Axis*)&( mmvar[1] ); + (FT_Var_Axis*)&( axis_flags[fvar_head.axisCount] ); mmvar->namedstyle = (FT_Var_Named_Style*)&( mmvar->axis[fvar_head.axisCount] ); @@ -2107,6 +2117,8 @@ a->name[3] = (FT_String)( ( a->tag ) & 0xFF ); a->name[4] = '\0'; + *axis_flags = axis_rec.flags; + if ( a->minimum > a->def || a->def > a->maximum ) { @@ -2118,13 +2130,17 @@ a->maximum = a->def; } - FT_TRACE5(( " \"%s\": minimum=%.5f, default=%.5f, maximum=%.5f\n", + FT_TRACE5(( " \"%s\":" + " minimum=%.5f, default=%.5f, maximum=%.5f," + " flags=0x%04X\n", a->name, a->minimum / 65536.0, a->def / 65536.0, - a->maximum / 65536.0 )); + a->maximum / 65536.0, + *axis_flags )); a++; + axis_flags++; } FT_TRACE5(( "\n" )); @@ -2136,8 +2152,16 @@ goto Exit; if ( fvar_head.instanceCount && !face->blend->avar_loaded ) + { + FT_ULong offset = FT_STREAM_POS(); + + ft_var_load_avar( face ); + if ( FT_STREAM_SEEK( offset ) ) + goto Exit; + } + ns = mmvar->namedstyle; nsc = face->blend->normalized_stylecoords; for ( i = 0; i < fvar_head.instanceCount; i++, ns++ ) @@ -2154,8 +2178,11 @@ for ( j = 0; j < fvar_head.axisCount; j++, c++ ) *c = FT_GET_LONG(); + /* valid psid values are 6, [256;32767], and 0xFFFF */ if ( usePsName ) ns->psid = FT_GET_USHORT(); + else + ns->psid = 0xFFFF; ft_var_to_normalized( face, fvar_head.axisCount, @@ -2171,7 +2198,7 @@ SFNT_Service sfnt = (SFNT_Service)face->sfnt; FT_Int found, dummy1, dummy2; - FT_UInt strid = 0xFFFFFFFFUL; + FT_UInt strid = ~0U; /* the default instance is missing in array the */ @@ -2230,13 +2257,15 @@ goto Exit; FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len ); + axis_flags = + (FT_UShort*)&( mmvar[1] ); mmvar->axis = - (FT_Var_Axis*)&( mmvar[1] ); + (FT_Var_Axis*)&( axis_flags[mmvar->num_axis] ); mmvar->namedstyle = (FT_Var_Named_Style*)&( mmvar->axis[mmvar->num_axis] ); + next_coords = (FT_Fixed*)&( mmvar->namedstyle[mmvar->num_namedstyles] ); - for ( n = 0; n < mmvar->num_namedstyles; n++ ) { mmvar->namedstyle[n].coords = next_coords; @@ -2281,7 +2310,10 @@ GX_Blend blend; FT_MM_Var* mmvar; FT_UInt i, j; - FT_Bool is_default_instance = 1; + + FT_Bool is_default_instance = TRUE; + FT_Bool all_design_coords = FALSE; + FT_Memory memory = face->root.memory; enum @@ -2327,7 +2359,7 @@ } if ( coords[i] != 0 ) - is_default_instance = 0; + is_default_instance = FALSE; } FT_TRACE5(( "\n" )); @@ -2340,6 +2372,9 @@ { if ( FT_NEW_ARRAY( blend->coords, mmvar->num_axis ) ) goto Exit; + + /* the first time we have to compute all design coordinates */ + all_design_coords = TRUE; } if ( !blend->normalizedcoords ) @@ -2388,7 +2423,7 @@ if ( set_design_coords ) ft_var_to_design( face, - num_coords, + all_design_coords ? blend->num_axis : num_coords, blend->normalizedcoords, blend->coords ); @@ -2529,6 +2564,14 @@ blend = face->blend; + if ( !blend->coords ) + { + /* select default instance coordinates */ + /* if no instance is selected yet */ + if ( FT_SET_ERROR( tt_set_mm_blend( face, 0, NULL, 1 ) ) ) + return error; + } + nc = num_coords; if ( num_coords > blend->num_axis ) { @@ -2626,7 +2669,7 @@ num_coords * sizeof ( FT_Fixed ) ); a = mmvar->axis + num_coords; - c = coords + num_coords; + c = blend->coords + num_coords; for ( i = num_coords; i < mmvar->num_axis; i++, a++, c++ ) *c = a->def; @@ -2636,7 +2679,7 @@ if ( !face->blend->avar_loaded ) ft_var_load_avar( face ); - ft_var_to_normalized( face, num_coords, coords, normalized ); + ft_var_to_normalized( face, num_coords, blend->coords, normalized ); error = tt_set_mm_blend( face, mmvar->num_axis, normalized, 0 ); @@ -2686,6 +2729,14 @@ blend = face->blend; + if ( !blend->coords ) + { + /* select default instance coordinates */ + /* if no instance is selected yet */ + if ( FT_SET_ERROR( tt_set_mm_blend( face, 0, NULL, 1 ) ) ) + return error; + } + nc = num_coords; if ( num_coords > blend->num_axis ) { diff --git a/thirdparty/freetype/src/truetype/ttinterp.c b/thirdparty/freetype/src/truetype/ttinterp.c index af31408cbf..ddcc839bb3 100644 --- a/thirdparty/freetype/src/truetype/ttinterp.c +++ b/thirdparty/freetype/src/truetype/ttinterp.c @@ -65,11 +65,15 @@ TT_INTERPRETER_VERSION_40 ) #endif -#define PROJECT( v1, v2 ) \ - exc->func_project( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y ) +#define PROJECT( v1, v2 ) \ + exc->func_project( exc, \ + SUB_LONG( (v1)->x, (v2)->x ), \ + SUB_LONG( (v1)->y, (v2)->y ) ) -#define DUALPROJ( v1, v2 ) \ - exc->func_dualproj( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y ) +#define DUALPROJ( v1, v2 ) \ + exc->func_dualproj( exc, \ + SUB_LONG( (v1)->x, (v2)->x ), \ + SUB_LONG( (v1)->y, (v2)->y ) ) #define FAST_PROJECT( v ) \ exc->func_project( exc, (v)->x, (v)->y ) @@ -1676,7 +1680,10 @@ if ( SUBPIXEL_HINTING_INFINALITY && ( !exc->ignore_x_mode || ( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) ) - zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); + zone->cur[point].x = ADD_LONG( zone->cur[point].x, + FT_MulDiv( distance, + v, + exc->F_dot_P ) ); else #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ @@ -1685,12 +1692,18 @@ /* diagonal moves, but only post-IUP. DejaVu tries to adjust */ /* diagonal stems like on `Z' and `z' post-IUP. */ if ( SUBPIXEL_HINTING_MINIMAL && !exc->backward_compatibility ) - zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); + zone->cur[point].x = ADD_LONG( 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->cur[point].x = ADD_LONG( zone->cur[point].x, + FT_MulDiv( distance, + v, + exc->F_dot_P ) ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; } @@ -1705,7 +1718,10 @@ exc->iupx_called && exc->iupy_called ) ) #endif - zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P ); + zone->cur[point].y = ADD_LONG( zone->cur[point].y, + FT_MulDiv( distance, + v, + exc->F_dot_P ) ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } @@ -1741,12 +1757,18 @@ v = exc->GS.freeVector.x; if ( v != 0 ) - zone->org[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); + zone->org[point].x = ADD_LONG( zone->org[point].x, + FT_MulDiv( distance, + v, + exc->F_dot_P ) ); v = exc->GS.freeVector.y; if ( v != 0 ) - zone->org[point].y += FT_MulDiv( distance, v, exc->F_dot_P ); + zone->org[point].y = ADD_LONG( zone->org[point].y, + FT_MulDiv( distance, + v, + exc->F_dot_P ) ); } @@ -1769,18 +1791,18 @@ { #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( SUBPIXEL_HINTING_INFINALITY && !exc->ignore_x_mode ) - zone->cur[point].x += distance; + zone->cur[point].x = ADD_LONG( zone->cur[point].x, distance ); else #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL if ( SUBPIXEL_HINTING_MINIMAL && !exc->backward_compatibility ) - zone->cur[point].x += distance; + zone->cur[point].x = ADD_LONG( zone->cur[point].x, distance ); else #endif if ( NO_SUBPIXEL_HINTING ) - zone->cur[point].x += distance; + zone->cur[point].x = ADD_LONG( zone->cur[point].x, distance ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; } @@ -1799,7 +1821,7 @@ exc->backward_compatibility && exc->iupx_called && exc->iupy_called ) ) #endif - zone->cur[point].y += distance; + zone->cur[point].y = ADD_LONG( zone->cur[point].y, distance ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } @@ -1823,7 +1845,7 @@ { FT_UNUSED( exc ); - zone->org[point].x += distance; + zone->org[point].x = ADD_LONG( zone->org[point].x, distance ); } @@ -1835,7 +1857,7 @@ { FT_UNUSED( exc ); - zone->org[point].y += distance; + zone->org[point].y = ADD_LONG( zone->org[point].y, distance ); } @@ -1873,13 +1895,13 @@ if ( distance >= 0 ) { - val = distance + compensation; + val = ADD_LONG( distance, compensation ); if ( val < 0 ) val = 0; } else { - val = distance - compensation; + val = SUB_LONG( distance, compensation ); if ( val > 0 ) val = 0; } @@ -1915,13 +1937,14 @@ if ( distance >= 0 ) { - val = FT_PIX_ROUND( distance + compensation ); + val = FT_PIX_ROUND_LONG( ADD_LONG( distance, compensation ) ); if ( val < 0 ) val = 0; } else { - val = -FT_PIX_ROUND( compensation - distance ); + val = NEG_LONG( FT_PIX_ROUND_LONG( SUB_LONG( compensation, + distance ) ) ); if ( val > 0 ) val = 0; } @@ -1958,13 +1981,16 @@ if ( distance >= 0 ) { - val = FT_PIX_FLOOR( distance + compensation ) + 32; + val = ADD_LONG( FT_PIX_FLOOR( ADD_LONG( distance, compensation ) ), + 32 ); if ( val < 0 ) val = 32; } else { - val = -( FT_PIX_FLOOR( compensation - distance ) + 32 ); + val = NEG_LONG( ADD_LONG( FT_PIX_FLOOR( SUB_LONG( compensation, + distance ) ), + 32 ) ); if ( val > 0 ) val = -32; } @@ -2001,13 +2027,13 @@ if ( distance >= 0 ) { - val = FT_PIX_FLOOR( distance + compensation ); + val = FT_PIX_FLOOR( ADD_LONG( distance, compensation ) ); if ( val < 0 ) val = 0; } else { - val = -FT_PIX_FLOOR( compensation - distance ); + val = NEG_LONG( FT_PIX_FLOOR( SUB_LONG( compensation, distance ) ) ); if ( val > 0 ) val = 0; } @@ -2044,13 +2070,14 @@ if ( distance >= 0 ) { - val = FT_PIX_CEIL( distance + compensation ); + val = FT_PIX_CEIL_LONG( ADD_LONG( distance, compensation ) ); if ( val < 0 ) val = 0; } else { - val = -FT_PIX_CEIL( compensation - distance ); + val = NEG_LONG( FT_PIX_CEIL_LONG( SUB_LONG( compensation, + distance ) ) ); if ( val > 0 ) val = 0; } @@ -2087,13 +2114,14 @@ if ( distance >= 0 ) { - val = FT_PAD_ROUND( distance + compensation, 32 ); + val = FT_PAD_ROUND_LONG( ADD_LONG( distance, compensation ), 32 ); if ( val < 0 ) val = 0; } else { - val = -FT_PAD_ROUND( compensation - distance, 32 ); + val = NEG_LONG( FT_PAD_ROUND_LONG( SUB_LONG( compensation, distance ), + 32 ) ); if ( val > 0 ) val = 0; } @@ -2134,7 +2162,8 @@ if ( distance >= 0 ) { - val = ( distance - exc->phase + exc->threshold + compensation ) & + val = ADD_LONG( distance, + exc->threshold - exc->phase + compensation ) & -exc->period; val += exc->phase; if ( val < 0 ) @@ -2142,8 +2171,9 @@ } else { - val = -( ( exc->threshold - exc->phase - distance + compensation ) & - -exc->period ); + val = NEG_LONG( SUB_LONG( exc->threshold - exc->phase + compensation, + distance ) & + -exc->period ); val -= exc->phase; if ( val > 0 ) val = -exc->phase; @@ -2183,7 +2213,8 @@ if ( distance >= 0 ) { - val = ( ( distance - exc->phase + exc->threshold + compensation ) / + val = ( ADD_LONG( distance, + exc->threshold - exc->phase + compensation ) / exc->period ) * exc->period; val += exc->phase; if ( val < 0 ) @@ -2191,8 +2222,9 @@ } else { - val = -( ( ( exc->threshold - exc->phase - distance + compensation ) / - exc->period ) * exc->period ); + val = NEG_LONG( ( SUB_LONG( exc->threshold - exc->phase + compensation, + distance ) / + exc->period ) * exc->period ); val -= exc->phase; if ( val > 0 ) val = -exc->phase; @@ -2826,7 +2858,7 @@ static void Ins_ADD( FT_Long* args ) { - args[0] += args[1]; + args[0] = ADD_LONG( args[0], args[1] ); } @@ -2839,7 +2871,7 @@ static void Ins_SUB( FT_Long* args ) { - args[0] -= args[1]; + args[0] = SUB_LONG( args[0], args[1] ); } @@ -2882,7 +2914,8 @@ static void Ins_ABS( FT_Long* args ) { - args[0] = FT_ABS( args[0] ); + if ( args[0] < 0 ) + args[0] = NEG_LONG( args[0] ); } @@ -2895,7 +2928,7 @@ static void Ins_NEG( FT_Long* args ) { - args[0] = -args[0]; + args[0] = NEG_LONG( args[0] ); } @@ -4211,8 +4244,8 @@ p1 = exc->zp1.cur + aIdx2; p2 = exc->zp2.cur + aIdx1; - A = p1->x - p2->x; - B = p1->y - p2->y; + A = SUB_LONG( p1->x, p2->x ); + B = SUB_LONG( p1->y, p2->y ); /* If p1 == p2, SPvTL and SFvTL behave the same as */ /* SPvTCA[X] and SFvTCA[X], respectively. */ @@ -4227,9 +4260,9 @@ if ( ( opcode & 1 ) != 0 ) { - C = B; /* counter clockwise rotation */ - B = A; - A = -C; + C = B; /* counter clockwise rotation */ + B = A; + A = NEG_LONG( C ); } Normalize( A, B, Vec ); @@ -4770,7 +4803,7 @@ K = FAST_PROJECT( &exc->zp2.cur[L] ); - exc->func_move( exc, &exc->zp2, L, args[1] - K ); + exc->func_move( exc, &exc->zp2, L, SUB_LONG( args[1], K ) ); /* UNDOCUMENTED! The MS rasterizer does that with */ /* twilight points (confirmed by Greg Hitchcock) */ @@ -4894,12 +4927,12 @@ } { - FT_Vector* v1 = exc->zp1.org + p2; - FT_Vector* v2 = exc->zp2.org + p1; + FT_Vector* v1 = exc->zp1.org + p2; + FT_Vector* v2 = exc->zp2.org + p1; - A = v1->x - v2->x; - B = v1->y - v2->y; + A = SUB_LONG( v1->x, v2->x ); + B = SUB_LONG( v1->y, v2->y ); /* If v1 == v2, SDPvTL behaves the same as */ /* SVTCA[X], respectively. */ @@ -4915,9 +4948,9 @@ if ( ( opcode & 1 ) != 0 ) { - C = B; /* counter clockwise rotation */ - B = A; - A = -C; + C = B; /* counter clockwise rotation */ + B = A; + A = NEG_LONG( C ); } Normalize( A, B, &exc->GS.dualVector ); @@ -4927,8 +4960,8 @@ FT_Vector* v2 = exc->zp2.cur + p1; - A = v1->x - v2->x; - B = v1->y - v2->y; + A = SUB_LONG( v1->x, v2->x ); + B = SUB_LONG( v1->y, v2->y ); if ( A == 0 && B == 0 ) { @@ -4939,9 +4972,9 @@ if ( ( opcode & 1 ) != 0 ) { - C = B; /* counter clockwise rotation */ - B = A; - A = -C; + C = B; /* counter clockwise rotation */ + B = A; + A = NEG_LONG( C ); } Normalize( A, B, &exc->GS.projVector ); @@ -5392,7 +5425,7 @@ if ( !( SUBPIXEL_HINTING_MINIMAL && exc->backward_compatibility ) ) #endif - exc->zp2.cur[point].x += dx; + exc->zp2.cur[point].x = ADD_LONG( exc->zp2.cur[point].x, dx ); if ( touch ) exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; @@ -5406,7 +5439,7 @@ exc->iupx_called && exc->iupy_called ) ) #endif - exc->zp2.cur[point].y += dy; + exc->zp2.cur[point].y = ADD_LONG( exc->zp2.cur[point].y, dy ); if ( touch ) exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; @@ -5781,14 +5814,17 @@ #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* subpixel hinting - make MSIRP respect CVT cut-in; */ - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 && - FT_ABS( distance - args[1] ) >= control_value_cutin ) + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 && + FT_ABS( SUB_LONG( distance, args[1] ) ) >= control_value_cutin ) distance = args[1]; #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - exc->func_move( exc, &exc->zp1, point, args[1] - distance ); + exc->func_move( exc, + &exc->zp1, + point, + SUB_LONG( args[1], distance ) ); exc->GS.rp1 = exc->GS.rp0; exc->GS.rp2 = point; @@ -6027,8 +6063,10 @@ FT_Vector vec; - vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale ); - vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale ); + vec.x = FT_MulFix( SUB_LONG( vec1->x, vec2->x ), + exc->metrics.x_scale ); + vec.y = FT_MulFix( SUB_LONG( vec1->y, vec2->y ), + exc->metrics.y_scale ); org_dist = FAST_DUALPROJ( &vec ); } @@ -6081,8 +6119,8 @@ } else { - if ( distance > -minimum_distance ) - distance = -minimum_distance; + if ( distance > NEG_LONG( minimum_distance ) ) + distance = NEG_LONG( minimum_distance ); } } @@ -6090,7 +6128,7 @@ org_dist = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 ); - exc->func_move( exc, &exc->zp1, point, distance - org_dist ); + exc->func_move( exc, &exc->zp1, point, SUB_LONG( distance, org_dist ) ); Fail: exc->GS.rp1 = exc->GS.rp0; @@ -6265,8 +6303,8 @@ } else { - if ( distance > -minimum_distance ) - distance = -minimum_distance; + if ( distance > NEG_LONG( minimum_distance ) ) + distance = NEG_LONG( minimum_distance ); } } @@ -6290,7 +6328,10 @@ } #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - exc->func_move( exc, &exc->zp1, point, distance - cur_dist ); + exc->func_move( exc, + &exc->zp1, + point, + SUB_LONG( distance, cur_dist ) ); #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( SUBPIXEL_HINTING_INFINALITY ) @@ -6314,7 +6355,10 @@ } if ( reverse_move ) - exc->func_move( exc, &exc->zp1, point, -( distance - cur_dist ) ); + exc->func_move( exc, + &exc->zp1, + point, + SUB_LONG( cur_dist, distance ) ); } #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ @@ -6380,7 +6424,7 @@ distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 ); - exc->func_move( exc, &exc->zp1, point, -distance ); + exc->func_move( exc, &exc->zp1, point, NEG_LONG( distance ) ); } exc->GS.loop--; @@ -6437,19 +6481,19 @@ /* Cramer's rule */ - dbx = exc->zp0.cur[b1].x - exc->zp0.cur[b0].x; - dby = exc->zp0.cur[b1].y - exc->zp0.cur[b0].y; + dbx = SUB_LONG( exc->zp0.cur[b1].x, exc->zp0.cur[b0].x ); + dby = SUB_LONG( exc->zp0.cur[b1].y, exc->zp0.cur[b0].y ); - dax = exc->zp1.cur[a1].x - exc->zp1.cur[a0].x; - day = exc->zp1.cur[a1].y - exc->zp1.cur[a0].y; + dax = SUB_LONG( exc->zp1.cur[a1].x, exc->zp1.cur[a0].x ); + day = SUB_LONG( exc->zp1.cur[a1].y, exc->zp1.cur[a0].y ); - dx = exc->zp0.cur[b0].x - exc->zp1.cur[a0].x; - dy = exc->zp0.cur[b0].y - exc->zp1.cur[a0].y; + dx = SUB_LONG( exc->zp0.cur[b0].x, exc->zp1.cur[a0].x ); + dy = SUB_LONG( exc->zp0.cur[b0].y, exc->zp1.cur[a0].y ); - discriminant = FT_MulDiv( dax, -dby, 0x40 ) + - FT_MulDiv( day, dbx, 0x40 ); - dotproduct = FT_MulDiv( dax, dbx, 0x40 ) + - FT_MulDiv( day, dby, 0x40 ); + discriminant = ADD_LONG( FT_MulDiv( dax, NEG_LONG( dby ), 0x40 ), + FT_MulDiv( day, dbx, 0x40 ) ); + dotproduct = ADD_LONG( FT_MulDiv( dax, dbx, 0x40 ), + FT_MulDiv( day, dby, 0x40 ) ); /* The discriminant above is actually a cross product of vectors */ /* da and db. Together with the dot product, they can be used as */ @@ -6459,30 +6503,29 @@ /* discriminant = |da||db|sin(angle) . */ /* We use these equations to reject grazing intersections by */ /* thresholding abs(tan(angle)) at 1/19, corresponding to 3 degrees. */ - if ( 19 * FT_ABS( discriminant ) > FT_ABS( dotproduct ) ) + if ( MUL_LONG( 19, FT_ABS( discriminant ) ) > FT_ABS( dotproduct ) ) { - val = FT_MulDiv( dx, -dby, 0x40 ) + FT_MulDiv( dy, dbx, 0x40 ); + val = ADD_LONG( FT_MulDiv( dx, NEG_LONG( dby ), 0x40 ), + FT_MulDiv( dy, dbx, 0x40 ) ); R.x = FT_MulDiv( val, dax, discriminant ); R.y = FT_MulDiv( val, day, discriminant ); /* XXX: Block in backward_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; + exc->zp2.cur[point].x = ADD_LONG( exc->zp1.cur[a0].x, R.x ); + exc->zp2.cur[point].y = ADD_LONG( exc->zp1.cur[a0].y, R.y ); } else { /* else, take the middle of the middles of A and B */ /* XXX: Block in backward_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 + - exc->zp0.cur[b1].x ) / 4; - exc->zp2.cur[point].y = ( exc->zp1.cur[a0].y + - exc->zp1.cur[a1].y + - exc->zp0.cur[b0].y + - exc->zp0.cur[b1].y ) / 4; + exc->zp2.cur[point].x = + ADD_LONG( ADD_LONG( exc->zp1.cur[a0].x, exc->zp1.cur[a1].x ), + ADD_LONG( exc->zp0.cur[b0].x, exc->zp0.cur[b1].x ) ) / 4; + exc->zp2.cur[point].y = + ADD_LONG( ADD_LONG( exc->zp1.cur[a0].y, exc->zp1.cur[a1].y ), + ADD_LONG( exc->zp0.cur[b0].y, exc->zp0.cur[b1].y ) ) / 4; } exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; @@ -6517,7 +6560,7 @@ distance = PROJECT( exc->zp0.cur + p2, exc->zp1.cur + p1 ) / 2; exc->func_move( exc, &exc->zp1, p1, distance ); - exc->func_move( exc, &exc->zp0, p2, -distance ); + exc->func_move( exc, &exc->zp0, p2, NEG_LONG( distance ) ); } @@ -6590,9 +6633,11 @@ FT_Vector vec; - vec.x = FT_MulFix( exc->zp1.orus[exc->GS.rp2].x - orus_base->x, + vec.x = FT_MulFix( SUB_LONG( exc->zp1.orus[exc->GS.rp2].x, + orus_base->x ), exc->metrics.x_scale ); - vec.y = FT_MulFix( exc->zp1.orus[exc->GS.rp2].y - orus_base->y, + vec.y = FT_MulFix( SUB_LONG( exc->zp1.orus[exc->GS.rp2].y, + orus_base->y ), exc->metrics.y_scale ); old_range = FAST_DUALPROJ( &vec ); @@ -6627,9 +6672,11 @@ FT_Vector vec; - vec.x = FT_MulFix( exc->zp2.orus[point].x - orus_base->x, + vec.x = FT_MulFix( SUB_LONG( exc->zp2.orus[point].x, + orus_base->x ), exc->metrics.x_scale ); - vec.y = FT_MulFix( exc->zp2.orus[point].y - orus_base->y, + vec.y = FT_MulFix( SUB_LONG( exc->zp2.orus[point].y, + orus_base->y ), exc->metrics.y_scale ); org_dist = FAST_DUALPROJ( &vec ); @@ -6668,7 +6715,7 @@ exc->func_move( exc, &exc->zp2, (FT_UShort)point, - new_dist - cur_dist ); + SUB_LONG( new_dist, cur_dist ) ); } Fail: @@ -6733,14 +6780,14 @@ FT_F26Dot6 dx; - dx = worker->curs[p].x - worker->orgs[p].x; + dx = SUB_LONG( worker->curs[p].x, worker->orgs[p].x ); if ( dx != 0 ) { for ( i = p1; i < p; i++ ) - worker->curs[i].x += dx; + worker->curs[i].x = ADD_LONG( worker->curs[i].x, dx ); for ( i = p + 1; i <= p2; i++ ) - worker->curs[i].x += dx; + worker->curs[i].x = ADD_LONG( worker->curs[i].x, dx ); } } @@ -6785,8 +6832,8 @@ org2 = worker->orgs[ref2].x; cur1 = worker->curs[ref1].x; cur2 = worker->curs[ref2].x; - delta1 = cur1 - org1; - delta2 = cur2 - org2; + delta1 = SUB_LONG( cur1, org1 ); + delta2 = SUB_LONG( cur2, org2 ); if ( cur1 == cur2 || orus1 == orus2 ) { @@ -6798,10 +6845,10 @@ if ( x <= org1 ) - x += delta1; + x = ADD_LONG( x, delta1 ); else if ( x >= org2 ) - x += delta2; + x = ADD_LONG( x, delta2 ); else x = cur1; @@ -6822,20 +6869,23 @@ if ( x <= org1 ) - x += delta1; + x = ADD_LONG( x, delta1 ); else if ( x >= org2 ) - x += delta2; + x = ADD_LONG( x, delta2 ); else { if ( !scale_valid ) { scale_valid = 1; - scale = FT_DivFix( cur2 - cur1, orus2 - orus1 ); + scale = FT_DivFix( SUB_LONG( cur2, cur1 ), + SUB_LONG( orus2, orus1 ) ); } - x = cur1 + FT_MulFix( worker->orus[i].x - orus1, scale ); + x = ADD_LONG( cur1, + FT_MulFix( SUB_LONG( worker->orus[i].x, orus1 ), + scale ) ); } worker->curs[i].x = x; } @@ -7310,7 +7360,11 @@ K |= 1 << 12; #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL - if ( SUBPIXEL_HINTING_MINIMAL ) + /* Toggle the following flags only outside of monochrome mode. */ + /* Otherwise, instructions may behave weirdly and rendering results */ + /* may differ between v35 and v40 mode, e.g., in `Times New Roman */ + /* Bold Italic'. */ + if ( SUBPIXEL_HINTING_MINIMAL && exc->subpixel_hinting_lean ) { /********************************/ /* HINTING FOR SUBPIXEL */ @@ -7345,7 +7399,7 @@ /* */ /* The only smoothing method FreeType supports unless someone sets */ /* FT_LOAD_TARGET_MONO. */ - if ( ( args[0] & 2048 ) != 0 ) + if ( ( args[0] & 2048 ) != 0 && exc->subpixel_hinting_lean ) K |= 1 << 18; /********************************/ @@ -7589,11 +7643,21 @@ #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL - /* Toggle backward 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. Backward compatibility */ - /* hacks may break it. */ + /* + * Toggle backward compatibility according to what font wants, except + * when + * + * 1) we have a `tricky' font that heavily relies on the interpreter to + * render glyphs correctly, for example DFKai-SB, or + * 2) FT_RENDER_MODE_MONO (i.e, monochome rendering) is requested. + * + * In those cases, backward compatibility needs to be turned off to get + * correct rendering. The rendering is then completely up to the + * font's programming. + * + */ if ( SUBPIXEL_HINTING_MINIMAL && + exc->subpixel_hinting_lean && !FT_IS_TRICKY( &exc->face->root ) ) exc->backward_compatibility = !( exc->GS.instruct_control & 4 ); else @@ -7639,8 +7703,7 @@ FT_MAX( 50, exc->cvtSize / 10 ); else - exc->loopcall_counter_max = FT_MAX( 100, - 10 * exc->cvtSize ); + exc->loopcall_counter_max = 300 + 8 * exc->cvtSize; /* as a protection against an unreasonable number of CVT entries */ /* we assume at most 100 control values per glyph for the counter */ diff --git a/thirdparty/freetype/src/truetype/ttinterp.h b/thirdparty/freetype/src/truetype/ttinterp.h index 55e472091c..abbecfcee3 100644 --- a/thirdparty/freetype/src/truetype/ttinterp.h +++ b/thirdparty/freetype/src/truetype/ttinterp.h @@ -253,23 +253,38 @@ FT_BEGIN_HEADER #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 backward - * 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). + * FreeType supports ClearType-like hinting of TrueType fonts through + * the version 40 interpreter. This is achieved through several hacks + * in the base (v35) interpreter, as detailed below. * - * 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. + * ClearType is an umbrella term for several rendering techniques + * employed by Microsoft's various GUI and rendering toolkit + * implementations, most importantly: subpixel rendering for using the + * RGB subpixels of LCDs to approximately triple the perceived + * resolution on the x-axis and subpixel hinting for positioning stems + * on subpixel borders. TrueType programming is explicit, i.e., fonts + * must be programmed to take advantage of ClearType's possibilities. + * + * When ClearType was introduced, it seemed unlikely that all fonts + * would be reprogrammed, so Microsoft decided to implement a backward + * compatibility mode. It employs several simple to complicated + * assumptions and tricks, many of them font-dependent, that modify the + * interpretation of the bytecode contained in these fonts to retrofit + * them into a ClearType-y look. The quality of the results varies. + * Most (web)fonts that were released since then have come to rely on + * these hacks to render correctly, even some of Microsoft's flagship + * fonts (e.g., Calibri, Cambria, Segoe UI). + * + * FreeType's minimal subpixel hinting code (interpreter version 40) + * employs a small list of font-agnostic hacks loosely based on the + * public information available on Microsoft's compatibility mode[2]. + * The focus is on modern (web)fonts rather than legacy fonts that were + * made for monochrome rendering. It will not match ClearType rendering + * exactly. Unlike the `Infinality' code (interpreter version 38) that + * came before, it will not try to toggle hacks for specific fonts for + * performance and complexity reasons. It will fall back to version 35 + * behavior for tricky fonts[1] or when monochrome rendering is + * requested. * * Major hacks * @@ -347,7 +362,8 @@ FT_BEGIN_HEADER * */ - /* Using v40 implies subpixel hinting. Used to detect interpreter */ + /* Using v40 implies subpixel hinting, unless FT_RENDER_MODE_MONO has been + * requested. Used to detect interpreter */ /* version switches. `_lean' to differentiate from the Infinality */ /* `subpixel_hinting', which is managed differently. */ FT_Bool subpixel_hinting_lean; diff --git a/thirdparty/freetype/src/truetype/ttobjs.c b/thirdparty/freetype/src/truetype/ttobjs.c index 4db0f289f8..081fa2f1a5 100644 --- a/thirdparty/freetype/src/truetype/ttobjs.c +++ b/thirdparty/freetype/src/truetype/ttobjs.c @@ -576,9 +576,11 @@ /* We must also be able to accept Mac/GX fonts, as well as OT ones. */ /* The 0x00020000 tag is completely undocumented; some fonts from */ /* Arphic made for Chinese Windows 3.1 have this. */ - if ( face->format_tag != 0x00010000L && /* MS fonts */ - face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */ - face->format_tag != TTAG_true ) /* Mac fonts */ + if ( face->format_tag != 0x00010000L && /* MS fonts */ + face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */ + face->format_tag != TTAG_true && /* Mac fonts */ + face->format_tag != TTAG_0xA5kbd && /* `Keyboard.dfont' (legacy Mac OS X) */ + face->format_tag != TTAG_0xA5lst ) /* `LastResort.dfont' (legacy Mac OS X) */ { FT_TRACE2(( " not a TTF font\n" )); goto Bad_Format; @@ -1230,7 +1232,9 @@ /* */ /* size :: A handle to the target size object. */ /* */ - /* only_height :: Only recompute ascender, descender, and height. */ + /* only_height :: Only recompute ascender, descender, and height; */ + /* this flag is used for variation fonts where */ + /* `tt_size_reset' is used as an iterator function. */ /* */ FT_LOCAL_DEF( FT_Error ) tt_size_reset( TT_Size size, @@ -1277,7 +1281,11 @@ size->ttmetrics.valid = TRUE; if ( only_height ) + { + /* we must not recompute the scaling values here since */ + /* `tt_size_reset' was already called (with only_height = 0) */ return FT_Err_Ok; + } if ( face->header.Flags & 8 ) { diff --git a/thirdparty/freetype/src/truetype/ttpload.c b/thirdparty/freetype/src/truetype/ttpload.c index 70ac15da4a..bcf6b34f67 100644 --- a/thirdparty/freetype/src/truetype/ttpload.c +++ b/thirdparty/freetype/src/truetype/ttpload.c @@ -247,13 +247,13 @@ if ( pos2 > face->glyf_len ) { /* We try to sanitize the last `loca' entry. */ - if ( gindex == face->num_locations - 1 ) + if ( gindex == face->num_locations - 2 ) { FT_TRACE1(( "tt_face_get_location:" - " too large offset (0x%08lx) found for glyph index %ld,\n" + " too large size (%ld bytes) found for glyph index %ld,\n" " " - " truncating at the end of `glyf' table (0x%08lx)\n", - pos2, gindex + 1, face->glyf_len )); + " truncating at the end of `glyf' table to %ld bytes\n", + pos2 - pos1, gindex, face->glyf_len - pos1 )); pos2 = face->glyf_len; } else diff --git a/thirdparty/freetype/src/type1/t1load.c b/thirdparty/freetype/src/type1/t1load.c index f5c661f7de..f569d6bec3 100644 --- a/thirdparty/freetype/src/type1/t1load.c +++ b/thirdparty/freetype/src/type1/t1load.c @@ -329,8 +329,8 @@ 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); - mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum); + mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum ); + mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum ); mmvar->axis[i].def = ( mmvar->axis[i].minimum + mmvar->axis[i].maximum ) / 2; /* Does not apply. But this value is in range */ diff --git a/thirdparty/freetype/src/type1/t1objs.c b/thirdparty/freetype/src/type1/t1objs.c index 97c16b0fdf..5ac1292ae0 100644 --- a/thirdparty/freetype/src/type1/t1objs.c +++ b/thirdparty/freetype/src/type1/t1objs.c @@ -555,12 +555,6 @@ if ( clazz ) error = FT_CMap_New( clazz, NULL, &charmap, NULL ); - -#if 0 - /* Select default charmap */ - if (root->num_charmaps) - root->charmap = root->charmaps[0]; -#endif } } diff --git a/thirdparty/freetype/src/type42/t42objs.c b/thirdparty/freetype/src/type42/t42objs.c index 87e5206b7f..1c4ebd768a 100644 --- a/thirdparty/freetype/src/type42/t42objs.c +++ b/thirdparty/freetype/src/type42/t42objs.c @@ -394,12 +394,6 @@ if ( clazz ) error = FT_CMap_New( clazz, NULL, &charmap, NULL ); - -#if 0 - /* Select default charmap */ - if ( root->num_charmaps ) - root->charmap = root->charmaps[0]; -#endif } } Exit: diff --git a/thirdparty/freetype/src/winfonts/winfnt.c b/thirdparty/freetype/src/winfonts/winfnt.c index 9811fbb05a..4c47962319 100644 --- a/thirdparty/freetype/src/winfonts/winfnt.c +++ b/thirdparty/freetype/src/winfonts/winfnt.c @@ -859,10 +859,6 @@ NULL ); if ( error ) goto Fail; - - /* Select default charmap */ - if ( root->num_charmaps ) - root->charmap = root->charmaps[0]; } /* set up remaining flags */ @@ -1095,7 +1091,7 @@ /* note: since glyphs are stored in columns and not in rows we */ /* can't use ft_glyphslot_set_bitmap */ - if ( FT_ALLOC_MULT( bitmap->buffer, pitch, bitmap->rows ) ) + if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, pitch ) ) goto Exit; column = (FT_Byte*)bitmap->buffer; -- cgit v1.2.3