Update freetype to 2.8.1

This commit is contained in:
volzhs 2017-10-10 01:38:41 +09:00
parent 8a57fe819d
commit 438175dd2b
79 changed files with 2093 additions and 1120 deletions

View File

@ -39,7 +39,7 @@ Use UI font if exists, because it has tight vertial metrix and good for UI.
## freetype ## freetype
- Upstream: https://www.freetype.org - Upstream: https://www.freetype.org
- Version: 2.8 - Version: 2.8.1
- License: FreeType License (BSD-like) - License: FreeType License (BSD-like)
Files extracted from upstream source: Files extracted from upstream source:

View File

@ -107,20 +107,17 @@ FT_BEGIN_HEADER
/*************************************************************************/ /*************************************************************************/
/* */ /* */
/* Uncomment the line below if you want to activate sub-pixel rendering */ /* Uncomment the line below if you want to activate LCD rendering */
/* (a.k.a. LCD rendering, or ClearType) in this build of the library. */ /* 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 */ /* Note that this feature is covered by several Microsoft patents */
/* and should not be activated in any default build of the library. */ /* and should not be activated in any default build of the library. */
/* */ /* When this macro is not defined, FreeType offers alternative LCD */
/* This macro has no impact on the FreeType API, only on its */ /* rendering technology that produces excellent output without LCD */
/* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */ /* filtering. */
/* 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. */
/* */ /* */
/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ /* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
@ -327,7 +324,7 @@ FT_BEGIN_HEADER
/* */ /* */
/* - The TrueType driver will provide its own set of glyph names, */ /* - The TrueType driver will provide its own set of glyph names, */
/* if you build it to support postscript names in the TrueType */ /* 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 */ /* - The Type 1 driver will not be able to synthesize a Unicode */
/* charmap out of the glyphs found in the fonts. */ /* charmap out of the glyphs found in the fonts. */

View File

@ -575,7 +575,8 @@ FT_BEGIN_HEADER
/* <Note> */ /* <Note> */
/* When a new face is created (either through @FT_New_Face or */ /* When a new face is created (either through @FT_New_Face or */
/* @FT_Open_Face), the library looks for a Unicode charmap within */ /* @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. */
/* */ /* */
/* <Also> */ /* <Also> */
/* See @FT_CharMapRec for the publicly accessible fields of a given */ /* 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 */ /* values of the corresponding fields in @FT_FaceRec. Some values */
/* like ascender or descender are rounded for historical reasons; */ /* like ascender or descender are rounded for historical reasons; */
/* more precise values (for outline fonts) can be derived by scaling */ /* 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 */ /* Note that due to glyph hinting and the selected rendering mode */
/* these values are usually not exact; consequently, they must be */ /* these values are usually not exact; consequently, they must be */
@ -1774,7 +1781,7 @@ FT_BEGIN_HEADER
/* and add it to `origin_x'> */ /* and add it to `origin_x'> */
/* */ /* */
/* origin_x += slot->advance.x; */ /* origin_x += slot->advance.x; */
/* origin_x += slot->rsb_delta - slot->lsb_relta; */ /* origin_x += slot->rsb_delta - slot->lsb_delta; */
/* endfor */ /* endfor */
/* } */ /* } */
/* */ /* */
@ -1794,9 +1801,9 @@ FT_BEGIN_HEADER
/* */ /* */
/* <load glyph with `FT_Load_Glyph'> */ /* <load glyph with `FT_Load_Glyph'> */
/* */ /* */
/* if ( prev_rsb_delta - slot->lsb_delta >= 32 ) */ /* if ( prev_rsb_delta - slot->lsb_delta > 32 ) */
/* origin_x -= 64; */ /* origin_x -= 64; */
/* else if ( prev_rsb_delta - slot->lsb_delta < -32 ) */ /* else if ( prev_rsb_delta - slot->lsb_delta < -31 ) */
/* origin_x += 64; */ /* origin_x += 64; */
/* */ /* */
/* prev_rsb_delta = slot->rsb_delta; */ /* 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. */ /* glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode. */
/* */ /* */
/* <Note> */ /* <Note> */
/* The LCD-optimized glyph bitmaps produced by `FT_Render_Glyph' can */ /* Should you define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your */
/* be filtered to reduce color-fringes by using */ /* `ftoption.h', which enables patented ClearType-style rendering, */
/* @FT_Library_SetLcdFilter (not active in the default builds). It */ /* the LCD-optimized glyph bitmaps should be filtered to reduce color */
/* is up to the caller to either call `FT_Library_SetLcdFilter' (if */ /* fringes inherent to this technology. You can either set up LCD */
/* available) or do the filtering itself. */ /* 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. */ /* The selected render mode only affects vector glyphs of a font. */
/* Embedded bitmaps often have a different pixel mode like */ /* 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 */ /* `a' rounded to the nearest 16.16 fixed integer, halfway cases away */
/* from zero. */ /* from zero. */
/* */ /* */
/* <Note> */
/* The function uses wrap-around arithmetic. */
/* */
FT_EXPORT( FT_Fixed ) FT_EXPORT( FT_Fixed )
FT_RoundFix( FT_Fixed a ); FT_RoundFix( FT_Fixed a );
@ -4345,6 +4357,9 @@ FT_BEGIN_HEADER
/* <Return> */ /* <Return> */
/* `a' rounded towards plus infinity. */ /* `a' rounded towards plus infinity. */
/* */ /* */
/* <Note> */
/* The function uses wrap-around arithmetic. */
/* */
FT_EXPORT( FT_Fixed ) FT_EXPORT( FT_Fixed )
FT_CeilFix( FT_Fixed a ); FT_CeilFix( FT_Fixed a );
@ -4442,7 +4457,7 @@ FT_BEGIN_HEADER
*/ */
#define FREETYPE_MAJOR 2 #define FREETYPE_MAJOR 2
#define FREETYPE_MINOR 8 #define FREETYPE_MINOR 8
#define FREETYPE_PATCH 0 #define FREETYPE_PATCH 1
/*************************************************************************/ /*************************************************************************/

View File

@ -404,12 +404,12 @@ FT_BEGIN_HEADER
* activate the warp hinting code in the auto-hinter, this property * activate the warp hinting code in the auto-hinter, this property
* switches warping on and off. * switches warping on and off.
* *
* Warping only works in `light' auto-hinting mode. The idea of the * Warping only works in `normal' auto-hinting mode replacing it.
* code is to slightly scale and shift a glyph along the non-hinted * The idea of the code is to slightly scale and shift a glyph along
* dimension (which is usually the horizontal axis) so that as much of * the non-hinted dimension (which is usually the horizontal axis) so
* its segments are aligned (more or less) to the grid. To find out a * that as much of its segments are aligned (more or less) to the grid.
* glyph's optimal scaling and shifting value, various parameter * To find out a glyph's optimal scaling and shifting value, various
* combinations are tried and scored. * parameter combinations are tried and scored.
* *
* By default, warping is off. The example below shows how to switch on * By default, warping is off. The example below shows how to switch on
* warping (omitting the error handling). * 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 * Since warping is a global property of the auto-hinter it is best to
* change its value before rendering any face. Otherwise, you should * 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.
* *
*/ */

View File

@ -233,6 +233,8 @@
"invalid PostScript (post) table" ) "invalid PostScript (post) table" )
FT_ERRORDEF_( DEF_In_Glyf_Bytecode, 0x9C, FT_ERRORDEF_( DEF_In_Glyf_Bytecode, 0x9C,
"found FDEF or IDEF opcode in glyf bytecode" ) "found FDEF or IDEF opcode in glyf bytecode" )
FT_ERRORDEF_( Missing_Bitmap, 0x9D,
"missing bitmap in strike" )
/* CFF, CID, and Type 1 errors */ /* CFF, CID, and Type 1 errors */

View File

@ -38,15 +38,15 @@
/* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */ /* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */
/* defined in `ftoption.h' in order to make the higher byte indicate */ /* defined in `ftoption.h' in order to make the higher byte indicate */
/* the module where the error has happened (this is not compatible */ /* the module where the error has happened (this is not compatible */
/* with standard builds of FreeType&nbsp;2, however). See the file */ /* with standard builds of FreeType~2, however). See the file */
/* `ftmoderr.h' for more details. */ /* `ftmoderr.h' for more details. */
/* */ /* */
/* *Error* *Message* *Strings* */ /* *Error* *Message* *Strings* */
/* */ /* */
/* Error definitions are set up with special macros that allow client */ /* Error definitions are set up with special macros that allow client */
/* applications to build a table of error message strings. The */ /* applications to build a table of error message strings. The */
/* strings are not included in a normal build of FreeType&nbsp;2 to */ /* strings are not included in a normal build of FreeType~2 to save */
/* save space (most client applications do not use them). */ /* space (most client applications do not use them). */
/* */ /* */
/* To do so, you have to define the following macros before including */ /* To do so, you have to define the following macros before including */
/* this file. */ /* this file. */

View File

@ -231,6 +231,12 @@ FT_BEGIN_HEADER
/* <Return> */ /* <Return> */
/* FreeType error code. 0~means success. */ /* FreeType error code. 0~means success. */
/* */ /* */
/* <Note> */
/* 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_EXPORT( FT_Error )
FT_Get_Glyph( FT_GlyphSlot slot, FT_Get_Glyph( FT_GlyphSlot slot,
FT_Glyph *aglyph ); FT_Glyph *aglyph );
@ -566,6 +572,9 @@ FT_BEGIN_HEADER
/* <Note> */ /* <Note> */
/* The result is undefined if either `a' or `b' is zero. */ /* 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_EXPORT( void )
FT_Matrix_Multiply( const FT_Matrix* a, FT_Matrix_Multiply( const FT_Matrix* a,
FT_Matrix* b ); FT_Matrix* b );

View File

@ -1064,24 +1064,24 @@ FT_BEGIN_HEADER
/* */ /* */
/* <Description> */ /* <Description> */
/* FreeType used to provide an area of memory called the `render */ /* FreeType used to provide an area of memory called the `render */
/* pool' available to all registered rasters. This was not thread */ /* pool' available to all registered rasterizers. This was not */
/* safe however and now FreeType never allocates this pool. NULL */ /* thread safe, however, and now FreeType never allocates this pool. */
/* is always passed in as pool_base. */
/* */ /* */
/* This function is called each time the render pool changes, or just */ /* This function is called after a new raster object is created. */
/* after a new raster object is created. */
/* */ /* */
/* <Input> */ /* <Input> */
/* raster :: A handle to the new raster object. */ /* 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. */
/* */ /* */
/* <Note> */ /* <Note> */
/* Rasters should ignore the render pool and rely on dynamic or stack */ /* Rasterizers should rely on dynamic or stack allocation if they */
/* allocation if they want to (a handle to the memory allocator is */ /* want to (a handle to the memory allocator is passed to the */
/* passed to the raster constructor). */ /* rasterizer constructor). */
/* */ /* */
typedef void typedef void
(*FT_Raster_ResetFunc)( FT_Raster raster, (*FT_Raster_ResetFunc)( FT_Raster raster,

View File

@ -44,9 +44,16 @@ FT_BEGIN_HEADER
* Reduce color fringes of subpixel-rendered bitmaps. * Reduce color fringes of subpixel-rendered bitmaps.
* *
* @description: * @description:
* Subpixel rendering exploits the color-striped structure of LCD * Should you #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your
* pixels, increasing the available resolution in the direction of the * `ftoption.h', which enables patented ClearType-style rendering,
* stripe (usually horizontal RGB) by a factor of~3. Since these * 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 * subpixels are color pixels, using them unfiltered creates severe
* color fringes. Use the @FT_Library_SetLcdFilter API to specify a * color fringes. Use the @FT_Library_SetLcdFilter API to specify a
* low-pass filter, which is then applied to subpixel-rendered bitmaps * 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 * the higher resolution to reduce color fringes, making the glyph image
* slightly blurrier. Positional improvements will remain. * 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: * A filter should have two properties:
* *
* 1) It should be normalized, meaning the sum of the 5~components * 1) It should be normalized, meaning the sum of the 5~components

View File

@ -35,11 +35,12 @@
FT_BEGIN_HEADER 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 #ifndef FT_DEPRECATED_ATTRIBUTE
#if defined(__GNUC__) && \ #if defined( __GNUC__ ) && \
((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) ( ( __GNUC__ >= 4 ) || \
#define FT_DEPRECATED_ATTRIBUTE __attribute__((deprecated)) ( ( __GNUC__ == 3 ) && ( __GNUC_MINOR__ >= 1 ) ) )
#define FT_DEPRECATED_ATTRIBUTE __attribute__(( deprecated ))
#else #else
#define FT_DEPRECATED_ATTRIBUTE #define FT_DEPRECATED_ATTRIBUTE
#endif #endif

View File

@ -178,7 +178,8 @@ FT_BEGIN_HEADER
/* strid :: The entry in `name' table identifying this instance. */ /* strid :: The entry in `name' table identifying this instance. */
/* */ /* */
/* psid :: The entry in `name' table identifying a PostScript name */ /* 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_ typedef struct FT_Var_Named_Style_
{ {
@ -195,7 +196,7 @@ FT_BEGIN_HEADER
/* FT_MM_Var */ /* FT_MM_Var */
/* */ /* */
/* <Description> */ /* <Description> */
/* 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. */ /* GX, or OpenType variation font. */
/* */ /* */
/* Some fields are specific to one format and not to the others. */ /* Some fields are specific to one format and not to the others. */
@ -321,6 +322,11 @@ FT_BEGIN_HEADER
/* <Return> */ /* <Return> */
/* FreeType error code. 0~means success. */ /* FreeType error code. 0~means success. */
/* */ /* */
/* <Note> */
/* 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_EXPORT( FT_Error )
FT_Set_MM_Design_Coordinates( FT_Face face, FT_Set_MM_Design_Coordinates( FT_Face face,
FT_UInt num_coords, FT_UInt num_coords,
@ -351,6 +357,11 @@ FT_BEGIN_HEADER
/* <Return> */ /* <Return> */
/* FreeType error code. 0~means success. */ /* FreeType error code. 0~means success. */
/* */ /* */
/* <Note> */
/* 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_EXPORT( FT_Error )
FT_Set_Var_Design_Coordinates( FT_Face face, FT_Set_Var_Design_Coordinates( FT_Face face,
FT_UInt num_coords, FT_UInt num_coords,
@ -415,6 +426,11 @@ FT_BEGIN_HEADER
/* <Return> */ /* <Return> */
/* FreeType error code. 0~means success. */ /* FreeType error code. 0~means success. */
/* */ /* */
/* <Note> */
/* 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_EXPORT( FT_Error )
FT_Set_MM_Blend_Coordinates( FT_Face face, FT_Set_MM_Blend_Coordinates( FT_Face face,
FT_UInt num_coords, FT_UInt num_coords,
@ -479,6 +495,50 @@ FT_BEGIN_HEADER
FT_UInt num_coords, FT_UInt num_coords,
FT_Fixed* coords ); FT_Fixed* coords );
/*************************************************************************/
/* */
/* <Enum> */
/* FT_VAR_AXIS_FLAG_XXX */
/* */
/* <Description> */
/* A list of bit flags used in the return value of */
/* @FT_Get_Var_Axis_Flags. */
/* */
/* <Values> */
/* FT_VAR_AXIS_FLAG_HIDDEN :: */
/* The variation axis should not be exposed to user interfaces. */
/* */
#define FT_VAR_AXIS_FLAG_HIDDEN 1
/*************************************************************************/
/* */
/* <Function> */
/* FT_Get_Var_Axis_Flags */
/* */
/* <Description> */
/* Get the `flags' field of an OpenType Variation Axis Record. */
/* */
/* Not meaningful for Adobe MM fonts (`*flags' is always zero). */
/* */
/* <Input> */
/* master :: The variation descriptor. */
/* */
/* axis_index :: The index of the requested variation axis. */
/* */
/* <Output> */
/* flags :: The `flags' field. See @FT_VAR_AXIS_FLAG_XXX for */
/* possible values. */
/* */
/* <Return> */
/* 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 );
/* */ /* */

View File

@ -385,6 +385,9 @@ FT_BEGIN_HEADER
/* @FT_Outline_Embolden, which uses the same strength in both */ /* @FT_Outline_Embolden, which uses the same strength in both */
/* directions. */ /* directions. */
/* */ /* */
/* <Since> */
/* 2.4.10 */
/* */
FT_EXPORT( FT_Error ) FT_EXPORT( FT_Error )
FT_Outline_EmboldenXY( FT_Outline* outline, FT_Outline_EmboldenXY( FT_Outline* outline,
FT_Pos xstrength, FT_Pos xstrength,

View File

@ -399,16 +399,42 @@ FT_BEGIN_HEADER
#endif /* 0 */ #endif /* 0 */
#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) #define INT_TO_F26DOT6( x ) ( (FT_Long)(x) * 64 ) /* << 6 */
#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) #define INT_TO_F2DOT14( x ) ( (FT_Long)(x) * 16384 ) /* << 14 */
#define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) #define INT_TO_FIXED( x ) ( (FT_Long)(x) * 65536 ) /* << 16 */
#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 ) #define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) * 4 ) /* << 2 */
#define FLOAT_TO_FIXED( x ) ( (FT_Long)( x * 65536.0 ) )
#define FIXED_TO_INT( x ) ( FT_RoundFix( x ) >> 16 ) #define FIXED_TO_INT( x ) ( FT_RoundFix( x ) >> 16 )
#define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \ #define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \
: ( -( ( 32 - (x) ) & -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 FT_END_HEADER

View File

@ -36,6 +36,7 @@
#include FT_INTERNAL_AUTOHINT_H #include FT_INTERNAL_AUTOHINT_H
#include FT_INTERNAL_SERVICE_H #include FT_INTERNAL_SERVICE_H
#include FT_INTERNAL_PIC_H #include FT_INTERNAL_PIC_H
#include FT_INTERNAL_CALC_H
#ifdef FT_CONFIG_OPTION_INCREMENTAL #ifdef FT_CONFIG_OPTION_INCREMENTAL
#include FT_INCREMENTAL_H #include FT_INCREMENTAL_H
@ -85,13 +86,29 @@ FT_BEGIN_HEADER
/* we use FT_TYPEOF to suppress signedness compilation warnings */ /* we use FT_TYPEOF to suppress signedness compilation warnings */
#define FT_PAD_FLOOR( x, n ) ( (x) & ~FT_TYPEOF( x )( (n)-1 ) ) #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_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_CEIL( x, n ) FT_PAD_FLOOR( (x) + (n)-1, n )
#define FT_PIX_FLOOR( x ) ( (x) & ~FT_TYPEOF( x )63 ) #define FT_PIX_FLOOR( x ) ( (x) & ~FT_TYPEOF( x )63 )
#define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 ) #define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 )
#define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 ) #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 * character classification functions -- since these are used to parse
@ -856,11 +873,6 @@ FT_BEGIN_HEADER
/* */ /* */
/* auto_hinter :: The auto-hinter module interface. */ /* 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 */ /* debug_hooks :: An array of four function pointers that allow */
/* debuggers to hook into a font format's */ /* debuggers to hook into a font format's */
/* interpreter. Currently, only the TrueType */ /* interpreter. Currently, only the TrueType */
@ -869,9 +881,6 @@ FT_BEGIN_HEADER
/* lcd_filter :: If subpixel rendering is activated, the */ /* lcd_filter :: If subpixel rendering is activated, the */
/* selected LCD filter mode. */ /* 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 */ /* lcd_weights :: If subpixel rendering is activated, the LCD */
/* filter weights, if any. */ /* filter weights, if any. */
/* */ /* */
@ -903,15 +912,10 @@ FT_BEGIN_HEADER
FT_Renderer cur_renderer; /* current outline renderer */ FT_Renderer cur_renderer; /* current outline renderer */
FT_Module auto_hinter; 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]; FT_DebugHook_Func debug_hooks[4];
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
FT_LcdFilter lcd_filter; FT_LcdFilter lcd_filter;
FT_Int lcd_extra; /* number of extra pixels */
FT_LcdFiveTapFilter lcd_weights; /* filter weights, if any */ FT_LcdFiveTapFilter lcd_weights; /* filter weights, if any */
FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */ FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */
#endif #endif

View File

@ -106,6 +106,12 @@ FT_BEGIN_HEADER
#define TTAG_VVAR FT_MAKE_TAG( 'V', 'V', 'A', 'R' ) #define TTAG_VVAR FT_MAKE_TAG( 'V', 'V', 'A', 'R' )
#define TTAG_wOFF FT_MAKE_TAG( 'w', 'O', 'F', 'F' ) #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 FT_END_HEADER

View File

@ -592,9 +592,6 @@
{ AF_BLUE_STRING_KAYAH_LI_DESCENDER, 0 }, { AF_BLUE_STRING_KAYAH_LI_DESCENDER, 0 },
{ AF_BLUE_STRING_KAYAH_LI_LARGE_DESCENDER, 0 }, { AF_BLUE_STRING_KAYAH_LI_LARGE_DESCENDER, 0 },
{ AF_BLUE_STRING_MAX, 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_STRING_KHMER_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
{ AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP, AF_BLUE_PROPERTY_LATIN_SUB_TOP }, { AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP, AF_BLUE_PROPERTY_LATIN_SUB_TOP },
@ -606,6 +603,9 @@
AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
{ AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM, 0 }, { AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM, 0 },
{ AF_BLUE_STRING_MAX, 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_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
{ AF_BLUE_STRING_LAO_BOTTOM, 0 }, { AF_BLUE_STRING_LAO_BOTTOM, 0 },
@ -701,6 +701,9 @@
{ AF_BLUE_STRING_TELUGU_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, { AF_BLUE_STRING_TELUGU_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
{ AF_BLUE_STRING_TELUGU_BOTTOM, 0 }, { AF_BLUE_STRING_TELUGU_BOTTOM, 0 },
{ AF_BLUE_STRING_MAX, 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_STRING_THAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
{ AF_BLUE_STRING_THAI_BOTTOM, 0 }, { AF_BLUE_STRING_THAI_BOTTOM, 0 },
@ -710,9 +713,6 @@
{ AF_BLUE_STRING_THAI_LARGE_DESCENDER, 0 }, { AF_BLUE_STRING_THAI_LARGE_DESCENDER, 0 },
{ AF_BLUE_STRING_THAI_DIGIT_TOP, 0 }, { AF_BLUE_STRING_THAI_DIGIT_TOP, 0 },
{ AF_BLUE_STRING_MAX, 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_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
{ AF_BLUE_STRING_VAI_BOTTOM, 0 }, { AF_BLUE_STRING_VAI_BOTTOM, 0 },
{ AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_MAX, 0 },

View File

@ -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_KAYAH_LI_LARGE_DESCENDER, 0 }
{ AF_BLUE_STRING_MAX, 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_STRINGSET_KHMR
{ AF_BLUE_STRING_KHMER_TOP, AF_BLUE_PROPERTY_LATIN_TOP | { AF_BLUE_STRING_KHMER_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT } 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_KHMER_SYMBOLS_WANING_BOTTOM, 0 }
{ AF_BLUE_STRING_MAX, 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_STRINGSET_LAO
{ AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP | { AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT } 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_TELUGU_BOTTOM, 0 }
{ AF_BLUE_STRING_MAX, 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_STRINGSET_THAI
{ AF_BLUE_STRING_THAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | { AF_BLUE_STRING_THAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT } 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_THAI_DIGIT_TOP, 0 }
{ AF_BLUE_STRING_MAX, 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_STRINGSET_VAII
{ AF_BLUE_STRING_VAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } { AF_BLUE_STRING_VAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
{ AF_BLUE_STRING_VAI_BOTTOM, 0 } { AF_BLUE_STRING_VAI_BOTTOM, 0 }

View File

@ -344,9 +344,9 @@ FT_BEGIN_HEADER
AF_BLUE_STRINGSET_GURU = 116, AF_BLUE_STRINGSET_GURU = 116,
AF_BLUE_STRINGSET_HEBR = 122, AF_BLUE_STRINGSET_HEBR = 122,
AF_BLUE_STRINGSET_KALI = 126, AF_BLUE_STRINGSET_KALI = 126,
AF_BLUE_STRINGSET_KNDA = 132, AF_BLUE_STRINGSET_KHMR = 132,
AF_BLUE_STRINGSET_KHMR = 135, AF_BLUE_STRINGSET_KHMS = 138,
AF_BLUE_STRINGSET_KHMS = 141, AF_BLUE_STRINGSET_KNDA = 141,
AF_BLUE_STRINGSET_LAO = 144, AF_BLUE_STRINGSET_LAO = 144,
AF_BLUE_STRINGSET_LATN = 150, AF_BLUE_STRINGSET_LATN = 150,
AF_BLUE_STRINGSET_LATB = 157, AF_BLUE_STRINGSET_LATB = 157,
@ -367,8 +367,8 @@ FT_BEGIN_HEADER
AF_BLUE_STRINGSET_TAML = 222, AF_BLUE_STRINGSET_TAML = 222,
AF_BLUE_STRINGSET_TAVT = 225, AF_BLUE_STRINGSET_TAVT = 225,
AF_BLUE_STRINGSET_TELU = 228, AF_BLUE_STRINGSET_TELU = 228,
AF_BLUE_STRINGSET_THAI = 231, AF_BLUE_STRINGSET_TFNG = 231,
AF_BLUE_STRINGSET_TFNG = 239, AF_BLUE_STRINGSET_THAI = 234,
AF_BLUE_STRINGSET_VAII = 242, AF_BLUE_STRINGSET_VAII = 242,
af_blue_2_1 = 245, af_blue_2_1 = 245,
#ifdef AF_CONFIG_OPTION_CJK #ifdef AF_CONFIG_OPTION_CJK

View File

@ -2272,13 +2272,7 @@
goto Exit; goto Exit;
/* analyze glyph outline */ /* 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 ) ) if ( AF_HINTS_DO_HORIZONTAL( hints ) )
#endif
{ {
error = af_cjk_hints_detect_features( hints, AF_DIMENSION_HORZ ); error = af_cjk_hints_detect_features( hints, AF_DIMENSION_HORZ );
if ( error ) if ( error )
@ -2304,9 +2298,9 @@
{ {
#ifdef AF_CONFIG_OPTION_USE_WARPER #ifdef AF_CONFIG_OPTION_USE_WARPER
if ( dim == AF_DIMENSION_HORZ && if ( dim == AF_DIMENSION_HORZ &&
metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL &&
AF_HINTS_DO_WARP( hints ) ) AF_HINTS_DO_WARP( hints ) )
{ {
AF_WarperRec warper; AF_WarperRec warper;
FT_Fixed scale; FT_Fixed scale;

View File

@ -507,15 +507,15 @@
return FT_THROW( Invalid_Argument ); return FT_THROW( Invalid_Argument );
seg = &axis->segments[idx]; seg = &axis->segments[idx];
*offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->ox *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->fx
: seg->first->oy; : seg->first->fy;
if ( seg->edge ) if ( seg->edge )
*is_blue = (FT_Bool)( seg->edge->blue_edge != 0 ); *is_blue = (FT_Bool)( seg->edge->blue_edge != 0 );
else else
*is_blue = FALSE; *is_blue = FALSE;
if ( *is_blue ) if ( *is_blue )
*blue_offset = seg->edge->blue_edge->cur; *blue_offset = seg->edge->blue_edge->org;
else else
*blue_offset = 0; *blue_offset = 0;

View File

@ -1690,9 +1690,11 @@
if ( prev_max_on_coord > max_on_coord ) if ( prev_max_on_coord > max_on_coord )
max_on_coord = prev_max_on_coord; max_on_coord = prev_max_on_coord;
prev_segment->last = point; prev_segment->last = point;
prev_segment->pos = (FT_Short)( ( min_pos + prev_segment->pos = (FT_Short)( ( min_pos +
max_pos ) >> 1 ); max_pos ) >> 1 );
prev_segment->delta = (FT_Short)( ( max_pos -
min_pos ) >> 1 );
if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL && if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL &&
( max_on_coord - min_on_coord ) < flat_threshold ) ( max_on_coord - min_on_coord ) < flat_threshold )
@ -1720,9 +1722,11 @@
if ( max_pos > prev_max_pos ) if ( max_pos > prev_max_pos )
prev_max_pos = max_pos; prev_max_pos = max_pos;
prev_segment->last = point; prev_segment->last = point;
prev_segment->pos = (FT_Short)( ( prev_min_pos + prev_segment->pos = (FT_Short)( ( prev_min_pos +
prev_max_pos ) >> 1 ); prev_max_pos ) >> 1 );
prev_segment->delta = (FT_Short)( ( prev_max_pos -
prev_min_pos ) >> 1 );
} }
else else
{ {
@ -1733,8 +1737,9 @@
if ( prev_max_pos > max_pos ) if ( prev_max_pos > max_pos )
max_pos = prev_max_pos; max_pos = prev_max_pos;
segment->last = point; segment->last = point;
segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 ); 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 && if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL &&
( max_on_coord - min_on_coord ) < flat_threshold ) ( max_on_coord - min_on_coord ) < flat_threshold )
@ -3492,13 +3497,7 @@
goto Exit; goto Exit;
/* analyze glyph outline */ /* 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 ) ) if ( AF_HINTS_DO_HORIZONTAL( hints ) )
#endif
{ {
axis = &metrics->axis[AF_DIMENSION_HORZ]; axis = &metrics->axis[AF_DIMENSION_HORZ];
error = af_latin_hints_detect_features( hints, error = af_latin_hints_detect_features( hints,
@ -3528,9 +3527,9 @@
for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
{ {
#ifdef AF_CONFIG_OPTION_USE_WARPER #ifdef AF_CONFIG_OPTION_USE_WARPER
if ( dim == AF_DIMENSION_HORZ && if ( dim == AF_DIMENSION_HORZ &&
metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL &&
AF_HINTS_DO_WARP( hints ) ) AF_HINTS_DO_WARP( hints ) )
{ {
AF_WarperRec warper; AF_WarperRec warper;
FT_Fixed scale; FT_Fixed scale;

View File

@ -2340,13 +2340,7 @@
goto Exit; goto Exit;
/* analyze glyph outline */ /* 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 ) ) if ( AF_HINTS_DO_HORIZONTAL( hints ) )
#endif
{ {
error = af_latin2_hints_detect_features( hints, AF_DIMENSION_HORZ ); error = af_latin2_hints_detect_features( hints, AF_DIMENSION_HORZ );
if ( error ) if ( error )
@ -2366,9 +2360,9 @@
for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
{ {
#ifdef AF_CONFIG_OPTION_USE_WARPER #ifdef AF_CONFIG_OPTION_USE_WARPER
if ( dim == AF_DIMENSION_HORZ && if ( dim == AF_DIMENSION_HORZ &&
metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL &&
AF_HINTS_DO_WARP( hints ) ) AF_HINTS_DO_WARP( hints ) )
{ {
AF_WarperRec warper; AF_WarperRec warper;
FT_Fixed scale; FT_Fixed scale;

View File

@ -483,8 +483,8 @@
FT_Pos pp2x = loader->pp2.x; FT_Pos pp2x = loader->pp2.x;
loader->pp1.x = FT_PIX_ROUND( pp1x ); loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta );
loader->pp2.x = FT_PIX_ROUND( pp2x ); loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta );
slot->lsb_delta = loader->pp1.x - pp1x; slot->lsb_delta = loader->pp1.x - pp1x;
slot->rsb_delta = loader->pp2.x - pp2x; slot->rsb_delta = loader->pp2.x - pp2x;
@ -498,8 +498,8 @@
FT_Pos pp2x = loader->pp2.x; FT_Pos pp2x = loader->pp2.x;
loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta ); loader->pp1.x = FT_PIX_ROUND( pp1x );
loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta ); loader->pp2.x = FT_PIX_ROUND( pp2x );
slot->lsb_delta = loader->pp1.x - pp1x; slot->lsb_delta = loader->pp1.x - pp1x;
slot->rsb_delta = loader->pp2.x - pp2x; slot->rsb_delta = loader->pp2.x - pp2x;

View File

@ -187,12 +187,6 @@
HINTING_BOTTOM_TO_TOP, HINTING_BOTTOM_TO_TOP,
"\xEA\xA4\x8D \xEA\xA4\x80" ) /* ꤍ ꤀ */ "\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 */ /* only digit zero has a simple shape in the Khmer script */
SCRIPT( khmr, KHMR, SCRIPT( khmr, KHMR,
"Khmer", "Khmer",
@ -206,6 +200,12 @@
HINTING_BOTTOM_TO_TOP, HINTING_BOTTOM_TO_TOP,
"\xE1\xA7\xA1 \xE1\xA7\xAA" ) /* ᧡ ᧪ */ "\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 */ /* only digit zero has a simple shape in the Lao script */
SCRIPT( lao, LAO, SCRIPT( lao, LAO,
"Lao", "Lao",
@ -330,18 +330,18 @@
HINTING_BOTTOM_TO_TOP, HINTING_BOTTOM_TO_TOP,
"\xE0\xB1\xA6 \xE0\xB1\xA7" ) /* ౧ */ "\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, SCRIPT( tfng, TFNG,
"Tifinagh", "Tifinagh",
HB_SCRIPT_TIFINAGH, HB_SCRIPT_TIFINAGH,
HINTING_BOTTOM_TO_TOP, HINTING_BOTTOM_TO_TOP,
"\xE2\xB5\x94" ) /* */ "\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, SCRIPT( vaii, VAII,
"Vai", "Vai",
HB_SCRIPT_VAI, HB_SCRIPT_VAI,

View File

@ -18,6 +18,7 @@
#include <ft2build.h> #include <ft2build.h>
#include FT_FREETYPE_H #include FT_FREETYPE_H
#include FT_ADVANCES_H
#include "afglobal.h" #include "afglobal.h"
#include "aftypes.h" #include "aftypes.h"
#include "afshaper.h" #include "afshaper.h"

View File

@ -255,13 +255,6 @@
AF_BLUE_STRINGSET_KALI, AF_BLUE_STRINGSET_KALI,
AF_COVERAGE_DEFAULT ) 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, STYLE( khmr_dflt, KHMR_DFLT,
"Khmer default style", "Khmer default style",
AF_WRITING_SYSTEM_LATIN, AF_WRITING_SYSTEM_LATIN,
@ -276,6 +269,13 @@
AF_BLUE_STRINGSET_KHMS, AF_BLUE_STRINGSET_KHMS,
AF_COVERAGE_DEFAULT ) 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, STYLE( lao_dflt, LAO_DFLT,
"Lao default style", "Lao default style",
AF_WRITING_SYSTEM_LATIN, AF_WRITING_SYSTEM_LATIN,
@ -420,13 +420,6 @@
AF_BLUE_STRINGSET_TELU, AF_BLUE_STRINGSET_TELU,
AF_COVERAGE_DEFAULT ) 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, STYLE( tfng_dflt, TFNG_DFLT,
"Tifinagh default style", "Tifinagh default style",
AF_WRITING_SYSTEM_LATIN, AF_WRITING_SYSTEM_LATIN,
@ -434,6 +427,13 @@
AF_BLUE_STRINGSET_TFNG, AF_BLUE_STRINGSET_TFNG,
AF_COVERAGE_DEFAULT ) 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, STYLE( vaii_dflt, VAII_DFLT,
"Vai default style", "Vai default style",
AF_WRITING_SYSTEM_LATIN, AF_WRITING_SYSTEM_LATIN,

View File

@ -226,7 +226,7 @@
} }
/* otherwise allocate new buffer */ /* 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; return error;
/* new rows get added at the top of the bitmap, */ /* 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 ) (FT_ULong)target->rows > FT_ULONG_MAX / (FT_ULong)target_pitch )
return FT_THROW( Invalid_Argument ); return FT_THROW( Invalid_Argument );
if ( target->rows * (FT_ULong)target_pitch > old_size && if ( FT_QREALLOC( target->buffer,
FT_QREALLOC( target->buffer,
old_size, target->rows * (FT_UInt)target_pitch ) ) old_size, target->rows * (FT_UInt)target_pitch ) )
return error; return error;

View File

@ -68,14 +68,15 @@
#define FT_COMPONENT trace_calc #define FT_COMPONENT trace_calc
/* transfer sign leaving a positive number */ /* transfer sign, leaving a positive number; */
#define FT_MOVE_SIGN( x, s ) \ /* we need an unsigned value to safely negate INT_MIN (or LONG_MIN) */
FT_BEGIN_STMNT \ #define FT_MOVE_SIGN( x, x_unsigned, s ) \
if ( x < 0 ) \ FT_BEGIN_STMNT \
{ \ if ( x < 0 ) \
x = -x; \ { \
s = -s; \ x_unsigned = 0U - (x_unsigned); \
} \ s = -s; \
} \
FT_END_STMNT FT_END_STMNT
/* The following three functions are available regardless of whether */ /* The following three functions are available regardless of whether */
@ -86,7 +87,7 @@
FT_EXPORT_DEF( FT_Fixed ) FT_EXPORT_DEF( FT_Fixed )
FT_RoundFix( FT_Fixed a ) 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_EXPORT_DEF( FT_Fixed )
FT_CeilFix( FT_Fixed a ) FT_CeilFix( FT_Fixed a )
{ {
return ( a + 0xFFFFL ) & ~0xFFFFL; return ( ADD_LONG( a, 0xFFFFL ) ) & ~0xFFFFL;
} }
@ -179,20 +180,20 @@
FT_Long d_; FT_Long d_;
FT_MOVE_SIGN( a_, s );
FT_MOVE_SIGN( b_, s );
FT_MOVE_SIGN( c_, s );
a = (FT_UInt64)a_; a = (FT_UInt64)a_;
b = (FT_UInt64)b_; b = (FT_UInt64)b_;
c = (FT_UInt64)c_; 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 d = c > 0 ? ( a * b + ( c >> 1 ) ) / c
: 0x7FFFFFFFUL; : 0x7FFFFFFFUL;
d_ = (FT_Long)d; d_ = (FT_Long)d;
return s < 0 ? -d_ : d_; return s < 0 ? NEG_LONG( d_ ) : d_;
} }
@ -208,20 +209,20 @@
FT_Long d_; FT_Long d_;
FT_MOVE_SIGN( a_, s );
FT_MOVE_SIGN( b_, s );
FT_MOVE_SIGN( c_, s );
a = (FT_UInt64)a_; a = (FT_UInt64)a_;
b = (FT_UInt64)b_; b = (FT_UInt64)b_;
c = (FT_UInt64)c_; 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 d = c > 0 ? a * b / c
: 0x7FFFFFFFUL; : 0x7FFFFFFFUL;
d_ = (FT_Long)d; d_ = (FT_Long)d;
return s < 0 ? -d_ : d_; return s < 0 ? NEG_LONG( d_ ) : d_;
} }
@ -257,18 +258,18 @@
FT_Long q_; FT_Long q_;
FT_MOVE_SIGN( a_, s );
FT_MOVE_SIGN( b_, s );
a = (FT_UInt64)a_; a = (FT_UInt64)a_;
b = (FT_UInt64)b_; b = (FT_UInt64)b_;
FT_MOVE_SIGN( a_, a, s );
FT_MOVE_SIGN( b_, b, s );
q = b > 0 ? ( ( a << 16 ) + ( b >> 1 ) ) / b q = b > 0 ? ( ( a << 16 ) + ( b >> 1 ) ) / b
: 0x7FFFFFFFUL; : 0x7FFFFFFFUL;
q_ = (FT_Long)q; 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 */ /* 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_; a = (FT_UInt32)a_;
b = (FT_UInt32)b_; b = (FT_UInt32)b_;
c = (FT_UInt32)c_; 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 ) if ( c == 0 )
a = 0x7FFFFFFFUL; a = 0x7FFFFFFFUL;
@ -455,7 +456,7 @@
a_ = (FT_Long)a; 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 */ /* 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_; a = (FT_UInt32)a_;
b = (FT_UInt32)b_; b = (FT_UInt32)b_;
c = (FT_UInt32)c_; 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 ) if ( c == 0 )
a = 0x7FFFFFFFUL; a = 0x7FFFFFFFUL;
@ -498,7 +499,7 @@
a_ = (FT_Long)a; 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 */ /* XXX: this function does not allow 64-bit arguments */
FT_MOVE_SIGN( a_, s );
FT_MOVE_SIGN( b_, s );
a = (FT_UInt32)a_; a = (FT_UInt32)a_;
b = (FT_UInt32)b_; b = (FT_UInt32)b_;
FT_MOVE_SIGN( a_, a, s );
FT_MOVE_SIGN( b_, b, s );
if ( a + ( b >> 8 ) <= 8190UL ) if ( a + ( b >> 8 ) <= 8190UL )
a = ( a * b + 0x8000UL ) >> 16; a = ( a * b + 0x8000UL ) >> 16;
else else
@ -594,7 +595,7 @@
a_ = (FT_Long)a; a_ = (FT_Long)a;
return s < 0 ? -a_ : a_; return s < 0 ? NEG_LONG( a_ ) : a_;
#endif /* 0 */ #endif /* 0 */
@ -614,12 +615,12 @@
/* XXX: this function does not allow 64-bit arguments */ /* XXX: this function does not allow 64-bit arguments */
FT_MOVE_SIGN( a_, s );
FT_MOVE_SIGN( b_, s );
a = (FT_UInt32)a_; a = (FT_UInt32)a_;
b = (FT_UInt32)b_; b = (FT_UInt32)b_;
FT_MOVE_SIGN( a_, a, s );
FT_MOVE_SIGN( b_, b, s );
if ( b == 0 ) if ( b == 0 )
{ {
/* check for division by 0 */ /* check for division by 0 */
@ -647,7 +648,7 @@
q_ = (FT_Long)q; q_ = (FT_Long)q;
return s < 0 ? -q_ : q_; return s < 0 ? NEG_LONG( q_ ) : q_;
} }
@ -666,13 +667,19 @@
if ( !a || !b ) if ( !a || !b )
return; return;
xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); xx = ADD_LONG( FT_MulFix( a->xx, b->xx ),
xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); FT_MulFix( a->xy, b->yx ) );
yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); xy = ADD_LONG( FT_MulFix( a->xx, b->xy ),
yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); 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->xx = xx;
b->yx = yx; b->yy = yy; b->xy = xy;
b->yx = yx;
b->yy = yy;
} }
@ -722,13 +729,19 @@
if ( !a || !b ) if ( !a || !b )
return; return;
xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val ); xx = ADD_LONG( FT_MulDiv( a->xx, b->xx, val ),
xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val ); FT_MulDiv( a->xy, b->yx, val ) );
yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val ); xy = ADD_LONG( FT_MulDiv( a->xx, b->xy, val ),
yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, 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->xx = xx;
b->yx = yx; b->yy = yy; b->xy = xy;
b->yx = yx;
b->yy = yy;
} }
@ -747,11 +760,10 @@
if ( !vector || !matrix ) if ( !vector || !matrix )
return; return;
xz = FT_MulDiv( vector->x, matrix->xx, val ) + xz = ADD_LONG( FT_MulDiv( vector->x, matrix->xx, val ),
FT_MulDiv( vector->y, matrix->xy, val ); FT_MulDiv( vector->y, matrix->xy, val ) );
yz = ADD_LONG( FT_MulDiv( vector->x, matrix->yx, val ),
yz = FT_MulDiv( vector->x, matrix->yx, val ) + FT_MulDiv( vector->y, matrix->yy, val ) );
FT_MulDiv( vector->y, matrix->yy, val );
vector->x = xz; vector->x = xz;
vector->y = yz; vector->y = yz;
@ -770,12 +782,12 @@
FT_Int sx = 1, sy = 1, shift; FT_Int sx = 1, sy = 1, shift;
FT_MOVE_SIGN( x_, sx );
FT_MOVE_SIGN( y_, sy );
x = (FT_UInt32)x_; x = (FT_UInt32)x_;
y = (FT_UInt32)y_; y = (FT_UInt32)y_;
FT_MOVE_SIGN( x_, x, sx );
FT_MOVE_SIGN( y_, y, sy );
/* trivial cases */ /* trivial cases */
if ( x == 0 ) if ( x == 0 )
{ {
@ -913,11 +925,13 @@
FT_Int result; FT_Int result;
if ( (FT_ULong)FT_ABS( in_x ) + (FT_ULong)FT_ABS( out_y ) <= 131071UL && /* we silently ignore overflow errors, since such large values */
(FT_ULong)FT_ABS( in_y ) + (FT_ULong)FT_ABS( out_x ) <= 131071UL ) /* 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 z1 = MUL_LONG( in_x, out_y );
FT_Long z2 = in_y * out_x; FT_Long z2 = MUL_LONG( in_y, out_x );
if ( z1 > z2 ) if ( z1 > z2 )

View File

@ -408,12 +408,28 @@
goto Exit; goto Exit;
/* copy advance while converting 26.6 to 16.16 format */ /* 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.x = slot->advance.x * 1024;
glyph->advance.y = slot->advance.y * 1024; glyph->advance.y = slot->advance.y * 1024;
/* now import the image from the glyph slot */ /* now import the image from the glyph slot */
error = clazz->glyph_init( glyph, slot ); error = clazz->glyph_init( glyph, slot );
Exit2:
/* if an error occurred, destroy the glyph */ /* if an error occurred, destroy the glyph */
if ( error ) if ( error )
FT_Done_Glyph( glyph ); FT_Done_Glyph( glyph );

View File

@ -29,141 +29,107 @@
/* define USE_LEGACY to implement the legacy filter */ /* define USE_LEGACY to implement the legacy filter */
#define USE_LEGACY #define USE_LEGACY
#define FT_SHIFTCLAMP( x ) ( x >>= 8, (FT_Byte)( x > 255 ? 255 : x ) )
/* FIR filter used by the default and light filters */ /* FIR filter used by the default and light filters */
FT_BASE( void ) FT_BASE( void )
ft_lcd_filter_fir( FT_Bitmap* bitmap, ft_lcd_filter_fir( FT_Bitmap* bitmap,
FT_Render_Mode mode, FT_Render_Mode mode,
FT_LcdFiveTapFilter weights ) FT_LcdFiveTapFilter weights )
{ {
FT_UInt width = (FT_UInt)bitmap->width; FT_UInt width = (FT_UInt)bitmap->width;
FT_UInt height = (FT_UInt)bitmap->rows; 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 */ /* 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 */ /* `fir' must be at least 32 bit wide, since the sum of */
if ( bitmap->pitch < 0 ) /* the values in `weights' can exceed 0xFF */
line -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 );
/* `fir' and `pix' must be at least 32 bit wide, since the sum of */ for ( ; height > 0; height--, line -= pitch )
/* the values in `weights' can exceed 0xFF */
for ( ; height > 0; height--, line += bitmap->pitch )
{ {
FT_UInt fir[4]; /* below, `pix' is used as the 5th element */ FT_UInt fir[5];
FT_UInt val1, xx; FT_UInt val, xx;
val1 = line[0]; val = line[0];
fir[0] = weights[2] * val1; fir[2] = weights[2] * val;
fir[1] = weights[3] * val1; fir[3] = weights[3] * val;
fir[2] = weights[4] * val1; fir[4] = weights[4] * val;
fir[3] = 0;
val1 = line[1]; val = line[1];
fir[0] += weights[1] * val1; fir[1] = fir[2] + weights[1] * val;
fir[1] += weights[2] * val1; fir[2] = fir[3] + weights[2] * val;
fir[2] += weights[3] * val1; fir[3] = fir[4] + weights[3] * val;
fir[3] += weights[4] * val1; fir[4] = weights[4] * val;
for ( xx = 2; xx < width; xx++ ) for ( xx = 2; xx < width; xx++ )
{ {
FT_UInt val, pix;
val = line[xx]; val = line[xx];
pix = fir[0] + weights[0] * val; fir[0] = fir[1] + weights[0] * val;
fir[0] = fir[1] + weights[1] * val; fir[1] = fir[2] + weights[1] * val;
fir[1] = fir[2] + weights[2] * val; fir[2] = fir[3] + weights[2] * val;
fir[2] = fir[3] + weights[3] * val; fir[3] = fir[4] + weights[3] * val;
fir[3] = weights[4] * val; fir[4] = weights[4] * val;
pix >>= 8; line[xx - 2] = FT_SHIFTCLAMP( fir[0] );
pix |= (FT_UInt)-(FT_Int)( pix >> 8 );
line[xx - 2] = (FT_Byte)pix;
} }
{ line[xx - 2] = FT_SHIFTCLAMP( fir[1] );
FT_UInt pix; line[xx - 1] = FT_SHIFTCLAMP( fir[2] );
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;
}
} }
} }
/* vertical in-place FIR filter */ /* 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_Byte* column = origin;
FT_Int pitch = bitmap->pitch;
/* take care of bitmap flow */
if ( bitmap->pitch < 0 )
column -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 );
for ( ; width > 0; width--, column++ ) for ( ; width > 0; width--, column++ )
{ {
FT_Byte* col = column; FT_Byte* col = column;
FT_UInt fir[4]; /* below, `pix' is used as the 5th element */ FT_UInt fir[5];
FT_UInt val1, yy; FT_UInt val, yy;
val1 = col[0]; val = col[0];
fir[0] = weights[2] * val1; fir[2] = weights[2] * val;
fir[1] = weights[3] * val1; fir[3] = weights[3] * val;
fir[2] = weights[4] * val1; fir[4] = weights[4] * val;
fir[3] = 0; col -= pitch;
col += pitch;
val1 = col[0]; val = col[0];
fir[0] += weights[1] * val1; fir[1] = fir[2] + weights[1] * val;
fir[1] += weights[2] * val1; fir[2] = fir[3] + weights[2] * val;
fir[2] += weights[3] * val1; fir[3] = fir[4] + weights[3] * val;
fir[3] += weights[4] * val1; fir[4] = weights[4] * val;
col += pitch; col -= pitch;
for ( yy = 2; yy < height; yy++ ) for ( yy = 2; yy < height; yy++, col -= pitch )
{ {
FT_UInt val, pix;
val = col[0]; val = col[0];
pix = fir[0] + weights[0] * val; fir[0] = fir[1] + weights[0] * val;
fir[0] = fir[1] + weights[1] * val; fir[1] = fir[2] + weights[1] * val;
fir[1] = fir[2] + weights[2] * val; fir[2] = fir[3] + weights[2] * val;
fir[2] = fir[3] + weights[3] * val; fir[3] = fir[4] + weights[3] * val;
fir[3] = weights[4] * val; fir[4] = weights[4] * val;
pix >>= 8; col[pitch * 2] = FT_SHIFTCLAMP( fir[0] );
pix |= (FT_UInt)-(FT_Int)( pix >> 8 );
col[-2 * pitch] = (FT_Byte)pix;
col += pitch;
} }
{ col[pitch * 2] = FT_SHIFTCLAMP( fir[1] );
FT_UInt pix; col[pitch] = FT_SHIFTCLAMP( fir[2] );
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;
}
} }
} }
} }
@ -177,9 +143,10 @@
FT_Render_Mode mode, FT_Render_Mode mode,
FT_Byte* weights ) FT_Byte* weights )
{ {
FT_UInt width = (FT_UInt)bitmap->width; FT_UInt width = (FT_UInt)bitmap->width;
FT_UInt height = (FT_UInt)bitmap->rows; FT_UInt height = (FT_UInt)bitmap->rows;
FT_Int pitch = bitmap->pitch; FT_Int pitch = bitmap->pitch;
FT_Byte* origin = bitmap->buffer;
static const unsigned int filters[3][3] = static const unsigned int filters[3][3] =
{ {
@ -191,33 +158,31 @@
FT_UNUSED( weights ); FT_UNUSED( weights );
/* take care of bitmap flow */
if ( pitch > 0 )
origin += pitch * (FT_Int)( height - 1 );
/* horizontal in-place intra-pixel filter */ /* horizontal in-place intra-pixel filter */
if ( mode == FT_RENDER_MODE_LCD && width >= 3 ) if ( mode == FT_RENDER_MODE_LCD && width >= 3 )
{ {
FT_Byte* line = bitmap->buffer; FT_Byte* line = origin;
/* take care of bitmap flow */ for ( ; height > 0; height--, line -= pitch )
if ( bitmap->pitch < 0 )
line -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 );
for ( ; height > 0; height--, line += pitch )
{ {
FT_UInt xx; FT_UInt xx;
for ( xx = 0; xx < width; xx += 3 ) for ( xx = 0; xx < width; xx += 3 )
{ {
FT_UInt r = 0; FT_UInt r, g, b;
FT_UInt g = 0;
FT_UInt b = 0;
FT_UInt p; FT_UInt p;
p = line[xx]; p = line[xx];
r += filters[0][0] * p; r = filters[0][0] * p;
g += filters[0][1] * p; g = filters[0][1] * p;
b += filters[0][2] * p; b = filters[0][2] * p;
p = line[xx + 1]; p = line[xx + 1];
r += filters[1][0] * p; r += filters[1][0] * p;
@ -237,31 +202,24 @@
} }
else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 ) 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++ ) for ( ; width > 0; width--, column++ )
{ {
FT_Byte* col = column; FT_Byte* col = column - 2 * pitch;
FT_Byte* col_end = col + (FT_Int)height * pitch;
for ( ; col < col_end; col += 3 * pitch ) for ( ; height > 0; height -= 3, col -= 3 * pitch )
{ {
FT_UInt r = 0; FT_UInt r, g, b;
FT_UInt g = 0;
FT_UInt b = 0;
FT_UInt p; FT_UInt p;
p = col[0]; p = col[0];
r += filters[0][0] * p; r = filters[0][0] * p;
g += filters[0][1] * p; g = filters[0][1] * p;
b += filters[0][2] * p; b = filters[0][2] * p;
p = col[pitch]; p = col[pitch];
r += filters[1][0] * p; r += filters[1][0] * p;
@ -275,7 +233,7 @@
col[0] = (FT_Byte)( r / 65536 ); col[0] = (FT_Byte)( r / 65536 );
col[pitch] = (FT_Byte)( g / 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 ); ft_memcpy( library->lcd_weights, weights, FT_LCD_FILTER_FIVE_TAPS );
library->lcd_filter_func = ft_lcd_filter_fir; library->lcd_filter_func = ft_lcd_filter_fir;
library->lcd_extra = 2;
return FT_Err_Ok; return FT_Err_Ok;
} }
@ -319,7 +276,6 @@
{ {
case FT_LCD_FILTER_NONE: case FT_LCD_FILTER_NONE:
library->lcd_filter_func = NULL; library->lcd_filter_func = NULL;
library->lcd_extra = 0;
break; break;
case FT_LCD_FILTER_DEFAULT: case FT_LCD_FILTER_DEFAULT:
@ -327,7 +283,6 @@
default_weights, default_weights,
FT_LCD_FILTER_FIVE_TAPS ); FT_LCD_FILTER_FIVE_TAPS );
library->lcd_filter_func = ft_lcd_filter_fir; library->lcd_filter_func = ft_lcd_filter_fir;
library->lcd_extra = 2;
break; break;
case FT_LCD_FILTER_LIGHT: case FT_LCD_FILTER_LIGHT:
@ -335,7 +290,6 @@
light_weights, light_weights,
FT_LCD_FILTER_FIVE_TAPS ); FT_LCD_FILTER_FIVE_TAPS );
library->lcd_filter_func = ft_lcd_filter_fir; library->lcd_filter_func = ft_lcd_filter_fir;
library->lcd_extra = 2;
break; break;
#ifdef USE_LEGACY #ifdef USE_LEGACY
@ -343,7 +297,6 @@
case FT_LCD_FILTER_LEGACY: case FT_LCD_FILTER_LEGACY:
case FT_LCD_FILTER_LEGACY1: case FT_LCD_FILTER_LEGACY1:
library->lcd_filter_func = _ft_lcd_filter_legacy; library->lcd_filter_func = _ft_lcd_filter_legacy;
library->lcd_extra = 0;
break; break;
#endif #endif

View File

@ -1005,7 +1005,7 @@
/* accepts an FSRef instead of a path. */ /* accepts an FSRef instead of a path. */
/* */ /* */
/* This function is deprecated because Carbon data types (FSRef) */ /* 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_EXPORT_DEF( FT_Error )
FT_New_Face_From_FSRef( FT_Library library, FT_New_Face_From_FSRef( FT_Library library,
const FSRef* ref, const FSRef* ref,

View File

@ -158,7 +158,7 @@
/* check of `face' delayed to `ft_face_get_mm_service' */ /* check of `face' delayed to `ft_face_get_mm_service' */
if ( !coords ) if ( num_coords && !coords )
return FT_THROW( Invalid_Argument ); return FT_THROW( Invalid_Argument );
error = ft_face_get_mm_service( face, &service ); error = ft_face_get_mm_service( face, &service );
@ -194,7 +194,7 @@
/* check of `face' delayed to `ft_face_get_mm_service' */ /* check of `face' delayed to `ft_face_get_mm_service' */
if ( !coords ) if ( num_coords && !coords )
return FT_THROW( Invalid_Argument ); return FT_THROW( Invalid_Argument );
error = ft_face_get_mm_service( face, &service_mm ); error = ft_face_get_mm_service( face, &service_mm );
@ -266,7 +266,7 @@
/* check of `face' delayed to `ft_face_get_mm_service' */ /* check of `face' delayed to `ft_face_get_mm_service' */
if ( !coords ) if ( num_coords && !coords )
return FT_THROW( Invalid_Argument ); return FT_THROW( Invalid_Argument );
error = ft_face_get_mm_service( face, &service_mm ); error = ft_face_get_mm_service( face, &service_mm );
@ -313,7 +313,7 @@
/* check of `face' delayed to `ft_face_get_mm_service' */ /* check of `face' delayed to `ft_face_get_mm_service' */
if ( !coords ) if ( num_coords && !coords )
return FT_THROW( Invalid_Argument ); return FT_THROW( Invalid_Argument );
error = ft_face_get_mm_service( face, &service_mm ); 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 */ /* END */

View File

@ -579,34 +579,42 @@
if ( vertical ) if ( vertical )
{ {
metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); 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 ); right = FT_PIX_CEIL_LONG( ADD_LONG( metrics->vertBearingX,
bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height ); metrics->width ) );
bottom = FT_PIX_CEIL_LONG( ADD_LONG( metrics->vertBearingY,
metrics->height ) );
metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
metrics->width = right - metrics->vertBearingX; metrics->width = SUB_LONG( right,
metrics->height = bottom - metrics->vertBearingY; metrics->vertBearingX );
metrics->height = SUB_LONG( bottom,
metrics->vertBearingY );
} }
else else
{ {
metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
right = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width ); right = FT_PIX_CEIL_LONG( ADD_LONG( metrics->horiBearingX,
bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height ); metrics->width ) );
bottom = FT_PIX_FLOOR( SUB_LONG( metrics->horiBearingY,
metrics->height ) );
metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); 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->width = SUB_LONG( right,
metrics->height = metrics->horiBearingY - bottom; metrics->horiBearingX );
metrics->height = SUB_LONG( metrics->horiBearingY,
bottom );
} }
metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); metrics->horiAdvance = FT_PIX_ROUND_LONG( metrics->horiAdvance );
metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); metrics->vertAdvance = FT_PIX_ROUND_LONG( metrics->vertAdvance );
} }
#endif /* GRID_FIT_METRICS */ #endif /* GRID_FIT_METRICS */
@ -4549,7 +4557,7 @@
if ( !clazz ) if ( !clazz )
return FT_THROW( Invalid_Argument ); return FT_THROW( Invalid_Argument );
/* check freetype version */ /* check FreeType version */
if ( clazz->module_requires > FREETYPE_VER_FIXED ) if ( clazz->module_requires > FREETYPE_VER_FIXED )
return FT_THROW( Invalid_Version ); return FT_THROW( Invalid_Version );
@ -4973,10 +4981,6 @@
goto Fail; goto Fail;
#endif #endif
/* we don't use raster_pool anymore. */
library->raster_pool_size = 0;
library->raster_pool = NULL;
library->version_major = FREETYPE_MAJOR; library->version_major = FREETYPE_MAJOR;
library->version_minor = FREETYPE_MINOR; library->version_minor = FREETYPE_MINOR;
library->version_patch = FREETYPE_PATCH; library->version_patch = FREETYPE_PATCH;

View File

@ -1088,7 +1088,8 @@
v_cur.x = points[n].x >> xshift; v_cur.x = points[n].x >> xshift;
v_cur.y = points[n].y >> yshift; 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; v_prev = v_cur;
} }

View File

@ -271,7 +271,13 @@
if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ if ( FT_STREAM_SKIP( 4 ) ) /* mbz */
goto Exit; 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 ); error = FT_THROW( Invalid_Table );
goto Exit; goto Exit;
@ -281,7 +287,7 @@
FT_TRACE3(( " [%d]:" FT_TRACE3(( " [%d]:"
" resource_id=0x%04x, offset=0x%08x\n", " 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 ) if ( sort_by_res_id )

View File

@ -123,7 +123,7 @@
/* /*
* XXX: overflow check for 16-bit system, for compatibility * 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 * unfortunately, this function return no informations
* about the cause of error. * about the cause of error.
*/ */

View File

@ -135,7 +135,7 @@
ft_mem_free( memory, block ); ft_mem_free( memory, block );
block = NULL; 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 ); error = FT_THROW( Array_Too_Large );
} }
@ -143,13 +143,15 @@
{ {
FT_ASSERT( !block ); 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 else
{ {
FT_Pointer block2; FT_Pointer block2;
FT_Long cur_size = cur_count*item_size; FT_Long cur_size = cur_count * item_size;
FT_Long new_size = new_count*item_size; FT_Long new_size = new_count * item_size;
block2 = memory->realloc( memory, cur_size, new_size, block ); block2 = memory->realloc( memory, cur_size, new_size, block );

View File

@ -373,7 +373,7 @@ THE SOFTWARE.
/* we have a bdf font: let's construct the face object */ /* we have a bdf font: let's construct the face object */
face->bdffont = font; 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 * XXX: non-zero face_index is already invalid argument, but
* Type1, Type42 driver has a convention to return * Type1, Type42 driver has a convention to return
* an invalid argument error when the font could be * an invalid argument error when the font could be
@ -437,46 +437,156 @@ THE SOFTWARE.
{ {
FT_Bitmap_Size* bsize = bdfface->available_sizes; FT_Bitmap_Size* bsize = bdfface->available_sizes;
FT_Short resolution_x = 0, resolution_y = 0; FT_Short resolution_x = 0, resolution_y = 0;
long value;
FT_ZERO( bsize ); 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 ); bsize->height = (FT_Short)( font->font_ascent + font->font_descent );
prop = bdf_get_font_property( font, "AVERAGE_WIDTH" ); prop = bdf_get_font_property( font, "AVERAGE_WIDTH" );
if ( prop ) 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 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" ); prop = bdf_get_font_property( font, "POINT_SIZE" );
if ( prop ) 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 */ /* convert from 722.7 decipoints to 72 points per inch */
bsize->size = if ( prop->value.l > 0x504C2L || /* 0x7FFF * 72270/7200 */
(FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L ); 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 else
bsize->size = bsize->width << 6; {
/* this is a heuristical value */
bsize->size = bsize->width * 64;
}
prop = bdf_get_font_property( font, "PIXEL_SIZE" ); prop = bdf_get_font_property( font, "PIXEL_SIZE" );
if ( prop ) 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" ); prop = bdf_get_font_property( font, "RESOLUTION_X" );
if ( prop ) 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" ); prop = bdf_get_font_property( font, "RESOLUTION_Y" );
if ( prop ) 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 ) if ( bsize->y_ppem == 0 )
{ {
bsize->y_ppem = bsize->size; bsize->y_ppem = bsize->size;
if ( resolution_y ) 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 ) 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 else
bsize->x_ppem = bsize->y_ppem; bsize->x_ppem = bsize->y_ppem;
} }
@ -545,7 +655,11 @@ THE SOFTWARE.
if ( !ft_strcmp( s, "10646" ) || if ( !ft_strcmp( s, "10646" ) ||
( !ft_strcmp( s, "8859" ) && ( !ft_strcmp( s, "8859" ) &&
!ft_strcmp( face->charset_encoding, "1" ) ) ) !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 ); 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; goto Exit;

View File

@ -704,7 +704,15 @@
return 0; return 0;
for ( v = 0; sbitset( ddigits, *s ); s++ ) 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; return v;
} }
@ -729,7 +737,15 @@
} }
for ( v = 0; sbitset( ddigits, *s ); s++ ) 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; return ( !neg ) ? v : -v;
} }
@ -746,7 +762,15 @@
return 0; return 0;
for ( v = 0; sbitset( ddigits, *s ); s++ ) 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; return v;
} }
@ -771,7 +795,15 @@
} }
for ( v = 0; sbitset( ddigits, *s ); s++ ) 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 ); return (short)( ( !neg ) ? v : -v );
} }

View File

@ -304,10 +304,18 @@
if ( anode ) if ( anode )
*anode = NULL; *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:" FT_TRACE1(( "FTC_ImageCache_Lookup:"
" higher bits in load_flags 0x%x are dropped\n", " higher bits in load_flags 0x%x are dropped\n",
(FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) )); (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) ));
#endif
query.attrs.scaler.face_id = type->face_id; query.attrs.scaler.face_id = type->face_id;
query.attrs.scaler.width = type->width; query.attrs.scaler.width = type->width;
@ -377,11 +385,18 @@
if ( anode ) if ( anode )
*anode = NULL; *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 ) if ( load_flags > FT_UINT_MAX )
FT_TRACE1(( "FTC_ImageCache_LookupScaler:" FT_TRACE1(( "FTC_ImageCache_LookupScaler:"
" higher bits in load_flags 0x%x are dropped\n", " higher bits in load_flags 0x%x are dropped\n",
load_flags & ~((FT_ULong)FT_UINT_MAX) )); load_flags & ~((FT_ULong)FT_UINT_MAX) ));
#endif
query.attrs.scaler = scaler[0]; query.attrs.scaler = scaler[0];
query.attrs.load_flags = (FT_UInt)load_flags; query.attrs.load_flags = (FT_UInt)load_flags;
@ -487,10 +502,18 @@
*ansbit = NULL; *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:" FT_TRACE1(( "FTC_ImageCache_Lookup:"
" higher bits in load_flags 0x%x are dropped\n", " higher bits in load_flags 0x%x are dropped\n",
(FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) )); (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) ));
#endif
query.attrs.scaler.face_id = type->face_id; query.attrs.scaler.face_id = type->face_id;
query.attrs.scaler.width = type->width; query.attrs.scaler.width = type->width;
@ -562,11 +585,18 @@
*ansbit = NULL; *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 ) if ( load_flags > FT_UINT_MAX )
FT_TRACE1(( "FTC_ImageCache_LookupScaler:" FT_TRACE1(( "FTC_ImageCache_LookupScaler:"
" higher bits in load_flags 0x%x are dropped\n", " higher bits in load_flags 0x%x are dropped\n",
load_flags & ~((FT_ULong)FT_UINT_MAX) )); load_flags & ~((FT_ULong)FT_UINT_MAX) ));
#endif
query.attrs.scaler = scaler[0]; query.attrs.scaler = scaler[0];
query.attrs.load_flags = (FT_UInt)load_flags; query.attrs.load_flags = (FT_UInt)load_flags;

View File

@ -194,8 +194,8 @@
blues->zone[blues->count].csTopEdge = blues->zone[blues->count].csTopEdge =
cf2_blueToFixed( blueValues[i + 1] ); cf2_blueToFixed( blueValues[i + 1] );
zoneHeight = blues->zone[blues->count].csTopEdge - zoneHeight = SUB_INT32( blues->zone[blues->count].csTopEdge,
blues->zone[blues->count].csBottomEdge; blues->zone[blues->count].csBottomEdge );
if ( zoneHeight < 0 ) if ( zoneHeight < 0 )
{ {
@ -243,8 +243,8 @@
blues->zone[blues->count].csTopEdge = blues->zone[blues->count].csTopEdge =
cf2_blueToFixed( otherBlues[i + 1] ); cf2_blueToFixed( otherBlues[i + 1] );
zoneHeight = blues->zone[blues->count].csTopEdge - zoneHeight = SUB_INT32( blues->zone[blues->count].csTopEdge,
blues->zone[blues->count].csBottomEdge; blues->zone[blues->count].csBottomEdge );
if ( zoneHeight < 0 ) if ( zoneHeight < 0 )
{ {
@ -301,7 +301,7 @@
/* top edge */ /* top edge */
flatFamilyEdge = cf2_blueToFixed( familyOtherBlues[j + 1] ); flatFamilyEdge = cf2_blueToFixed( familyOtherBlues[j + 1] );
diff = cf2_fixedAbs( flatEdge - flatFamilyEdge ); diff = cf2_fixedAbs( SUB_INT32( flatEdge, flatFamilyEdge ) );
if ( diff < minDiff && diff < csUnitsPerPixel ) if ( diff < minDiff && diff < csUnitsPerPixel )
{ {
@ -319,7 +319,7 @@
/* top edge */ /* top edge */
flatFamilyEdge = cf2_blueToFixed( familyBlues[1] ); flatFamilyEdge = cf2_blueToFixed( familyBlues[1] );
diff = cf2_fixedAbs( flatEdge - flatFamilyEdge ); diff = cf2_fixedAbs( SUB_INT32( flatEdge, flatFamilyEdge ) );
if ( diff < minDiff && diff < csUnitsPerPixel ) if ( diff < minDiff && diff < csUnitsPerPixel )
blues->zone[i].csFlatEdge = flatFamilyEdge; blues->zone[i].csFlatEdge = flatFamilyEdge;
@ -342,7 +342,7 @@
/* adjust edges of top zone upward by twice darkening amount */ /* adjust edges of top zone upward by twice darkening amount */
flatFamilyEdge += 2 * font->darkenY; /* bottom edge */ flatFamilyEdge += 2 * font->darkenY; /* bottom edge */
diff = cf2_fixedAbs( flatEdge - flatFamilyEdge ); diff = cf2_fixedAbs( SUB_INT32( flatEdge, flatFamilyEdge ) );
if ( diff < minDiff && diff < csUnitsPerPixel ) if ( diff < minDiff && diff < csUnitsPerPixel )
{ {
@ -408,8 +408,8 @@
/* Note: constant changed from 0.5 to 0.6 to avoid a problem with */ /* Note: constant changed from 0.5 to 0.6 to avoid a problem with */
/* 10ppem Arial */ /* 10ppem Arial */
blues->boost = cf2_floatToFixed( .6 ) - blues->boost = cf2_doubleToFixed( .6 ) -
FT_MulDiv( cf2_floatToFixed ( .6 ), FT_MulDiv( cf2_doubleToFixed ( .6 ),
blues->scale, blues->scale,
blues->blueScale ); blues->blueScale );
if ( blues->boost > 0x7FFF ) if ( blues->boost > 0x7FFF )
@ -489,17 +489,18 @@
if ( blues->zone[i].bottomZone && if ( blues->zone[i].bottomZone &&
cf2_hint_isBottom( bottomHintEdge ) ) cf2_hint_isBottom( bottomHintEdge ) )
{ {
if ( ( blues->zone[i].csBottomEdge - csFuzz ) <= if ( SUB_INT32( blues->zone[i].csBottomEdge, csFuzz ) <=
bottomHintEdge->csCoord && bottomHintEdge->csCoord &&
bottomHintEdge->csCoord <= bottomHintEdge->csCoord <=
( blues->zone[i].csTopEdge + csFuzz ) ) ADD_INT32( blues->zone[i].csTopEdge, csFuzz ) )
{ {
/* bottom edge captured by bottom zone */ /* bottom edge captured by bottom zone */
if ( blues->suppressOvershoot ) if ( blues->suppressOvershoot )
dsNew = blues->zone[i].dsFlatEdge; 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 ) blues->blueShift )
{ {
/* guarantee minimum of 1 pixel overshoot */ /* guarantee minimum of 1 pixel overshoot */
@ -514,7 +515,7 @@
dsNew = cf2_fixedRound( bottomHintEdge->dsCoord ); dsNew = cf2_fixedRound( bottomHintEdge->dsCoord );
} }
dsMove = dsNew - bottomHintEdge->dsCoord; dsMove = SUB_INT32( dsNew, bottomHintEdge->dsCoord );
captured = TRUE; captured = TRUE;
break; break;
@ -523,17 +524,18 @@
if ( !blues->zone[i].bottomZone && cf2_hint_isTop( topHintEdge ) ) if ( !blues->zone[i].bottomZone && cf2_hint_isTop( topHintEdge ) )
{ {
if ( ( blues->zone[i].csBottomEdge - csFuzz ) <= if ( SUB_INT32( blues->zone[i].csBottomEdge, csFuzz ) <=
topHintEdge->csCoord && topHintEdge->csCoord &&
topHintEdge->csCoord <= topHintEdge->csCoord <=
( blues->zone[i].csTopEdge + csFuzz ) ) ADD_INT32( blues->zone[i].csTopEdge, csFuzz ) )
{ {
/* top edge captured by top zone */ /* top edge captured by top zone */
if ( blues->suppressOvershoot ) if ( blues->suppressOvershoot )
dsNew = blues->zone[i].dsFlatEdge; 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 ) blues->blueShift )
{ {
/* guarantee minimum of 1 pixel overshoot */ /* guarantee minimum of 1 pixel overshoot */
@ -548,7 +550,7 @@
dsNew = cf2_fixedRound( topHintEdge->dsCoord ); dsNew = cf2_fixedRound( topHintEdge->dsCoord );
} }
dsMove = dsNew - topHintEdge->dsCoord; dsMove = SUB_INT32( dsNew, topHintEdge->dsCoord );
captured = TRUE; captured = TRUE;
break; break;
@ -561,13 +563,14 @@
/* move both edges and flag them `locked' */ /* move both edges and flag them `locked' */
if ( cf2_hint_isValid( bottomHintEdge ) ) if ( cf2_hint_isValid( bottomHintEdge ) )
{ {
bottomHintEdge->dsCoord += dsMove; bottomHintEdge->dsCoord = ADD_INT32( bottomHintEdge->dsCoord,
dsMove );
cf2_hint_lock( bottomHintEdge ); cf2_hint_lock( bottomHintEdge );
} }
if ( cf2_hint_isValid( topHintEdge ) ) if ( cf2_hint_isValid( topHintEdge ) )
{ {
topHintEdge->dsCoord += dsMove; topHintEdge->dsCoord = ADD_INT32( topHintEdge->dsCoord, dsMove );
cf2_hint_lock( topHintEdge ); cf2_hint_lock( topHintEdge );
} }
} }

View File

@ -111,7 +111,7 @@ FT_BEGIN_HEADER
* Constant used for hint adjustment and for synthetic em box hint * Constant used for hint adjustment and for synthetic em box hint
* placement. * placement.
*/ */
#define CF2_MIN_COUNTER cf2_floatToFixed( 0.5 ) #define CF2_MIN_COUNTER cf2_doubleToFixed( 0.5 )
/* shared typedef is in cf2glue.h */ /* shared typedef is in cf2glue.h */

View File

@ -63,10 +63,10 @@ FT_BEGIN_HEADER
( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) )
#define cf2_fixedRound( x ) \ #define cf2_fixedRound( x ) \
( (CF2_Fixed)( ( (FT_UInt32)(x) + 0x8000U ) & 0xFFFF0000UL ) ) ( (CF2_Fixed)( ( (FT_UInt32)(x) + 0x8000U ) & 0xFFFF0000UL ) )
#define cf2_floatToFixed( f ) \ #define cf2_doubleToFixed( f ) \
( (CF2_Fixed)( (f) * 65536.0 + 0.5 ) ) ( (CF2_Fixed)( (f) * 65536.0 + 0.5 ) )
#define cf2_fixedAbs( x ) \ #define cf2_fixedAbs( x ) \
( (x) < 0 ? -(x) : (x) ) ( (x) < 0 ? NEG_INT32( x ) : (x) )
#define cf2_fixedFloor( x ) \ #define cf2_fixedFloor( x ) \
( (CF2_Fixed)( (FT_UInt32)(x) & 0xFFFF0000UL ) ) ( (CF2_Fixed)( (FT_UInt32)(x) & 0xFFFF0000UL ) )
#define cf2_fixedFraction( x ) \ #define cf2_fixedFraction( x ) \

View File

@ -117,7 +117,7 @@
return; return;
/* protect against range problems and divide by zero */ /* protect against range problems and divide by zero */
if ( emRatio < cf2_floatToFixed( .01 ) ) if ( emRatio < cf2_doubleToFixed( .01 ) )
return; return;
if ( stemDarkened ) if ( stemDarkened )
@ -447,7 +447,7 @@
/* choose a constant for StdHW that depends on font contrast */ /* choose a constant for StdHW that depends on font contrast */
stdHW = cf2_getStdHW( decoder ); 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 ); font->stdHW = FT_DivFix( cf2_intToFixed( 75 ), emRatio );
else else
{ {

View File

@ -267,8 +267,8 @@
if ( *hinted ) if ( *hinted )
{ {
*x_scale = ( decoder->builder.glyph->x_scale + 32 ) / 64; *x_scale = ADD_INT32( decoder->builder.glyph->x_scale, 32 ) / 64;
*y_scale = ( decoder->builder.glyph->y_scale + 32 ) / 64; *y_scale = ADD_INT32( decoder->builder.glyph->y_scale, 32 ) / 64;
} }
else else
{ {

View File

@ -74,8 +74,8 @@
/* cross product of pt1 position from origin with pt2 position from */ /* cross product of pt1 position from origin with pt2 position from */
/* pt1; we reduce the precision so that the result fits into 32 bits */ /* pt1; we reduce the precision so that the result fits into 32 bits */
return ( x1 >> 16 ) * ( ( y2 - y1 ) >> 16 ) - return ( x1 >> 16 ) * ( SUB_INT32( y2, y1 ) >> 16 ) -
( y1 >> 16 ) * ( ( x2 - x1 ) >> 16 ); ( y1 >> 16 ) * ( SUB_INT32( x2, x1 ) >> 16 );
} }
@ -105,7 +105,7 @@
stemHintArray, stemHintArray,
indexStemHint ); indexStemHint );
width = stemHint->max - stemHint->min; width = SUB_INT32( stemHint->max, stemHint->min );
if ( width == cf2_intToFixed( -21 ) ) if ( width == cf2_intToFixed( -21 ) )
{ {
@ -185,11 +185,11 @@
/* darkening. Bottoms are not changed; tops are incremented by twice */ /* darkening. Bottoms are not changed; tops are incremented by twice */
/* `darkenY'. */ /* `darkenY'. */
if ( cf2_hint_isTop( hint ) ) if ( cf2_hint_isTop( hint ) )
hint->csCoord += 2 * font->darkenY; hint->csCoord = ADD_INT32( hint->csCoord, 2 * font->darkenY );
hint->csCoord += hintOrigin; hint->csCoord = ADD_INT32( hint->csCoord, hintOrigin );
hint->scale = scale; hint->scale = scale;
hint->index = indexStemHint; /* index in original stem hint array */ hint->index = indexStemHint; /* index in original stem hint array */
/* if original stem hint has been used, use the same position */ /* if original stem hint has been used, use the same position */
if ( hint->flags != 0 && stemHint->used ) if ( hint->flags != 0 && stemHint->used )
@ -314,6 +314,7 @@
/* start linear search from last hit */ /* start linear search from last hit */
CF2_UInt i = hintmap->lastIndex; CF2_UInt i = hintmap->lastIndex;
FT_ASSERT( hintmap->lastIndex < CF2_MAX_HINT_EDGES ); FT_ASSERT( hintmap->lastIndex < CF2_MAX_HINT_EDGES );
/* search up */ /* search up */
@ -330,9 +331,10 @@
if ( i == 0 && csCoord < hintmap->edge[0].csCoord ) if ( i == 0 && csCoord < hintmap->edge[0].csCoord )
{ {
/* special case for points below first edge: use uniform scale */ /* special case for points below first edge: use uniform scale */
return FT_MulFix( csCoord - hintmap->edge[0].csCoord, return ADD_INT32( FT_MulFix( SUB_INT32( csCoord,
hintmap->scale ) + hintmap->edge[0].csCoord ),
hintmap->edge[0].dsCoord; hintmap->scale ),
hintmap->edge[0].dsCoord );
} }
else else
{ {
@ -340,9 +342,10 @@
* Note: entries with duplicate csCoord are allowed. * Note: entries with duplicate csCoord are allowed.
* Use edge[i], the highest entry where csCoord >= entry[i].csCoord * Use edge[i], the highest entry where csCoord >= entry[i].csCoord
*/ */
return FT_MulFix( csCoord - hintmap->edge[i].csCoord, return ADD_INT32( FT_MulFix( SUB_INT32( csCoord,
hintmap->edge[i].scale ) + hintmap->edge[i].csCoord ),
hintmap->edge[i].dsCoord; hintmap->edge[i].scale ),
hintmap->edge[i].dsCoord );
} }
} }
} }
@ -437,14 +440,16 @@
/* is there room to move up? */ /* is there room to move up? */
/* there is if we are at top of array or the next edge is at or */ /* there is if we are at top of array or the next edge is at or */
/* beyond proposed move up? */ /* beyond proposed move up? */
if ( j >= hintmap->count - 1 || if ( j >= hintmap->count - 1 ||
hintmap->edge[j + 1].dsCoord >= 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? */ /* 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 - 1].dsCoord <=
hintmap->edge[i].dsCoord + moveDown - downMinCounter ) ADD_INT32( hintmap->edge[i].dsCoord,
moveDown - downMinCounter ) )
{ {
/* move smaller absolute amount */ /* move smaller absolute amount */
move = ( -moveDown < moveUp ) ? moveDown : moveUp; /* optimum */ move = ( -moveDown < moveUp ) ? moveDown : moveUp; /* optimum */
@ -455,9 +460,10 @@
else else
{ {
/* is there room to move down? */ /* is there room to move down? */
if ( i == 0 || if ( i == 0 ||
hintmap->edge[i - 1].dsCoord <= hintmap->edge[i - 1].dsCoord <=
hintmap->edge[i].dsCoord + moveDown - downMinCounter ) ADD_INT32( hintmap->edge[i].dsCoord,
moveDown - downMinCounter ) )
{ {
move = moveDown; move = moveDown;
/* true if non-optimum move */ /* true if non-optimum move */
@ -491,9 +497,11 @@
} }
/* move the edge(s) */ /* move the edge(s) */
hintmap->edge[i].dsCoord += move; hintmap->edge[i].dsCoord = ADD_INT32( hintmap->edge[i].dsCoord,
move );
if ( isPair ) 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 */ /* assert there are no overlaps in device space */
@ -507,18 +515,20 @@
{ {
if ( hintmap->edge[i].csCoord != hintmap->edge[i - 1].csCoord ) if ( hintmap->edge[i].csCoord != hintmap->edge[i - 1].csCoord )
hintmap->edge[i - 1].scale = hintmap->edge[i - 1].scale =
FT_DivFix( FT_DivFix( SUB_INT32( hintmap->edge[i].dsCoord,
hintmap->edge[i].dsCoord - hintmap->edge[i - 1].dsCoord, hintmap->edge[i - 1].dsCoord ),
hintmap->edge[i].csCoord - hintmap->edge[i - 1].csCoord ); SUB_INT32( hintmap->edge[i].csCoord,
hintmap->edge[i - 1].csCoord ) );
} }
if ( isPair ) if ( isPair )
{ {
if ( hintmap->edge[j].csCoord != hintmap->edge[j - 1].csCoord ) if ( hintmap->edge[j].csCoord != hintmap->edge[j - 1].csCoord )
hintmap->edge[j - 1].scale = hintmap->edge[j - 1].scale =
FT_DivFix( FT_DivFix( SUB_INT32( hintmap->edge[j].dsCoord,
hintmap->edge[j].dsCoord - hintmap->edge[j - 1].dsCoord, hintmap->edge[j - 1].dsCoord ),
hintmap->edge[j].csCoord - hintmap->edge[j - 1].csCoord ); SUB_INT32( hintmap->edge[j].csCoord,
hintmap->edge[j - 1].csCoord ) );
i += 1; /* skip upper edge on next loop */ i += 1; /* skip upper edge on next loop */
} }
@ -539,15 +549,18 @@
/* is there room to move up? */ /* is there room to move up? */
if ( hintmap->edge[j + 1].dsCoord >= 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 */ /* 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] ) ) if ( cf2_hint_isPair( &hintmap->edge[j] ) )
{ {
FT_ASSERT( j > 0 ); 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 */ /* Use hint map to position the center of stem, and nominal scale */
/* to position the two edges. This preserves the stem width. */ /* to position the two edges. This preserves the stem width. */
CF2_Fixed midpoint = cf2_hintmap_map( CF2_Fixed midpoint =
hintmap->initialHintMap, cf2_hintmap_map(
( secondHintEdge->csCoord + hintmap->initialHintMap,
firstHintEdge->csCoord ) / 2 ); ADD_INT32( secondHintEdge->csCoord,
CF2_Fixed halfWidth = FT_MulFix( firstHintEdge->csCoord ) / 2 );
( secondHintEdge->csCoord - CF2_Fixed halfWidth =
firstHintEdge->csCoord ) / 2, FT_MulFix( SUB_INT32( secondHintEdge->csCoord,
hintmap->scale ); firstHintEdge->csCoord ) / 2,
hintmap->scale );
firstHintEdge->dsCoord = midpoint - halfWidth; firstHintEdge->dsCoord = SUB_INT32( midpoint, halfWidth );
secondHintEdge->dsCoord = midpoint + halfWidth; secondHintEdge->dsCoord = ADD_INT32( midpoint, halfWidth );
} }
else else
firstHintEdge->dsCoord = cf2_hintmap_map( hintmap->initialHintMap, firstHintEdge->dsCoord = cf2_hintmap_map( hintmap->initialHintMap,
@ -715,7 +729,7 @@
/* insert first edge */ /* insert first edge */
hintmap->edge[indexInsert] = *firstHintEdge; /* copy struct */ hintmap->edge[indexInsert] = *firstHintEdge; /* copy struct */
hintmap->count += 1; hintmap->count += 1;
if ( isPair ) if ( isPair )
{ {
@ -781,7 +795,7 @@
cf2_arrstack_size( hStemHintArray ) + cf2_arrstack_size( hStemHintArray ) +
cf2_arrstack_size( vStemHintArray ) ); cf2_arrstack_size( vStemHintArray ) );
if ( !cf2_hintmask_isValid( hintMask ) ) if ( !cf2_hintmask_isValid( hintMask ) )
return; /* too many stem hints */ return; /* too many stem hints */
} }
/* begin by clearing the map */ /* begin by clearing the map */
@ -797,7 +811,7 @@
/* Defense-in-depth. Should never return here. */ /* Defense-in-depth. Should never return here. */
if ( bitCount > hintMask->bitCount ) if ( bitCount > hintMask->bitCount )
return; return;
/* synthetic embox hints get highest priority */ /* synthetic embox hints get highest priority */
if ( font->blues.doEmBoxHints ) if ( font->blues.doEmBoxHints )
@ -1063,7 +1077,7 @@
cf2_fixedAbs( glyphpath->yOffset ) ); cf2_fixedAbs( glyphpath->yOffset ) );
/* .1 character space unit */ /* .1 character space unit */
glyphpath->snapThreshold = cf2_floatToFixed( 0.1f ); glyphpath->snapThreshold = cf2_doubleToFixed( 0.1 );
glyphpath->moveIsPending = TRUE; glyphpath->moveIsPending = TRUE;
glyphpath->pathIsOpen = FALSE; glyphpath->pathIsOpen = FALSE;
@ -1095,16 +1109,20 @@
FT_Vector pt; /* hinted point in upright DS */ FT_Vector pt; /* hinted point in upright DS */
pt.x = FT_MulFix( glyphpath->scaleX, x ) + pt.x = ADD_INT32( FT_MulFix( glyphpath->scaleX, x ),
FT_MulFix( glyphpath->scaleC, y ); FT_MulFix( glyphpath->scaleC, y ) );
pt.y = cf2_hintmap_map( hintmap, y ); pt.y = cf2_hintmap_map( hintmap, y );
ppt->x = FT_MulFix( glyphpath->font->outerTransform.a, pt.x ) + ppt->x = ADD_INT32(
FT_MulFix( glyphpath->font->outerTransform.c, pt.y ) + FT_MulFix( glyphpath->font->outerTransform.a, pt.x ),
glyphpath->fractionalTranslation.x; ADD_INT32(
ppt->y = FT_MulFix( glyphpath->font->outerTransform.b, pt.x ) + FT_MulFix( glyphpath->font->outerTransform.c, pt.y ),
FT_MulFix( glyphpath->font->outerTransform.d, pt.y ) + glyphpath->fractionalTranslation.x ) );
glyphpath->fractionalTranslation.y; 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; CF2_Fixed denominator, s;
u.x = CF2_CS_SCALE( u2->x - u1->x ); u.x = CF2_CS_SCALE( SUB_INT32( u2->x, u1->x ) );
u.y = CF2_CS_SCALE( u2->y - u1->y ); u.y = CF2_CS_SCALE( SUB_INT32( u2->y, u1->y ) );
v.x = CF2_CS_SCALE( v2->x - v1->x ); v.x = CF2_CS_SCALE( SUB_INT32( v2->x, v1->x ) );
v.y = CF2_CS_SCALE( v2->y - v1->y ); v.y = CF2_CS_SCALE( SUB_INT32( v2->y, v1->y ) );
w.x = CF2_CS_SCALE( v1->x - u1->x ); w.x = CF2_CS_SCALE( SUB_INT32( v1->x, u1->x ) );
w.y = CF2_CS_SCALE( v1->y - u1->y ); w.y = CF2_CS_SCALE( SUB_INT32( v1->y, u1->y ) );
denominator = cf2_perp( u, v ); denominator = cf2_perp( u, v );
@ -1168,8 +1186,11 @@
s = FT_DivFix( cf2_perp( w, v ), denominator ); s = FT_DivFix( cf2_perp( w, v ), denominator );
intersection->x = u1->x + FT_MulFix( s, u2->x - u1->x ); intersection->x = ADD_INT32( u1->x,
intersection->y = u1->y + FT_MulFix( s, u2->y - u1->y ); 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. * Special case snapping for horizontal and vertical lines.
@ -1180,25 +1201,29 @@
* *
*/ */
if ( u1->x == u2->x && if ( u1->x == u2->x &&
cf2_fixedAbs( intersection->x - u1->x ) < glyphpath->snapThreshold ) cf2_fixedAbs( SUB_INT32( intersection->x,
u1->x ) ) < glyphpath->snapThreshold )
intersection->x = u1->x; intersection->x = u1->x;
if ( u1->y == u2->y && if ( u1->y == u2->y &&
cf2_fixedAbs( intersection->y - u1->y ) < glyphpath->snapThreshold ) cf2_fixedAbs( SUB_INT32( intersection->y,
u1->y ) ) < glyphpath->snapThreshold )
intersection->y = u1->y; intersection->y = u1->y;
if ( v1->x == v2->x && if ( v1->x == v2->x &&
cf2_fixedAbs( intersection->x - v1->x ) < glyphpath->snapThreshold ) cf2_fixedAbs( SUB_INT32( intersection->x,
v1->x ) ) < glyphpath->snapThreshold )
intersection->x = v1->x; intersection->x = v1->x;
if ( v1->y == v2->y && if ( v1->y == v2->y &&
cf2_fixedAbs( intersection->y - v1->y ) < glyphpath->snapThreshold ) cf2_fixedAbs( SUB_INT32( intersection->y,
v1->y ) ) < glyphpath->snapThreshold )
intersection->y = v1->y; intersection->y = v1->y;
/* limit the intersection distance from midpoint of u2 and v1 */ /* limit the intersection distance from midpoint of u2 and v1 */
if ( cf2_fixedAbs( intersection->x - ( u2->x + v1->x ) / 2 ) > if ( cf2_fixedAbs( intersection->x - ADD_INT32( u2->x, v1->x ) / 2 ) >
glyphpath->miterLimit || glyphpath->miterLimit ||
cf2_fixedAbs( intersection->y - ( u2->y + v1->y ) / 2 ) > cf2_fixedAbs( intersection->y - ADD_INT32( u2->y, v1->y ) / 2 ) >
glyphpath->miterLimit ) glyphpath->miterLimit )
return FALSE; return FALSE;
return TRUE; return TRUE;
@ -1446,16 +1471,16 @@
CF2_Fixed* x, CF2_Fixed* x,
CF2_Fixed* y ) CF2_Fixed* y )
{ {
CF2_Fixed dx = x2 - x1; CF2_Fixed dx = SUB_INT32( x2, x1 );
CF2_Fixed dy = y2 - y1; CF2_Fixed dy = SUB_INT32( y2, y1 );
/* note: negative offsets don't work here; negate deltas to change */ /* note: negative offsets don't work here; negate deltas to change */
/* quadrants, below */ /* quadrants, below */
if ( glyphpath->font->reverseWinding ) if ( glyphpath->font->reverseWinding )
{ {
dx = -dx; dx = NEG_INT32( dx );
dy = -dy; dy = NEG_INT32( dy );
} }
*x = *y = 0; *x = *y = 0;
@ -1464,8 +1489,9 @@
return; return;
/* add momentum for this path element */ /* add momentum for this path element */
glyphpath->callbacks->windingMomentum += glyphpath->callbacks->windingMomentum =
cf2_getWindingMomentum( x1, y1, x2, y2 ); ADD_INT32( glyphpath->callbacks->windingMomentum,
cf2_getWindingMomentum( x1, y1, x2, y2 ) );
/* note: allow mixed integer and fixed multiplication here */ /* note: allow mixed integer and fixed multiplication here */
if ( dx >= 0 ) if ( dx >= 0 )
@ -1474,13 +1500,13 @@
{ {
/* first quadrant, +x +y */ /* first quadrant, +x +y */
if ( dx > 2 * dy ) if ( dx > MUL_INT32( 2, dy ) )
{ {
/* +x */ /* +x */
*x = 0; *x = 0;
*y = 0; *y = 0;
} }
else if ( dy > 2 * dx ) else if ( dy > MUL_INT32( 2, dx ) )
{ {
/* +y */ /* +y */
*x = glyphpath->xOffset; *x = glyphpath->xOffset;
@ -1489,9 +1515,9 @@
else else
{ {
/* +x +y */ /* +x +y */
*x = FT_MulFix( cf2_floatToFixed( 0.7 ), *x = FT_MulFix( cf2_doubleToFixed( 0.7 ),
glyphpath->xOffset ); glyphpath->xOffset );
*y = FT_MulFix( cf2_floatToFixed( 1.0 - 0.7 ), *y = FT_MulFix( cf2_doubleToFixed( 1.0 - 0.7 ),
glyphpath->yOffset ); glyphpath->yOffset );
} }
} }
@ -1499,24 +1525,24 @@
{ {
/* fourth quadrant, +x -y */ /* fourth quadrant, +x -y */
if ( dx > -2 * dy ) if ( dx > MUL_INT32( -2, dy ) )
{ {
/* +x */ /* +x */
*x = 0; *x = 0;
*y = 0; *y = 0;
} }
else if ( -dy > 2 * dx ) else if ( NEG_INT32( dy ) > MUL_INT32( 2, dx ) )
{ {
/* -y */ /* -y */
*x = -glyphpath->xOffset; *x = NEG_INT32( glyphpath->xOffset );
*y = glyphpath->yOffset; *y = glyphpath->yOffset;
} }
else else
{ {
/* +x -y */ /* +x -y */
*x = FT_MulFix( cf2_floatToFixed( -0.7 ), *x = FT_MulFix( cf2_doubleToFixed( -0.7 ),
glyphpath->xOffset ); glyphpath->xOffset );
*y = FT_MulFix( cf2_floatToFixed( 1.0 - 0.7 ), *y = FT_MulFix( cf2_doubleToFixed( 1.0 - 0.7 ),
glyphpath->yOffset ); glyphpath->yOffset );
} }
} }
@ -1527,13 +1553,13 @@
{ {
/* second quadrant, -x +y */ /* second quadrant, -x +y */
if ( -dx > 2 * dy ) if ( NEG_INT32( dx ) > MUL_INT32( 2, dy ) )
{ {
/* -x */ /* -x */
*x = 0; *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 */ /* +y */
*x = glyphpath->xOffset; *x = glyphpath->xOffset;
@ -1542,9 +1568,9 @@
else else
{ {
/* -x +y */ /* -x +y */
*x = FT_MulFix( cf2_floatToFixed( 0.7 ), *x = FT_MulFix( cf2_doubleToFixed( 0.7 ),
glyphpath->xOffset ); glyphpath->xOffset );
*y = FT_MulFix( cf2_floatToFixed( 1.0 + 0.7 ), *y = FT_MulFix( cf2_doubleToFixed( 1.0 + 0.7 ),
glyphpath->yOffset ); glyphpath->yOffset );
} }
} }
@ -1552,24 +1578,24 @@
{ {
/* third quadrant, -x -y */ /* third quadrant, -x -y */
if ( -dx > -2 * dy ) if ( NEG_INT32( dx ) > MUL_INT32( -2, dy ) )
{ {
/* -x */ /* -x */
*x = 0; *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 */ /* -y */
*x = -glyphpath->xOffset; *x = NEG_INT32( glyphpath->xOffset );
*y = glyphpath->yOffset; *y = glyphpath->yOffset;
} }
else else
{ {
/* -x -y */ /* -x -y */
*x = FT_MulFix( cf2_floatToFixed( -0.7 ), *x = FT_MulFix( cf2_doubleToFixed( -0.7 ),
glyphpath->xOffset ); glyphpath->xOffset );
*y = FT_MulFix( cf2_floatToFixed( 1.0 + 0.7 ), *y = FT_MulFix( cf2_doubleToFixed( 1.0 + 0.7 ),
glyphpath->yOffset ); glyphpath->yOffset );
} }
} }
@ -1675,10 +1701,10 @@
&yOffset ); &yOffset );
/* construct offset points */ /* construct offset points */
P0.x = glyphpath->currentCS.x + xOffset; P0.x = ADD_INT32( glyphpath->currentCS.x, xOffset );
P0.y = glyphpath->currentCS.y + yOffset; P0.y = ADD_INT32( glyphpath->currentCS.y, yOffset );
P1.x = x + xOffset; P1.x = ADD_INT32( x, xOffset );
P1.y = y + yOffset; P1.y = ADD_INT32( y, yOffset );
if ( glyphpath->moveIsPending ) if ( glyphpath->moveIsPending )
{ {
@ -1753,19 +1779,20 @@
&yOffset3 ); &yOffset3 );
/* add momentum from the middle segment */ /* add momentum from the middle segment */
glyphpath->callbacks->windingMomentum += glyphpath->callbacks->windingMomentum =
cf2_getWindingMomentum( x1, y1, x2, y2 ); ADD_INT32( glyphpath->callbacks->windingMomentum,
cf2_getWindingMomentum( x1, y1, x2, y2 ) );
/* construct offset points */ /* construct offset points */
P0.x = glyphpath->currentCS.x + xOffset1; P0.x = ADD_INT32( glyphpath->currentCS.x, xOffset1 );
P0.y = glyphpath->currentCS.y + yOffset1; P0.y = ADD_INT32( glyphpath->currentCS.y, yOffset1 );
P1.x = x1 + xOffset1; P1.x = ADD_INT32( x1, xOffset1 );
P1.y = y1 + yOffset1; P1.y = ADD_INT32( y1, yOffset1 );
/* note: preserve angle of final segment by using offset3 at both ends */ /* note: preserve angle of final segment by using offset3 at both ends */
P2.x = x2 + xOffset3; P2.x = ADD_INT32( x2, xOffset3 );
P2.y = y2 + yOffset3; P2.y = ADD_INT32( y2, yOffset3 );
P3.x = x3 + xOffset3; P3.x = ADD_INT32( x3, xOffset3 );
P3.y = y3 + yOffset3; P3.y = ADD_INT32( y3, yOffset3 );
if ( glyphpath->moveIsPending ) if ( glyphpath->moveIsPending )
{ {

View File

@ -304,10 +304,12 @@
CF2_StemHintRec stemhint; CF2_StemHintRec stemhint;
stemhint.min = stemhint.min =
position += cf2_stack_getReal( opStack, i ); position = ADD_INT32( position,
stemhint.max = cf2_stack_getReal( opStack, i ) );
position += cf2_stack_getReal( opStack, i + 1 ); stemhint.max =
position = ADD_INT32( position,
cf2_stack_getReal( opStack, i + 1 ) );
stemhint.used = FALSE; stemhint.used = FALSE;
stemhint.maxDS = stemhint.maxDS =
@ -348,7 +350,8 @@
{ {
vals[i + 2] = vals[i]; vals[i + 2] = vals[i];
if ( readFromStack[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 ) if ( isHFlex )
@ -356,31 +359,34 @@
if ( doConditionalLastRead ) if ( doConditionalLastRead )
{ {
FT_Bool lastIsX = (FT_Bool)( cf2_fixedAbs( vals[10] - *curX ) > FT_Bool lastIsX = (FT_Bool)(
cf2_fixedAbs( vals[11] - *curY ) ); cf2_fixedAbs( SUB_INT32( vals[10], *curX ) ) >
cf2_fixedAbs( SUB_INT32( vals[11], *curY ) ) );
CF2_Fixed lastVal = cf2_stack_getReal( opStack, idx ); CF2_Fixed lastVal = cf2_stack_getReal( opStack, idx );
if ( lastIsX ) if ( lastIsX )
{ {
vals[12] = vals[10] + lastVal; vals[12] = ADD_INT32( vals[10], lastVal );
vals[13] = *curY; vals[13] = *curY;
} }
else else
{ {
vals[12] = *curX; vals[12] = *curX;
vals[13] = vals[11] + lastVal; vals[13] = ADD_INT32( vals[11], lastVal );
} }
} }
else else
{ {
if ( readFromStack[10] ) if ( readFromStack[10] )
vals[12] = vals[10] + cf2_stack_getReal( opStack, idx++ ); vals[12] = ADD_INT32( vals[10],
cf2_stack_getReal( opStack, idx++ ) );
else else
vals[12] = *curX; vals[12] = *curX;
if ( readFromStack[11] ) if ( readFromStack[11] )
vals[13] = vals[11] + cf2_stack_getReal( opStack, idx ); vals[13] = ADD_INT32( vals[11],
cf2_stack_getReal( opStack, idx ) );
else else
vals[13] = *curY; vals[13] = *curY;
} }
@ -426,7 +432,10 @@
for ( j = 1; j < blend->lenBV; j++ ) 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 */ /* store blended result */
cf2_stack_setReal( opStack, i + base, sum ); cf2_stack_setReal( opStack, i + base, sum );
@ -759,7 +768,8 @@
FT_TRACE4(( " vmoveto\n" )); FT_TRACE4(( " vmoveto\n" ));
if ( cf2_stack_count( opStack ) > 1 && !haveWidth ) 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 */ /* width is defined or default after this */
haveWidth = TRUE; haveWidth = TRUE;
@ -767,7 +777,7 @@
if ( font->decoder->width_only ) if ( font->decoder->width_only )
goto exit; goto exit;
curY += cf2_stack_popFixed( opStack ); curY = ADD_INT32( curY, cf2_stack_popFixed( opStack ) );
cf2_glyphpath_moveTo( &glyphPath, curX, curY ); cf2_glyphpath_moveTo( &glyphPath, curX, curY );
@ -783,8 +793,10 @@
for ( idx = 0; idx < count; idx += 2 ) for ( idx = 0; idx < count; idx += 2 )
{ {
curX += cf2_stack_getReal( opStack, idx + 0 ); curX = ADD_INT32( curX, cf2_stack_getReal( opStack,
curY += cf2_stack_getReal( opStack, idx + 1 ); idx + 0 ) );
curY = ADD_INT32( curY, cf2_stack_getReal( opStack,
idx + 1 ) );
cf2_glyphpath_lineTo( &glyphPath, curX, curY ); cf2_glyphpath_lineTo( &glyphPath, curX, curY );
} }
@ -810,9 +822,9 @@
if ( isX ) if ( isX )
curX += v; curX = ADD_INT32( curX, v );
else else
curY += v; curY = ADD_INT32( curY, v );
isX = !isX; isX = !isX;
@ -835,14 +847,16 @@
while ( idx + 6 <= count ) while ( idx + 6 <= count )
{ {
CF2_Fixed x1 = cf2_stack_getReal( opStack, idx + 0 ) + curX; CF2_Fixed x1, y1, x2, y2, x3, y3;
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;
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 ); cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
curX = x3; curX = x3;
@ -852,8 +866,10 @@
if ( op1 == cf2_cmdRCURVELINE ) if ( op1 == cf2_cmdRCURVELINE )
{ {
curX += cf2_stack_getReal( opStack, idx + 0 ); curX = ADD_INT32( curX, cf2_stack_getReal( opStack,
curY += cf2_stack_getReal( opStack, idx + 1 ); idx + 0 ) );
curY = ADD_INT32( curY, cf2_stack_getReal( opStack,
idx + 1 ) );
cf2_glyphpath_lineTo( &glyphPath, curX, curY ); cf2_glyphpath_lineTo( &glyphPath, curX, curY );
} }
@ -1129,7 +1145,10 @@
arg = cf2_stack_popFixed( opStack ); 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 */ continue; /* do not clear the stack */
@ -1144,7 +1163,9 @@
summand2 = cf2_stack_popFixed( opStack ); summand2 = cf2_stack_popFixed( opStack );
summand1 = 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 */ continue; /* do not clear the stack */
@ -1159,7 +1180,8 @@
subtrahend = cf2_stack_popFixed( opStack ); subtrahend = cf2_stack_popFixed( opStack );
minuend = 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 */ continue; /* do not clear the stack */
@ -1174,7 +1196,8 @@
divisor = cf2_stack_popFixed( opStack ); divisor = cf2_stack_popFixed( opStack );
dividend = 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 */ continue; /* do not clear the stack */
@ -1187,7 +1210,10 @@
arg = cf2_stack_popFixed( opStack ); 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 */ continue; /* do not clear the stack */
@ -1257,7 +1283,8 @@
arg2 = cf2_stack_popFixed( opStack ); arg2 = cf2_stack_popFixed( opStack );
arg1 = 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 */ continue; /* do not clear the stack */
@ -1291,7 +1318,8 @@
factor2 = cf2_stack_popFixed( opStack ); factor2 = cf2_stack_popFixed( opStack );
factor1 = 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 */ continue; /* do not clear the stack */
@ -1305,7 +1333,9 @@
arg = cf2_stack_popFixed( opStack ); arg = cf2_stack_popFixed( opStack );
if ( arg > 0 ) 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; FT_Fixed new_root;
@ -1369,7 +1399,8 @@
if ( size > 0 ) 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; CF2_UInt gr_idx;
@ -1381,7 +1412,8 @@
gr_idx = size - 1 - (CF2_UInt)idx; gr_idx = size - 1 - (CF2_UInt)idx;
cf2_stack_pushFixed( opStack, cf2_stack_pushFixed( opStack,
cf2_stack_getReal( opStack, gr_idx ) ); cf2_stack_getReal( opStack,
gr_idx ) );
} }
} }
continue; /* do not clear the stack */ continue; /* do not clear the stack */
@ -1416,7 +1448,8 @@
cf2_stack_count( opStack ) == 5 ) cf2_stack_count( opStack ) == 5 )
{ {
if ( !haveWidth ) 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 */ /* width is defined or default after this */
@ -1564,7 +1597,8 @@
FT_TRACE4(( " rmoveto\n" )); FT_TRACE4(( " rmoveto\n" ));
if ( cf2_stack_count( opStack ) > 2 && !haveWidth ) 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 */ /* width is defined or default after this */
haveWidth = TRUE; haveWidth = TRUE;
@ -1572,8 +1606,8 @@
if ( font->decoder->width_only ) if ( font->decoder->width_only )
goto exit; goto exit;
curY += cf2_stack_popFixed( opStack ); curY = ADD_INT32( curY, cf2_stack_popFixed( opStack ) );
curX += cf2_stack_popFixed( opStack ); curX = ADD_INT32( curX, cf2_stack_popFixed( opStack ) );
cf2_glyphpath_moveTo( &glyphPath, curX, curY ); cf2_glyphpath_moveTo( &glyphPath, curX, curY );
@ -1583,7 +1617,8 @@
FT_TRACE4(( " hmoveto\n" )); FT_TRACE4(( " hmoveto\n" ));
if ( cf2_stack_count( opStack ) > 1 && !haveWidth ) 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 */ /* width is defined or default after this */
haveWidth = TRUE; haveWidth = TRUE;
@ -1591,7 +1626,7 @@
if ( font->decoder->width_only ) if ( font->decoder->width_only )
goto exit; goto exit;
curX += cf2_stack_popFixed( opStack ); curX = ADD_INT32( curX, cf2_stack_popFixed( opStack ) );
cf2_glyphpath_moveTo( &glyphPath, curX, curY ); cf2_glyphpath_moveTo( &glyphPath, curX, curY );
@ -1607,8 +1642,10 @@
while ( idx + 6 < count ) while ( idx + 6 < count )
{ {
curX += cf2_stack_getReal( opStack, idx + 0 ); curX = ADD_INT32( curX, cf2_stack_getReal( opStack,
curY += cf2_stack_getReal( opStack, idx + 1 ); idx + 0 ) );
curY = ADD_INT32( curY, cf2_stack_getReal( opStack,
idx + 1 ) );
cf2_glyphpath_lineTo( &glyphPath, curX, curY ); cf2_glyphpath_lineTo( &glyphPath, curX, curY );
idx += 2; idx += 2;
@ -1616,14 +1653,16 @@
while ( idx < count ) while ( idx < count )
{ {
CF2_Fixed x1 = cf2_stack_getReal( opStack, idx + 0 ) + curX; CF2_Fixed x1, y1, x2, y2, x3, y3;
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;
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 ); cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
curX = x3; curX = x3;
@ -1656,18 +1695,18 @@
if ( ( count - idx ) & 1 ) if ( ( count - idx ) & 1 )
{ {
x1 = cf2_stack_getReal( opStack, idx ) + curX; x1 = ADD_INT32( cf2_stack_getReal( opStack, idx ), curX );
idx++; idx++;
} }
else else
x1 = curX; x1 = curX;
y1 = cf2_stack_getReal( opStack, idx + 0 ) + curY; y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curY );
x2 = cf2_stack_getReal( opStack, idx + 1 ) + x1; x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 );
y2 = cf2_stack_getReal( opStack, idx + 2 ) + y1; y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 );
x3 = x2; 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 ); cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
@ -1701,17 +1740,17 @@
if ( ( count - idx ) & 1 ) if ( ( count - idx ) & 1 )
{ {
y1 = cf2_stack_getReal( opStack, idx ) + curY; y1 = ADD_INT32( cf2_stack_getReal( opStack, idx ), curY );
idx++; idx++;
} }
else else
y1 = curY; y1 = curY;
x1 = cf2_stack_getReal( opStack, idx + 0 ) + curX; x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX );
x2 = cf2_stack_getReal( opStack, idx + 1 ) + x1; x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 );
y2 = cf2_stack_getReal( opStack, idx + 2 ) + y1; y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 );
x3 = cf2_stack_getReal( opStack, idx + 3 ) + x2; x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), x2 );
y3 = y2; y3 = y2;
cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
@ -1750,15 +1789,15 @@
if ( alternate ) if ( alternate )
{ {
x1 = cf2_stack_getReal( opStack, idx + 0 ) + curX; x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX );
y1 = curY; y1 = curY;
x2 = cf2_stack_getReal( opStack, idx + 1 ) + x1; x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 );
y2 = cf2_stack_getReal( opStack, idx + 2 ) + y1; y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 );
y3 = cf2_stack_getReal( opStack, idx + 3 ) + y2; y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y2 );
if ( count - idx == 5 ) if ( count - idx == 5 )
{ {
x3 = cf2_stack_getReal( opStack, idx + 4 ) + x2; x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), x2 );
idx++; idx++;
} }
@ -1770,14 +1809,14 @@
else else
{ {
x1 = curX; x1 = curX;
y1 = cf2_stack_getReal( opStack, idx + 0 ) + curY; y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curY );
x2 = cf2_stack_getReal( opStack, idx + 1 ) + x1; x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 );
y2 = cf2_stack_getReal( opStack, idx + 2 ) + y1; y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 );
x3 = cf2_stack_getReal( opStack, idx + 3 ) + x2; x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), x2 );
if ( count - idx == 5 ) if ( count - idx == 5 )
{ {
y3 = cf2_stack_getReal( opStack, idx + 4 ) + y2; y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), y2 );
idx++; idx++;
} }

View File

@ -20,6 +20,7 @@
#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H #include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_SFNT_H #include FT_INTERNAL_SFNT_H
#include FT_INTERNAL_CALC_H
#include FT_OUTLINE_H #include FT_OUTLINE_H
#include FT_CFF_DRIVER_H #include FT_CFF_DRIVER_H
@ -1450,8 +1451,8 @@
cff_builder_close_contour( builder ); cff_builder_close_contour( builder );
builder->path_begun = 0; builder->path_begun = 0;
x += args[-2]; x = ADD_LONG( x, args[-2] );
y += args[-1]; y = ADD_LONG( y, args[-1] );
args = stack; args = stack;
break; break;
@ -1460,7 +1461,7 @@
cff_builder_close_contour( builder ); cff_builder_close_contour( builder );
builder->path_begun = 0; builder->path_begun = 0;
y += args[-1]; y = ADD_LONG( y, args[-1] );
args = stack; args = stack;
break; break;
@ -1469,7 +1470,7 @@
cff_builder_close_contour( builder ); cff_builder_close_contour( builder );
builder->path_begun = 0; builder->path_begun = 0;
x += args[-1]; x = ADD_LONG( x, args[-1] );
args = stack; args = stack;
break; break;
@ -1486,8 +1487,8 @@
args -= num_args & ~1; args -= num_args & ~1;
while ( args < decoder->top ) while ( args < decoder->top )
{ {
x += args[0]; x = ADD_LONG( x, args[0] );
y += args[1]; y = ADD_LONG( y, args[1] );
cff_builder_add_point( builder, x, y, 1 ); cff_builder_add_point( builder, x, y, 1 );
args += 2; args += 2;
} }
@ -1519,9 +1520,9 @@
while ( args < decoder->top ) while ( args < decoder->top )
{ {
if ( phase ) if ( phase )
x += args[0]; x = ADD_LONG( x, args[0] );
else else
y += args[0]; y = ADD_LONG( y, args[0] );
if ( cff_builder_add_point1( builder, x, y ) ) if ( cff_builder_add_point1( builder, x, y ) )
goto Fail; goto Fail;
@ -1552,15 +1553,18 @@
args -= nargs; args -= nargs;
while ( args < decoder->top ) while ( args < decoder->top )
{ {
x += args[0]; x = ADD_LONG( x, args[0] );
y += args[1]; y = ADD_LONG( y, args[1] );
cff_builder_add_point( builder, x, y, 0 ); 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 ); 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 ); cff_builder_add_point( builder, x, y, 1 );
args += 6; args += 6;
} }
args = stack; args = stack;
@ -1589,7 +1593,7 @@
if ( nargs & 1 ) if ( nargs & 1 )
{ {
x += args[0]; x = ADD_LONG( x, args[0] );
args++; args++;
nargs--; nargs--;
} }
@ -1599,13 +1603,16 @@
while ( args < decoder->top ) while ( args < decoder->top )
{ {
y += args[0]; y = ADD_LONG( y, args[0] );
cff_builder_add_point( builder, x, y, 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 ); 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 ); cff_builder_add_point( builder, x, y, 1 );
args += 4; args += 4;
} }
args = stack; args = stack;
@ -1633,7 +1640,7 @@
args -= nargs; args -= nargs;
if ( nargs & 1 ) if ( nargs & 1 )
{ {
y += args[0]; y = ADD_LONG( y, args[0] );
args++; args++;
nargs--; nargs--;
} }
@ -1643,13 +1650,16 @@
while ( args < decoder->top ) while ( args < decoder->top )
{ {
x += args[0]; x = ADD_LONG( x, args[0] );
cff_builder_add_point( builder, x, y, 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 ); 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 ); cff_builder_add_point( builder, x, y, 1 );
args += 4; args += 4;
} }
args = stack; args = stack;
@ -1688,26 +1698,30 @@
nargs -= 4; nargs -= 4;
if ( phase ) if ( phase )
{ {
x += args[0]; x = ADD_LONG( x, args[0] );
cff_builder_add_point( builder, x, y, 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 ); cff_builder_add_point( builder, x, y, 0 );
y += args[3];
y = ADD_LONG( y, args[3] );
if ( nargs == 1 ) if ( nargs == 1 )
x += args[4]; x = ADD_LONG( x, args[4] );
cff_builder_add_point( builder, x, y, 1 ); cff_builder_add_point( builder, x, y, 1 );
} }
else else
{ {
y += args[0]; y = ADD_LONG( y, args[0] );
cff_builder_add_point( builder, x, y, 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 ); cff_builder_add_point( builder, x, y, 0 );
x += args[3];
x = ADD_LONG( x, args[3] );
if ( nargs == 1 ) if ( nargs == 1 )
y += args[4]; y = ADD_LONG( y, args[4] );
cff_builder_add_point( builder, x, y, 1 ); cff_builder_add_point( builder, x, y, 1 );
} }
args += 4; args += 4;
@ -1740,23 +1754,27 @@
/* first, add the line segments */ /* first, add the line segments */
while ( num_lines > 0 ) while ( num_lines > 0 )
{ {
x += args[0]; x = ADD_LONG( x, args[0] );
y += args[1]; y = ADD_LONG( y, args[1] );
cff_builder_add_point( builder, x, y, 1 ); cff_builder_add_point( builder, x, y, 1 );
args += 2; args += 2;
num_lines--; num_lines--;
} }
/* then the curve */ /* then the curve */
x += args[0]; x = ADD_LONG( x, args[0] );
y += args[1]; y = ADD_LONG( y, args[1] );
cff_builder_add_point( builder, x, y, 0 ); 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 ); 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 ); cff_builder_add_point( builder, x, y, 1 );
args = stack; args = stack;
} }
break; break;
@ -1785,23 +1803,27 @@
/* first, add the curves */ /* first, add the curves */
while ( num_curves > 0 ) while ( num_curves > 0 )
{ {
x += args[0]; x = ADD_LONG( x, args[0] );
y += args[1]; y = ADD_LONG( y, args[1] );
cff_builder_add_point( builder, x, y, 0 ); 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 ); 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 ); cff_builder_add_point( builder, x, y, 1 );
args += 6; args += 6;
num_curves--; num_curves--;
} }
/* then the final line */ /* then the final line */
x += args[0]; x = ADD_LONG( x, args[0] );
y += args[1]; y = ADD_LONG( y, args[1] );
cff_builder_add_point( builder, x, y, 1 ); cff_builder_add_point( builder, x, y, 1 );
args = stack; args = stack;
} }
break; break;
@ -1824,33 +1846,33 @@
start_y = y; start_y = y;
/* first control point */ /* first control point */
x += args[0]; x = ADD_LONG( x, args[0] );
y += args[1]; y = ADD_LONG( y, args[1] );
cff_builder_add_point( builder, x, y, 0 ); cff_builder_add_point( builder, x, y, 0 );
/* second control point */ /* second control point */
x += args[2]; x = ADD_LONG( x, args[2] );
y += args[3]; y = ADD_LONG( y, args[3] );
cff_builder_add_point( builder, x, y, 0 ); cff_builder_add_point( builder, x, y, 0 );
/* join point; on curve, with y-value the same as the last */ /* join point; on curve, with y-value the same as the last */
/* control point's y-value */ /* control point's y-value */
x += args[4]; x = ADD_LONG( x, args[4] );
cff_builder_add_point( builder, x, y, 1 ); cff_builder_add_point( builder, x, y, 1 );
/* third control point, with y-value the same as the join */ /* third control point, with y-value the same as the join */
/* point's y-value */ /* point's y-value */
x += args[5]; x = ADD_LONG( x, args[5] );
cff_builder_add_point( builder, x, y, 0 ); cff_builder_add_point( builder, x, y, 0 );
/* fourth control point */ /* fourth control point */
x += args[6]; x = ADD_LONG( x, args[6] );
y += args[7]; y = ADD_LONG( y, args[7] );
cff_builder_add_point( builder, x, y, 0 ); cff_builder_add_point( builder, x, y, 0 );
/* ending point, with y-value the same as the start */ /* ending point, with y-value the same as the start */
x += args[8]; x = ADD_LONG( x, args[8] );
y = start_y; y = start_y;
cff_builder_add_point( builder, x, y, 1 ); cff_builder_add_point( builder, x, y, 1 );
args = stack; args = stack;
@ -1873,32 +1895,32 @@
start_y = y; start_y = y;
/* first control point */ /* first control point */
x += args[0]; x = ADD_LONG( x, args[0] );
cff_builder_add_point( builder, x, y, 0 ); cff_builder_add_point( builder, x, y, 0 );
/* second control point */ /* second control point */
x += args[1]; x = ADD_LONG( x, args[1] );
y += args[2]; y = ADD_LONG( y, args[2] );
cff_builder_add_point( builder, x, y, 0 ); cff_builder_add_point( builder, x, y, 0 );
/* join point; on curve, with y-value the same as the last */ /* join point; on curve, with y-value the same as the last */
/* control point's y-value */ /* control point's y-value */
x += args[3]; x = ADD_LONG( x, args[3] );
cff_builder_add_point( builder, x, y, 1 ); cff_builder_add_point( builder, x, y, 1 );
/* third control point, with y-value the same as the join */ /* third control point, with y-value the same as the join */
/* point's y-value */ /* point's y-value */
x += args[4]; x = ADD_LONG( x, args[4] );
cff_builder_add_point( builder, x, y, 0 ); cff_builder_add_point( builder, x, y, 0 );
/* fourth control point */ /* fourth control point */
x += args[5]; x = ADD_LONG( x, args[5] );
y = start_y; y = start_y;
cff_builder_add_point( builder, x, y, 0 ); cff_builder_add_point( builder, x, y, 0 );
/* ending point, with y-value the same as the start point's */ /* ending point, with y-value the same as the start point's */
/* y-value -- we don't add this point, though */ /* 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 ); cff_builder_add_point( builder, x, y, 1 );
args = stack; args = stack;
@ -1934,8 +1956,8 @@
/* grab up to the last argument */ /* grab up to the last argument */
for ( count = 5; count > 0; count-- ) for ( count = 5; count > 0; count-- )
{ {
dx += temp[0]; dx = ADD_LONG( dx, temp[0] );
dy += temp[1]; dy = ADD_LONG( dy, temp[1] );
temp += 2; temp += 2;
} }
@ -1949,8 +1971,8 @@
for ( count = 5; count > 0; count-- ) for ( count = 5; count > 0; count-- )
{ {
x += args[0]; x = ADD_LONG( x, args[0] );
y += args[1]; y = ADD_LONG( y, args[1] );
cff_builder_add_point( builder, x, y, cff_builder_add_point( builder, x, y,
(FT_Bool)( count == 3 ) ); (FT_Bool)( count == 3 ) );
args += 2; args += 2;
@ -1959,13 +1981,13 @@
/* is last operand an x- or y-delta? */ /* is last operand an x- or y-delta? */
if ( horizontal ) if ( horizontal )
{ {
x += args[0]; x = ADD_LONG( x, args[0] );
y = start_y; y = start_y;
} }
else else
{ {
x = start_x; x = start_x;
y += args[0]; y = ADD_LONG( y, args[0] );
} }
cff_builder_add_point( builder, x, y, 1 ); cff_builder_add_point( builder, x, y, 1 );
@ -1987,8 +2009,8 @@
for ( count = 6; count > 0; count-- ) for ( count = 6; count > 0; count-- )
{ {
x += args[0]; x = ADD_LONG( x, args[0] );
y += args[1]; y = ADD_LONG( y, args[1] );
cff_builder_add_point( builder, x, y, cff_builder_add_point( builder, x, y,
(FT_Bool)( count == 4 || count == 1 ) ); (FT_Bool)( count == 4 || count == 1 ) );
args += 2; args += 2;
@ -2066,21 +2088,26 @@
FT_TRACE4(( " abs\n" )); FT_TRACE4(( " abs\n" ));
if ( args[0] < 0 ) 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++; args++;
break; break;
case cff_op_add: case cff_op_add:
FT_TRACE4(( " add\n" )); FT_TRACE4(( " add\n" ));
args[0] += args[1]; args[0] = ADD_LONG( args[0], args[1] );
args++; args++;
break; break;
case cff_op_sub: case cff_op_sub:
FT_TRACE4(( " sub\n" )); FT_TRACE4(( " sub\n" ));
args[0] -= args[1]; args[0] = SUB_LONG( args[0], args[1] );
args++; args++;
break; break;
@ -2094,6 +2121,8 @@
case cff_op_neg: case cff_op_neg:
FT_TRACE4(( " neg\n" )); FT_TRACE4(( " neg\n" ));
if ( args[0] == FT_LONG_MIN )
args[0] = FT_LONG_MAX;
args[0] = -args[0]; args[0] = -args[0];
args++; args++;
break; break;
@ -2350,12 +2379,13 @@
FT_TRACE4(( " hsbw (invalid op)\n" )); 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.x = args[0];
decoder->builder.left_bearing.y = 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; y = decoder->builder.pos_y;
args = stack; args = stack;
break; break;
@ -2367,13 +2397,14 @@
FT_TRACE4(( " sbw (invalid op)\n" )); 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.x = args[0];
decoder->builder.left_bearing.y = args[1]; decoder->builder.left_bearing.y = args[1];
x = decoder->builder.pos_x + args[0]; x = ADD_LONG( decoder->builder.pos_x, args[0] );
y = decoder->builder.pos_y + args[1]; y = ADD_LONG( decoder->builder.pos_y, args[1] );
args = stack; args = stack;
break; break;
@ -2384,8 +2415,8 @@
FT_TRACE4(( " setcurrentpoint (invalid op)\n" )); FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
x = decoder->builder.pos_x + args[0]; x = ADD_LONG( decoder->builder.pos_x, args[0] );
y = decoder->builder.pos_y + args[1]; y = ADD_LONG( decoder->builder.pos_y, args[1] );
args = stack; args = stack;
break; break;

View File

@ -1352,9 +1352,12 @@
sum = cff_parse_num( parser, &parser->stack[i + base] ) * 65536; sum = cff_parse_num( parser, &parser->stack[i + base] ) * 65536;
for ( j = 1; j < blend->lenBV; j++ ) for ( j = 1; j < blend->lenBV; j++ )
sum += FT_MulFix( *weight++, sum = ADD_INT32(
cff_parse_num( parser, sum,
&parser->stack[delta++] ) * 65536 ); FT_MulFix(
*weight++,
cff_parse_num( parser,
&parser->stack[delta++] ) * 65536 ) );
/* point parser stack to new value on blend_stack */ /* point parser stack to new value on blend_stack */
parser->stack[i + base] = subFont->blend_top; parser->stack[i + base] = subFont->blend_top;

View File

@ -20,6 +20,7 @@
#include "cffparse.h" #include "cffparse.h"
#include FT_INTERNAL_STREAM_H #include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_CALC_H
#include "cfferrs.h" #include "cfferrs.h"
#include "cffpic.h" #include "cffpic.h"
@ -156,6 +157,22 @@
1000000000L 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 */ /* read a real */
static FT_Fixed static FT_Fixed
@ -484,7 +501,15 @@
if ( scaling ) if ( scaling )
{
if ( FT_ABS( val ) > power_ten_limits[scaling] )
{
val = val > 0 ? 0x7FFFFFFFL : -0x7FFFFFFFL;
goto Overflow;
}
val *= power_tens[scaling]; val *= power_tens[scaling];
}
if ( val > 0x7FFF ) if ( val > 0x7FFF )
{ {
@ -1585,7 +1610,7 @@
val = 0; val = 0;
while ( num_args > 0 ) while ( num_args > 0 )
{ {
val += cff_parse_num( parser, data++ ); val = ADD_LONG( val, cff_parse_num( parser, data++ ) );
switch ( field->size ) switch ( field->size )
{ {
case (8 / FT_CHAR_BIT): case (8 / FT_CHAR_BIT):

View File

@ -9,7 +9,7 @@ gxvalid: TrueType GX validator
additional tables in TrueType font which are used by `QuickDraw GX additional tables in TrueType font which are used by `QuickDraw GX
Text', Apple Advanced Typography (AAT). In addition, gxvalid can Text', Apple Advanced Typography (AAT). In addition, gxvalid can
validates `kern' tables which have been extended for AAT. Like the 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). (ftvalid).
You can link gxvalid with your program; before running your own layout You can link gxvalid with your program; before running your own layout

View File

@ -41,8 +41,8 @@ value given as argument into the corresponding glyph number.
Known problems Known problems
************** **************
- dealing explicitly with encodings breaks the uniformity of freetype2 - dealing explicitly with encodings breaks the uniformity of FreeType 2
api. API.
- except for encodings properties, client applications have no - except for encodings properties, client applications have no
visibility of the PCF_Face object. This means that applications visibility of the PCF_Face object. This means that applications

View File

@ -387,7 +387,11 @@ THE SOFTWARE.
if ( !ft_strcmp( s, "10646" ) || if ( !ft_strcmp( s, "10646" ) ||
( !ft_strcmp( s, "8859" ) && ( !ft_strcmp( s, "8859" ) &&
!ft_strcmp( face->charset_encoding, "1" ) ) ) !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 ); 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
} }
} }

View File

@ -1162,6 +1162,20 @@ THE SOFTWARE.
accel->fontDescent, accel->fontDescent,
accel->maxOverlap )); 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:" )); FT_TRACE5(( " minbounds:" ));
error = pcf_get_metric( stream, error = pcf_get_metric( stream,
format & ( ~PCF_FORMAT_MASK ), format & ( ~PCF_FORMAT_MASK ),
@ -1496,8 +1510,16 @@ THE SOFTWARE.
if ( face->accel.fontAscent + face->accel.fontDescent < 0 ) if ( face->accel.fontAscent + face->accel.fontDescent < 0 )
FT_TRACE0(( "pcf_load_font: negative height\n" )); FT_TRACE0(( "pcf_load_font: negative height\n" ));
#endif #endif
bsize->height = FT_ABS( (FT_Short)( face->accel.fontAscent + if ( FT_ABS( face->accel.fontAscent +
face->accel.fontDescent ) ); 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" ); prop = pcf_find_property( face, "AVERAGE_WIDTH" );
if ( prop ) if ( prop )
@ -1506,10 +1528,20 @@ THE SOFTWARE.
if ( prop->value.l < 0 ) if ( prop->value.l < 0 )
FT_TRACE0(( "pcf_load_font: negative average width\n" )); FT_TRACE0(( "pcf_load_font: negative average width\n" ));
#endif #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 else
{
/* this is a heuristical value */
bsize->width = (FT_Short)FT_MulDiv( bsize->height, 2, 3 ); bsize->width = (FT_Short)FT_MulDiv( bsize->height, 2, 3 );
}
prop = pcf_find_property( face, "POINT_SIZE" ); prop = pcf_find_property( face, "POINT_SIZE" );
if ( prop ) if ( prop )
@ -1519,9 +1551,16 @@ THE SOFTWARE.
FT_TRACE0(( "pcf_load_font: negative point size\n" )); FT_TRACE0(( "pcf_load_font: negative point size\n" ));
#endif #endif
/* convert from 722.7 decipoints to 72 points per inch */ /* convert from 722.7 decipoints to 72 points per inch */
bsize->size = FT_MulDiv( FT_ABS( prop->value.l ), if ( FT_ABS( prop->value.l ) > 0x504C2L ) /* 0x7FFF * 72270/7200 */
64 * 7200, {
72270L ); 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" ); prop = pcf_find_property( face, "PIXEL_SIZE" );
@ -1531,7 +1570,14 @@ THE SOFTWARE.
if ( prop->value.l < 0 ) if ( prop->value.l < 0 )
FT_TRACE0(( "pcf_load_font: negative pixel size\n" )); FT_TRACE0(( "pcf_load_font: negative pixel size\n" ));
#endif #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" ); prop = pcf_find_property( face, "RESOLUTION_X" );
@ -1541,7 +1587,14 @@ THE SOFTWARE.
if ( prop->value.l < 0 ) if ( prop->value.l < 0 )
FT_TRACE0(( "pcf_load_font: negative X resolution\n" )); FT_TRACE0(( "pcf_load_font: negative X resolution\n" ));
#endif #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" ); prop = pcf_find_property( face, "RESOLUTION_Y" );
@ -1551,7 +1604,14 @@ THE SOFTWARE.
if ( prop->value.l < 0 ) if ( prop->value.l < 0 )
FT_TRACE0(( "pcf_load_font: negative Y resolution\n" )); FT_TRACE0(( "pcf_load_font: negative Y resolution\n" ));
#endif #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 ) if ( bsize->y_ppem == 0 )

View File

@ -264,12 +264,6 @@
charmap.encoding = FT_ENCODING_UNICODE; charmap.encoding = FT_ENCODING_UNICODE;
error = FT_CMap_New( &pfr_cmap_class_rec, NULL, &charmap, NULL ); 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 */ /* check whether we have loaded any kerning pairs */

View File

@ -111,6 +111,10 @@
p++; p++;
if ( p == limit ) if ( p == limit )
goto Bad; goto Bad;
/* only a single sign is allowed */
if ( *p == '-' || *p == '+' )
return 0;
} }
num_limit = 0x7FFFFFFFL / base; num_limit = 0x7FFFFFFFL / base;
@ -215,6 +219,10 @@
p++; p++;
if ( p == limit ) if ( p == limit )
goto Bad; goto Bad;
/* only a single sign is allowed */
if ( *p == '-' || *p == '+' )
return 0;
} }
/* read the integer part */ /* read the integer part */

View File

@ -864,7 +864,9 @@
for ( mm = 1; mm < blend->num_designs; mm++ ) 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; *values++ = tmp;
} }
@ -904,7 +906,7 @@
if ( arg_cnt != 2 ) if ( arg_cnt != 2 )
goto Unexpected_OtherSubr; goto Unexpected_OtherSubr;
top[0] += top[1]; /* XXX (over|under)flow */ top[0] = ADD_LONG( top[0], top[1] );
known_othersubr_result_cnt = 1; known_othersubr_result_cnt = 1;
break; break;
@ -915,7 +917,7 @@
if ( arg_cnt != 2 ) if ( arg_cnt != 2 )
goto Unexpected_OtherSubr; goto Unexpected_OtherSubr;
top[0] -= top[1]; /* XXX (over|under)flow */ top[0] = SUB_LONG( top[0], top[1] );
known_othersubr_result_cnt = 1; known_othersubr_result_cnt = 1;
break; break;
@ -1147,11 +1149,13 @@
builder->parse_state = T1_Parse_Have_Width; builder->parse_state = T1_Parse_Have_Width;
builder->left_bearing.x += top[0]; builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
builder->advance.x = top[1]; top[0] );
builder->advance.y = 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; orig_y = y = builder->pos_y;
FT_UNUSED( orig_y ); FT_UNUSED( orig_y );
@ -1177,13 +1181,16 @@
builder->parse_state = T1_Parse_Have_Width; builder->parse_state = T1_Parse_Have_Width;
builder->left_bearing.x += top[0]; builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
builder->left_bearing.y += top[1]; top[0] );
builder->advance.x = top[2]; builder->left_bearing.y = ADD_LONG( builder->left_bearing.y,
builder->advance.y = top[3]; top[1] );
x = builder->pos_x + top[0]; builder->advance.x = top[2];
y = builder->pos_y + top[1]; builder->advance.y = top[3];
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 `metrics_only' indicates that we only want to compute */
/* the glyph's metrics (lsb + advance width), not load the */ /* 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 ) ) ) if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
goto Fail; goto Fail;
x += top[0]; x = ADD_LONG( x, top[0] );
goto Add_Line; goto Add_Line;
case op_hmoveto: case op_hmoveto:
FT_TRACE4(( " hmoveto" )); FT_TRACE4(( " hmoveto" ));
x += top[0]; x = ADD_LONG( x, top[0] );
if ( !decoder->flex_state ) if ( !decoder->flex_state )
{ {
if ( builder->parse_state == T1_Parse_Start ) if ( builder->parse_state == T1_Parse_Start )
@ -1232,12 +1240,14 @@
FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) )
goto Fail; goto Fail;
x += top[0]; x = ADD_LONG( x, top[0] );
t1_builder_add_point( builder, x, y, 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 ); 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 ); t1_builder_add_point( builder, x, y, 1 );
break; break;
@ -1247,8 +1257,8 @@
if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
goto Fail; goto Fail;
x += top[0]; x = ADD_LONG( x, top[0] );
y += top[1]; y = ADD_LONG( y, top[1] );
Add_Line: Add_Line:
if ( FT_SET_ERROR( t1_builder_add_point1( builder, x, y ) ) ) if ( FT_SET_ERROR( t1_builder_add_point1( builder, x, y ) ) )
@ -1258,8 +1268,9 @@
case op_rmoveto: case op_rmoveto:
FT_TRACE4(( " rmoveto" )); FT_TRACE4(( " rmoveto" ));
x += top[0]; x = ADD_LONG( x, top[0] );
y += top[1]; y = ADD_LONG( y, top[1] );
if ( !decoder->flex_state ) if ( !decoder->flex_state )
{ {
if ( builder->parse_state == T1_Parse_Start ) if ( builder->parse_state == T1_Parse_Start )
@ -1275,16 +1286,16 @@
FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) )
goto Fail; goto Fail;
x += top[0]; x = ADD_LONG( x, top[0] );
y += top[1]; y = ADD_LONG( y, top[1] );
t1_builder_add_point( builder, x, y, 0 ); t1_builder_add_point( builder, x, y, 0 );
x += top[2]; x = ADD_LONG( x, top[2] );
y += top[3]; y = ADD_LONG( y, top[3] );
t1_builder_add_point( builder, x, y, 0 ); t1_builder_add_point( builder, x, y, 0 );
x += top[4]; x = ADD_LONG( x, top[4] );
y += top[5]; y = ADD_LONG( y, top[5] );
t1_builder_add_point( builder, x, y, 1 ); t1_builder_add_point( builder, x, y, 1 );
break; break;
@ -1295,12 +1306,14 @@
FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) )
goto Fail; goto Fail;
y += top[0]; y = ADD_LONG( y, top[0] );
t1_builder_add_point( builder, x, y, 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 ); 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 ); t1_builder_add_point( builder, x, y, 1 );
break; break;
@ -1310,13 +1323,14 @@
if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
goto Fail; goto Fail;
y += top[0]; y = ADD_LONG( y, top[0] );
goto Add_Line; goto Add_Line;
case op_vmoveto: case op_vmoveto:
FT_TRACE4(( " vmoveto" )); FT_TRACE4(( " vmoveto" ));
y += top[0]; y = ADD_LONG( y, top[0] );
if ( !decoder->flex_state ) if ( !decoder->flex_state )
{ {
if ( builder->parse_state == T1_Parse_Start ) if ( builder->parse_state == T1_Parse_Start )
@ -1473,7 +1487,7 @@
/* record vertical hint */ /* record vertical hint */
if ( hinter ) if ( hinter )
{ {
top[0] += orig_x; top[0] = ADD_LONG( top[0], orig_x );
hinter->stem( hinter->hints, 0, top ); hinter->stem( hinter->hints, 0, top );
} }
break; break;
@ -1487,9 +1501,9 @@
FT_Pos dx = orig_x; FT_Pos dx = orig_x;
top[0] += dx; top[0] = ADD_LONG( top[0], dx );
top[2] += dx; top[2] = ADD_LONG( top[2], dx );
top[4] += dx; top[4] = ADD_LONG( top[4], dx );
hinter->stem3( hinter->hints, 0, top ); hinter->stem3( hinter->hints, 0, top );
} }
break; break;

View File

@ -23,8 +23,21 @@
#include "psmodule.h" #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" #include "pstables.h"
#define DEFINE_PS_TABLES #define DEFINE_PS_TABLES
#define DEFINE_PS_TABLES_DATA
#include "pstables.h" #include "pstables.h"
#include "psnamerr.h" #include "psnamerr.h"

View File

@ -19,7 +19,7 @@
/* This file has been generated automatically -- do not edit! */ /* This file has been generated automatically -- do not edit! */
#ifndef DEFINE_PS_TABLES #ifndef DEFINE_PS_TABLES_DATA
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
#else #else
@ -27,7 +27,7 @@
#endif #endif
#endif #endif
const char ft_standard_glyph_names[3696] const char ft_standard_glyph_names[3696]
#ifdef DEFINE_PS_TABLES #ifdef DEFINE_PS_TABLES_DATA
= =
{ {
'.','n','u','l','l', 0, '.','n','u','l','l', 0,
@ -451,7 +451,7 @@
'R','o','m','a','n', 0, 'R','o','m','a','n', 0,
'S','e','m','i','b','o','l','d', 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 */ /* Values are offsets into the `ft_standard_glyph_names' table */
#ifndef DEFINE_PS_TABLES #ifndef DEFINE_PS_TABLES_DATA
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
#else #else
@ -467,7 +467,7 @@
#endif #endif
#endif #endif
const short ft_mac_names[FT_NUM_MAC_NAMES] 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, 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, 1270,1313,1323,1171,1290,1332,1211,1235,1276, 169, 175, 182, 189, 200,
209, 218, 225, 232, 239, 246 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 */ /* Values are offsets into the `ft_standard_glyph_names' table */
#ifndef DEFINE_PS_TABLES #ifndef DEFINE_PS_TABLES_DATA
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
#else #else
@ -506,7 +506,7 @@
#endif #endif
#endif #endif
const short ft_sid_names[FT_NUM_SID_NAMES] 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, 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, 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 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 */ /* the following are indices into the SID name table */
#ifndef DEFINE_PS_TABLES #ifndef DEFINE_PS_TABLES_DATA
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
#else #else
@ -551,7 +551,7 @@
#endif #endif
#endif #endif
const unsigned short t1_standard_encoding[256] 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, 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,138, 0,139, 0, 0, 0, 0,140,141,142,143, 0, 0, 0, 0,
0,144, 0, 0, 0,145, 0, 0,146,147,148,149, 0, 0, 0, 0 0,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 */ /* the following are indices into the SID name table */
#ifndef DEFINE_PS_TABLES #ifndef DEFINE_PS_TABLES_DATA
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
#else #else
@ -584,7 +584,7 @@
#endif #endif
#endif #endif
const unsigned short t1_expert_encoding[256] 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, 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, 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 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 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
#ifndef DEFINE_PS_TABLES #ifndef DEFINE_PS_TABLES_DATA
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
#else #else
@ -627,7 +627,7 @@
#endif #endif
#endif #endif
const unsigned char ft_adobe_glyph_list[55997L] 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, 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, 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 48, 90,235,225,244,225,235,225,238, 97,128, 48,186
} }
#endif /* DEFINE_PS_TABLES */ #endif /* DEFINE_PS_TABLES_DATA */
; ;

View File

@ -31,12 +31,7 @@
static FT_Error static FT_Error
ft_raster1_init( FT_Renderer render ) ft_raster1_init( FT_Renderer render )
{ {
FT_Library library = FT_MODULE_LIBRARY( render ); render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
render->clazz->raster_class->raster_reset( render->raster,
library->raster_pool,
library->raster_pool_size );
return FT_Err_Ok; return FT_Err_Ok;
} }
@ -194,7 +189,7 @@
bitmap->rows = height; bitmap->rows = height;
bitmap->pitch = (int)pitch; bitmap->pitch = (int)pitch;
if ( FT_ALLOC_MULT( bitmap->buffer, pitch, height ) ) if ( FT_ALLOC_MULT( bitmap->buffer, height, pitch ) )
goto Exit; goto Exit;
slot->internal->flags |= FT_GLYPH_OWN_BITMAP; slot->internal->flags |= FT_GLYPH_OWN_BITMAP;

View File

@ -49,18 +49,82 @@
} }
/* Premultiplies data and converts RGBA bytes => native endian. */ /* Premultiplies data and converts RGBA bytes => BGRA. */
static void static void
premultiply_data( png_structp png, premultiply_data( png_structp png,
png_row_infop row_info, png_row_infop row_info,
png_bytep data ) 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
typedef unsigned short v82 __attribute__(( vector_size( 16 ) ));
/* 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 ); FT_UNUSED( png );
limit = row_info->rowbytes;
for ( i = 0; i < row_info->rowbytes; i += 4 ) for ( ; i < limit; i += 4 )
{ {
unsigned char* base = &data[i]; unsigned char* base = &data[i];
unsigned int alpha = base[3]; unsigned int alpha = base[3];

View File

@ -787,6 +787,8 @@
tag != TTAG_OTTO && tag != TTAG_OTTO &&
tag != TTAG_true && tag != TTAG_true &&
tag != TTAG_typ1 && tag != TTAG_typ1 &&
tag != TTAG_0xA5kbd &&
tag != TTAG_0xA5lst &&
tag != 0x00020000UL ) tag != 0x00020000UL )
{ {
FT_TRACE2(( " not a font using the SFNT container format\n" )); FT_TRACE2(( " not a font using the SFNT container format\n" ));
@ -1224,7 +1226,10 @@
goto Exit; 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 ); error = FT_THROW( Invalid_Table );
@ -1464,7 +1469,8 @@
/* Polish the charmaps. */ /* Polish the charmaps. */
/* */ /* */
/* Try to set the charmap encoding according to the platform & */ /* 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 */ tt_face_build_cmaps( face ); /* ignore errors */
@ -1472,7 +1478,10 @@
/* set the encoding fields */ /* 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++ ) for ( m = 0; m < root->num_charmaps; m++ )
@ -1483,14 +1492,34 @@
charmap->encoding = sfnt_find_encoding( charmap->platform_id, charmap->encoding = sfnt_find_encoding( charmap->platform_id,
charmap->encoding_id ); charmap->encoding_id );
#if 0 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
if ( !root->charmap &&
charmap->encoding == FT_ENCODING_UNICODE ) if ( charmap->encoding == FT_ENCODING_UNICODE ||
{ charmap->encoding == FT_ENCODING_MS_SYMBOL ) /* PUA */
/* set 'root->charmap' to the first Unicode encoding we find */ has_unicode = TRUE;
root->charmap = charmap; }
}
#endif /* 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 */
} }
} }

View File

@ -23,8 +23,10 @@
#include FT_INTERNAL_VALIDATE_H #include FT_INTERNAL_VALIDATE_H
#include FT_INTERNAL_STREAM_H #include FT_INTERNAL_STREAM_H
#include FT_SERVICE_POSTSCRIPT_CMAPS_H
#include "ttload.h" #include "ttload.h"
#include "ttcmap.h" #include "ttcmap.h"
#include "ttpost.h"
#include "sfntpic.h" #include "sfntpic.h"
@ -3622,6 +3624,110 @@
#endif /* TT_CONFIG_CMAP_FORMAT_14 */ #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 #ifndef FT_CONFIG_OPTION_PIC
static const TT_CMap_Class tt_cmap_classes[] = static const TT_CMap_Class tt_cmap_classes[] =
@ -3801,8 +3907,10 @@
FT_CMap cmap = (FT_CMap)charmap; FT_CMap cmap = (FT_CMap)charmap;
TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz; TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz;
if ( clazz->get_cmap_info )
return clazz->get_cmap_info( charmap, cmap_info ); return clazz->get_cmap_info( charmap, cmap_info );
else
return FT_THROW( Invalid_CharMap_Format );
} }

View File

@ -141,6 +141,8 @@ FT_BEGIN_HEADER
#define TT_VALID_GLYPH_COUNT( x ) TT_VALIDATOR( x )->num_glyphs #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 ) FT_LOCAL( FT_Error )
tt_face_build_cmaps( TT_Face face ); tt_face_build_cmaps( TT_Face face );

View File

@ -85,7 +85,7 @@
for ( nn = 0; nn < num_tables; nn++ ) 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_Byte* p_next;
FT_UInt32 mask = (FT_UInt32)1UL << nn; FT_UInt32 mask = (FT_UInt32)1UL << nn;
@ -107,6 +107,12 @@
if ( p_next > p_limit ) /* handle broken table */ if ( p_next > p_limit ) /* handle broken table */
p_next = p_limit; 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 */ /* only use horizontal kerning tables */
if ( ( coverage & 3U ) != 0x0001 || if ( ( coverage & 3U ) != 0x0001 ||
p + 8 > p_next ) p + 8 > p_next )

View File

@ -325,7 +325,6 @@
FT_UNUSED( post_limit ); FT_UNUSED( post_limit );
/* UNDOCUMENTED! This value appears only in the Apple TT specs. */
if ( FT_READ_USHORT( num_glyphs ) ) if ( FT_READ_USHORT( num_glyphs ) )
goto Exit; goto Exit;
@ -408,7 +407,7 @@
/* now read postscript table */ /* now read postscript table */
if ( format == 0x00020000L ) if ( format == 0x00020000L )
error = load_format_20( face, stream, post_limit ); error = load_format_20( face, stream, post_limit );
else if ( format == 0x00028000L ) else if ( format == 0x00025000L )
error = load_format_25( face, stream, post_limit ); error = load_format_25( face, stream, post_limit );
else else
error = FT_THROW( Invalid_File_Format ); error = FT_THROW( Invalid_File_Format );
@ -447,7 +446,7 @@
FT_FREE( table->glyph_names ); FT_FREE( table->glyph_names );
table->num_names = 0; table->num_names = 0;
} }
else if ( format == 0x00028000L ) else if ( format == 0x00025000L )
{ {
TT_Post_25 table = &names->names.format_25; TT_Post_25 table = &names->names.format_25;
@ -543,7 +542,7 @@
*PSname = (FT_String*)table->glyph_names[name_index - 258]; *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; TT_Post_25 table = &names->names.format_25;

View File

@ -448,6 +448,15 @@
metrics->max_advance = metrics->max_advance =
FT_MulDiv( hori->advance_Width_Max, ppem_ * 64, upem ); 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; return error;
} }
@ -1439,10 +1448,17 @@
return FT_THROW( Invalid_Table ); return FT_THROW( Invalid_Table );
NoBitmap: 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:" FT_TRACE4(( "tt_sbit_decoder_load_image:"
" no sbit found for glyph index %d\n", glyph_index )); " no sbit found for glyph index %d\n", glyph_index ));
return FT_THROW( Missing_Bitmap );
return FT_THROW( Invalid_Argument );
} }

View File

@ -141,6 +141,16 @@
#define FT_INT_MAX INT_MAX #define FT_INT_MAX INT_MAX
#define FT_ULONG_MAX ULONG_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_memset memset
#define ft_setjmp setjmp #define ft_setjmp setjmp
@ -264,6 +274,7 @@ typedef ptrdiff_t FT_PtrDist;
#include "ftgrays.h" #include "ftgrays.h"
#include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_CALC_H
#include FT_OUTLINE_H #include FT_OUTLINE_H
#include "ftsmerrs.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. */ /* s is L * the perpendicular distance from P1 to the line P0-P3. */
dx1 = arc[1].x - arc[0].x; dx1 = arc[1].x - arc[0].x;
dy1 = arc[1].y - arc[0].y; 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 ) if ( s > s_limit )
goto Split; goto Split;
@ -1143,7 +1154,7 @@ typedef ptrdiff_t FT_PtrDist;
/* s is L * the perpendicular distance from P2 to the line P0-P3. */ /* s is L * the perpendicular distance from P2 to the line P0-P3. */
dx2 = arc[2].x - arc[0].x; dx2 = arc[2].x - arc[0].x;
dy2 = arc[2].y - arc[0].y; 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 ) if ( s > s_limit )
goto Split; goto Split;

View File

@ -31,12 +31,7 @@
static FT_Error static FT_Error
ft_smooth_init( FT_Renderer render ) ft_smooth_init( FT_Renderer render )
{ {
FT_Library library = FT_MODULE_LIBRARY( render ); render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
render->clazz->raster_class->raster_reset( render->raster,
library->raster_pool,
library->raster_pool_size );
return 0; return 0;
} }
@ -111,9 +106,6 @@
FT_Pos y_shift = 0; FT_Pos y_shift = 0;
FT_Pos x_left, y_top; FT_Pos x_left, y_top;
FT_Pos width, height, pitch; 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 hmul = ( mode == FT_RENDER_MODE_LCD );
FT_Int vmul = ( mode == FT_RENDER_MODE_LCD_V ); FT_Int vmul = ( mode == FT_RENDER_MODE_LCD_V );
@ -124,7 +116,6 @@
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
FT_Int lcd_extra = 0;
FT_LcdFiveTapFilter lcd_weights = { 0 }; FT_LcdFiveTapFilter lcd_weights = { 0 };
FT_Bool have_custom_weight = FALSE; FT_Bool have_custom_weight = FALSE;
FT_Bitmap_LcdFilterFunc lcd_filter_func = NULL; FT_Bitmap_LcdFilterFunc lcd_filter_func = NULL;
@ -152,13 +143,12 @@
{ {
/* /*
* A per-font filter is set. It always uses the default 5-tap * 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, ft_memcpy( lcd_weights,
slot->face->internal->lcd_weights, slot->face->internal->lcd_weights,
FT_LCD_FILTER_FIVE_TAPS ); FT_LCD_FILTER_FIVE_TAPS );
lcd_filter_func = ft_lcd_filter_fir; lcd_filter_func = ft_lcd_filter_fir;
lcd_extra = 2;
} }
else else
{ {
@ -172,7 +162,6 @@
slot->library->lcd_weights, slot->library->lcd_weights,
FT_LCD_FILTER_FIVE_TAPS ); FT_LCD_FILTER_FIVE_TAPS );
lcd_filter_func = slot->library->lcd_filter_func; lcd_filter_func = slot->library->lcd_filter_func;
lcd_extra = slot->library->lcd_extra;
} }
#endif /*FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ #endif /*FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
@ -201,6 +190,45 @@
/* taking into account the origin shift */ /* taking into account the origin shift */
FT_Outline_Get_CBox( outline, &cbox ); 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.xMin = FT_PIX_FLOOR( cbox.xMin + x_shift );
cbox.yMin = FT_PIX_FLOOR( cbox.yMin + y_shift ); cbox.yMin = FT_PIX_FLOOR( cbox.yMin + y_shift );
cbox.xMax = FT_PIX_CEIL( cbox.xMax + x_shift ); cbox.xMax = FT_PIX_CEIL( cbox.xMax + x_shift );
@ -215,11 +243,6 @@
width = (FT_ULong)( cbox.xMax - cbox.xMin ) >> 6; width = (FT_ULong)( cbox.xMax - cbox.xMin ) >> 6;
height = (FT_ULong)( cbox.yMax - cbox.yMin ) >> 6; height = (FT_ULong)( cbox.yMax - cbox.yMin ) >> 6;
#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
width_org = width;
height_org = height;
#endif
pitch = width; pitch = width;
if ( hmul ) if ( hmul )
{ {
@ -230,26 +253,6 @@
if ( vmul ) if ( vmul )
height *= 3; 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 * XXX: on 16bit system, we return an error for huge bitmap
* to prevent an overflow. * to prevent an overflow.
@ -353,57 +356,98 @@
#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
/* render outline into bitmap */ if ( hmul ) /* lcd */
error = render->raster_render( render->raster, &params );
if ( error )
goto Exit;
/* expand it horizontally */
if ( hmul )
{ {
FT_Byte* line = bitmap->buffer; FT_Byte* line;
FT_UInt hh; FT_Byte* temp;
FT_Int i, j;
for ( hh = height_org; hh > 0; hh--, line += pitch ) /* Render 3 separate monochrome bitmaps, shifting the outline */
/* by 1/3 pixel. */
width /= 3;
FT_Outline_Translate( outline, 21, 0 );
error = render->raster_render( render->raster, &params );
if ( error )
goto Exit;
FT_Outline_Translate( outline, -21, 0 );
bitmap->buffer += width;
error = render->raster_render( render->raster, &params );
if ( error )
goto Exit;
FT_Outline_Translate( outline, -21, 0 );
bitmap->buffer += width;
error = render->raster_render( render->raster, &params );
if ( error )
goto Exit;
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++ )
{ {
FT_UInt xx; line = bitmap->buffer + i * pitch;
FT_Byte* end = line + width; for ( j = 0; j < width; j++ )
for ( xx = width_org; xx > 0; xx-- )
{ {
FT_UInt pixel = line[xx-1]; temp[3 * j ] = line[j];
temp[3 * j + 1] = line[j + width];
temp[3 * j + 2] = line[j + width + width];
end[-3] = (FT_Byte)pixel;
end[-2] = (FT_Byte)pixel;
end[-1] = (FT_Byte)pixel;
end -= 3;
} }
FT_MEM_COPY( line, temp, pitch );
} }
FT_FREE( temp );
} }
else if ( vmul ) /* lcd_v */
/* expand it vertically */
if ( vmul )
{ {
FT_Byte* read = bitmap->buffer + ( height - height_org ) * pitch; /* Render 3 separate monochrome bitmaps, shifting the outline */
FT_Byte* write = bitmap->buffer; /* by 1/3 pixel. Triple the pitch to render on each third row. */
FT_UInt hh; bitmap->pitch *= 3;
bitmap->rows /= 3;
FT_Outline_Translate( outline, 0, 21 );
bitmap->buffer += 2 * pitch;
for ( hh = height_org; hh > 0; hh-- ) error = render->raster_render( render->raster, &params );
{ if ( error )
ft_memcpy( write, read, pitch ); goto Exit;
write += pitch;
ft_memcpy( write, read, pitch ); FT_Outline_Translate( outline, 0, -21 );
write += pitch; bitmap->buffer -= pitch;
ft_memcpy( write, read, pitch ); error = render->raster_render( render->raster, &params );
write += pitch; if ( error )
read += pitch; goto Exit;
}
FT_Outline_Translate( outline, 0, -21 );
bitmap->buffer -= pitch;
error = render->raster_render( render->raster, &params );
if ( error )
goto Exit;
FT_Outline_Translate( outline, 0, 21 );
bitmap->pitch /= 3;
bitmap->rows *= 3;
}
else /* grayscale */
{
error = render->raster_render( render->raster, &params );
if ( error )
goto Exit;
} }
#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */

View File

@ -87,7 +87,7 @@
/*************************************************************************/ /*************************************************************************/
/* */ /* */
/* Return the vertical metrics in font units for a given glyph. */ /* 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 ) FT_LOCAL_DEF( void )
TT_Get_VMetrics( TT_Face face, TT_Get_VMetrics( TT_Face face,
@ -825,7 +825,7 @@
/* compatibility mode, where no movement on the x axis means no reason */ /* compatibility mode, where no movement on the x axis means no reason */
/* to change bearings or advance widths. */ /* to change bearings or advance widths. */
if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 && if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
!loader->exec->backward_compatibility ) ) loader->exec->backward_compatibility ) )
{ {
#endif #endif
loader->pp1 = zone->cur[zone->n_points - 4]; loader->pp1 = zone->cur[zone->n_points - 4];
@ -1686,7 +1686,7 @@
/***********************************************************************/ /***********************************************************************/
/* otherwise, load a composite! */ /* otherwise, load a composite! */
else if ( loader->n_contours == -1 ) else if ( loader->n_contours < 0 )
{ {
FT_Memory memory = face->root.memory; FT_Memory memory = face->root.memory;
@ -1697,6 +1697,9 @@
FT_ListNode node, node2; FT_ListNode node, node2;
/* normalize the `n_contours' value */
loader->n_contours = -1;
/* /*
* We store the glyph index directly in the `node->data' pointer, * We store the glyph index directly in the `node->data' pointer,
* following the glib solution (cf. macro `GUINT_TO_POINTER') with a * 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 */ /* set glyph dimensions */
glyph->metrics.width = bbox.xMax - bbox.xMin; glyph->metrics.width = SUB_LONG( bbox.xMax, bbox.xMin );
glyph->metrics.height = bbox.yMax - bbox.yMin; glyph->metrics.height = SUB_LONG( bbox.yMax, bbox.yMin );
/* Now take care of vertical metrics. In the case where there is */ /* Now take care of vertical metrics. In the case where there is */
/* no vertical information within the font (relatively common), */ /* no vertical information within the font (relatively common), */
@ -2137,7 +2134,8 @@
/* table in the font. Otherwise, we use the */ /* table in the font. Otherwise, we use the */
/* values defined in the horizontal header. */ /* 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 ); y_scale );
if ( face->os2.version != 0xFFFFU ) if ( face->os2.version != 0xFFFFU )
advance = (FT_Pos)( face->os2.sTypoAscender - advance = (FT_Pos)( face->os2.sTypoAscender -
@ -2339,13 +2337,19 @@
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
{ {
subpixel_hinting_lean = TRUE; subpixel_hinting_lean =
grayscale_cleartype = !FT_BOOL( load_flags & FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
FT_LOAD_TARGET_LCD || FT_RENDER_MODE_MONO );
load_flags & grayscale_cleartype =
FT_LOAD_TARGET_LCD_V ); FT_BOOL( subpixel_hinting_lean &&
exec->vertical_lcd_lean = FT_BOOL( load_flags & !( ( load_flags &
FT_LOAD_TARGET_LCD_V ); 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 else
{ {
@ -2621,7 +2625,64 @@
IS_DEFAULT_INSTANCE ) IS_DEFAULT_INSTANCE )
{ {
error = load_sbit_image( size, glyph, glyph_index, load_flags ); 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 ) ) if ( FT_IS_SCALABLE( glyph->face ) )
{ {

View File

@ -60,8 +60,11 @@
#define FT_Stream_FTell( stream ) \ #define FT_Stream_FTell( stream ) \
(FT_ULong)( (stream)->cursor - (stream)->base ) (FT_ULong)( (stream)->cursor - (stream)->base )
#define FT_Stream_SeekSet( stream, off ) \ #define FT_Stream_SeekSet( stream, off ) \
( (stream)->cursor = (stream)->base + (off) ) (stream)->cursor = \
( (off) < (FT_ULong)( (stream)->limit - (stream)->base ) ) \
? (stream)->base + (off) \
: (stream)->limit
/*************************************************************************/ /*************************************************************************/
@ -392,14 +395,14 @@
/* some macros we need */ /* some macros we need */
#define FT_FIXED_ONE ( (FT_Fixed)0x10000 ) #define FT_FIXED_ONE ( (FT_Fixed)0x10000 )
#define FT_fdot14ToFixed( x ) \ #define FT_fdot14ToFixed( x ) \
( (FT_Fixed)( (FT_ULong)(x) << 2 ) ) ( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
#define FT_intToFixed( i ) \ #define FT_intToFixed( i ) \
( (FT_Fixed)( (FT_ULong)(i) << 16 ) ) ( (FT_Fixed)( (FT_ULong)(i) << 16 ) )
#define FT_fixedToInt( x ) \ #define FT_fixedToInt( x ) \
( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) )
static FT_Error static FT_Error
@ -1953,6 +1956,7 @@
GX_FVar_Head fvar_head; GX_FVar_Head fvar_head;
FT_Bool usePsName; FT_Bool usePsName;
FT_UInt num_instances; FT_UInt num_instances;
FT_UShort* axis_flags;
static const FT_Frame_Field fvar_fields[] = static const FT_Frame_Field fvar_fields[] =
{ {
@ -2038,14 +2042,16 @@
/* in fvar's table of named instances */ /* in fvar's table of named instances */
num_instances = face->root.style_flags >> 16; num_instances = face->root.style_flags >> 16;
/* cannot overflow 32-bit arithmetic because of the size limits */ /* prepare storage area for MM data; this cannot overflow */
/* used in the `fvar' table validity check in `sfnt_init_face' */ /* 32-bit arithmetic because of the size limits used in the */
/* `fvar' table validity check in `sfnt_init_face' */
face->blend->mmvar_len = face->blend->mmvar_len =
sizeof ( FT_MM_Var ) + sizeof ( FT_MM_Var ) +
fvar_head.axisCount * sizeof ( FT_UShort ) +
fvar_head.axisCount * sizeof ( FT_Var_Axis ) + fvar_head.axisCount * sizeof ( FT_Var_Axis ) +
num_instances * sizeof ( FT_Var_Named_Style ) + num_instances * sizeof ( FT_Var_Named_Style ) +
num_instances * fvar_head.axisCount * sizeof ( FT_Fixed ) + num_instances * fvar_head.axisCount * sizeof ( FT_Fixed ) +
5 * fvar_head.axisCount; fvar_head.axisCount * 5;
if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) )
goto Exit; goto Exit;
@ -2062,8 +2068,12 @@
/* (or tuples, as called by Apple) */ /* (or tuples, as called by Apple) */
mmvar->num_namedstyles = mmvar->num_namedstyles =
num_instances; num_instances;
/* alas, no public field in `FT_Var_Axis' for axis flags */
axis_flags =
(FT_UShort*)&( mmvar[1] );
mmvar->axis = mmvar->axis =
(FT_Var_Axis*)&( mmvar[1] ); (FT_Var_Axis*)&( axis_flags[fvar_head.axisCount] );
mmvar->namedstyle = mmvar->namedstyle =
(FT_Var_Named_Style*)&( mmvar->axis[fvar_head.axisCount] ); (FT_Var_Named_Style*)&( mmvar->axis[fvar_head.axisCount] );
@ -2107,6 +2117,8 @@
a->name[3] = (FT_String)( ( a->tag ) & 0xFF ); a->name[3] = (FT_String)( ( a->tag ) & 0xFF );
a->name[4] = '\0'; a->name[4] = '\0';
*axis_flags = axis_rec.flags;
if ( a->minimum > a->def || if ( a->minimum > a->def ||
a->def > a->maximum ) a->def > a->maximum )
{ {
@ -2118,13 +2130,17 @@
a->maximum = a->def; 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->name,
a->minimum / 65536.0, a->minimum / 65536.0,
a->def / 65536.0, a->def / 65536.0,
a->maximum / 65536.0 )); a->maximum / 65536.0,
*axis_flags ));
a++; a++;
axis_flags++;
} }
FT_TRACE5(( "\n" )); FT_TRACE5(( "\n" ));
@ -2136,8 +2152,16 @@
goto Exit; goto Exit;
if ( fvar_head.instanceCount && !face->blend->avar_loaded ) if ( fvar_head.instanceCount && !face->blend->avar_loaded )
{
FT_ULong offset = FT_STREAM_POS();
ft_var_load_avar( face ); ft_var_load_avar( face );
if ( FT_STREAM_SEEK( offset ) )
goto Exit;
}
ns = mmvar->namedstyle; ns = mmvar->namedstyle;
nsc = face->blend->normalized_stylecoords; nsc = face->blend->normalized_stylecoords;
for ( i = 0; i < fvar_head.instanceCount; i++, ns++ ) for ( i = 0; i < fvar_head.instanceCount; i++, ns++ )
@ -2154,8 +2178,11 @@
for ( j = 0; j < fvar_head.axisCount; j++, c++ ) for ( j = 0; j < fvar_head.axisCount; j++, c++ )
*c = FT_GET_LONG(); *c = FT_GET_LONG();
/* valid psid values are 6, [256;32767], and 0xFFFF */
if ( usePsName ) if ( usePsName )
ns->psid = FT_GET_USHORT(); ns->psid = FT_GET_USHORT();
else
ns->psid = 0xFFFF;
ft_var_to_normalized( face, ft_var_to_normalized( face,
fvar_head.axisCount, fvar_head.axisCount,
@ -2171,7 +2198,7 @@
SFNT_Service sfnt = (SFNT_Service)face->sfnt; SFNT_Service sfnt = (SFNT_Service)face->sfnt;
FT_Int found, dummy1, dummy2; FT_Int found, dummy1, dummy2;
FT_UInt strid = 0xFFFFFFFFUL; FT_UInt strid = ~0U;
/* the default instance is missing in array the */ /* the default instance is missing in array the */
@ -2230,13 +2257,15 @@
goto Exit; goto Exit;
FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len ); FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len );
axis_flags =
(FT_UShort*)&( mmvar[1] );
mmvar->axis = mmvar->axis =
(FT_Var_Axis*)&( mmvar[1] ); (FT_Var_Axis*)&( axis_flags[mmvar->num_axis] );
mmvar->namedstyle = mmvar->namedstyle =
(FT_Var_Named_Style*)&( mmvar->axis[mmvar->num_axis] ); (FT_Var_Named_Style*)&( mmvar->axis[mmvar->num_axis] );
next_coords = next_coords =
(FT_Fixed*)&( mmvar->namedstyle[mmvar->num_namedstyles] ); (FT_Fixed*)&( mmvar->namedstyle[mmvar->num_namedstyles] );
for ( n = 0; n < mmvar->num_namedstyles; n++ ) for ( n = 0; n < mmvar->num_namedstyles; n++ )
{ {
mmvar->namedstyle[n].coords = next_coords; mmvar->namedstyle[n].coords = next_coords;
@ -2281,7 +2310,10 @@
GX_Blend blend; GX_Blend blend;
FT_MM_Var* mmvar; FT_MM_Var* mmvar;
FT_UInt i, j; 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; FT_Memory memory = face->root.memory;
enum enum
@ -2327,7 +2359,7 @@
} }
if ( coords[i] != 0 ) if ( coords[i] != 0 )
is_default_instance = 0; is_default_instance = FALSE;
} }
FT_TRACE5(( "\n" )); FT_TRACE5(( "\n" ));
@ -2340,6 +2372,9 @@
{ {
if ( FT_NEW_ARRAY( blend->coords, mmvar->num_axis ) ) if ( FT_NEW_ARRAY( blend->coords, mmvar->num_axis ) )
goto Exit; goto Exit;
/* the first time we have to compute all design coordinates */
all_design_coords = TRUE;
} }
if ( !blend->normalizedcoords ) if ( !blend->normalizedcoords )
@ -2388,7 +2423,7 @@
if ( set_design_coords ) if ( set_design_coords )
ft_var_to_design( face, ft_var_to_design( face,
num_coords, all_design_coords ? blend->num_axis : num_coords,
blend->normalizedcoords, blend->normalizedcoords,
blend->coords ); blend->coords );
@ -2529,6 +2564,14 @@
blend = face->blend; 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; nc = num_coords;
if ( num_coords > blend->num_axis ) if ( num_coords > blend->num_axis )
{ {
@ -2626,7 +2669,7 @@
num_coords * sizeof ( FT_Fixed ) ); num_coords * sizeof ( FT_Fixed ) );
a = mmvar->axis + num_coords; 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++ ) for ( i = num_coords; i < mmvar->num_axis; i++, a++, c++ )
*c = a->def; *c = a->def;
@ -2636,7 +2679,7 @@
if ( !face->blend->avar_loaded ) if ( !face->blend->avar_loaded )
ft_var_load_avar( face ); 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 ); error = tt_set_mm_blend( face, mmvar->num_axis, normalized, 0 );
@ -2686,6 +2729,14 @@
blend = face->blend; 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; nc = num_coords;
if ( num_coords > blend->num_axis ) if ( num_coords > blend->num_axis )
{ {

View File

@ -65,11 +65,15 @@
TT_INTERPRETER_VERSION_40 ) TT_INTERPRETER_VERSION_40 )
#endif #endif
#define PROJECT( v1, v2 ) \ #define PROJECT( v1, v2 ) \
exc->func_project( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y ) exc->func_project( exc, \
SUB_LONG( (v1)->x, (v2)->x ), \
SUB_LONG( (v1)->y, (v2)->y ) )
#define DUALPROJ( v1, v2 ) \ #define DUALPROJ( v1, v2 ) \
exc->func_dualproj( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y ) exc->func_dualproj( exc, \
SUB_LONG( (v1)->x, (v2)->x ), \
SUB_LONG( (v1)->y, (v2)->y ) )
#define FAST_PROJECT( v ) \ #define FAST_PROJECT( v ) \
exc->func_project( exc, (v)->x, (v)->y ) exc->func_project( exc, (v)->x, (v)->y )
@ -1676,7 +1680,10 @@
if ( SUBPIXEL_HINTING_INFINALITY && if ( SUBPIXEL_HINTING_INFINALITY &&
( !exc->ignore_x_mode || ( !exc->ignore_x_mode ||
( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) ) ( 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 else
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
@ -1685,12 +1692,18 @@
/* diagonal moves, but only post-IUP. DejaVu tries to adjust */ /* diagonal moves, but only post-IUP. DejaVu tries to adjust */
/* diagonal stems like on `Z' and `z' post-IUP. */ /* diagonal stems like on `Z' and `z' post-IUP. */
if ( SUBPIXEL_HINTING_MINIMAL && !exc->backward_compatibility ) 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 else
#endif #endif
if ( NO_SUBPIXEL_HINTING ) 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; zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
} }
@ -1705,7 +1718,10 @@
exc->iupx_called && exc->iupx_called &&
exc->iupy_called ) ) exc->iupy_called ) )
#endif #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; zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
} }
@ -1741,12 +1757,18 @@
v = exc->GS.freeVector.x; v = exc->GS.freeVector.x;
if ( v != 0 ) 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; v = exc->GS.freeVector.y;
if ( v != 0 ) 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 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
if ( SUBPIXEL_HINTING_INFINALITY && !exc->ignore_x_mode ) 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 else
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
if ( SUBPIXEL_HINTING_MINIMAL && !exc->backward_compatibility ) if ( SUBPIXEL_HINTING_MINIMAL && !exc->backward_compatibility )
zone->cur[point].x += distance; zone->cur[point].x = ADD_LONG( zone->cur[point].x, distance );
else else
#endif #endif
if ( NO_SUBPIXEL_HINTING ) 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; zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
} }
@ -1799,7 +1821,7 @@
exc->backward_compatibility && exc->backward_compatibility &&
exc->iupx_called && exc->iupy_called ) ) exc->iupx_called && exc->iupy_called ) )
#endif #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; zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
} }
@ -1823,7 +1845,7 @@
{ {
FT_UNUSED( exc ); 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 ); 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 ) if ( distance >= 0 )
{ {
val = distance + compensation; val = ADD_LONG( distance, compensation );
if ( val < 0 ) if ( val < 0 )
val = 0; val = 0;
} }
else else
{ {
val = distance - compensation; val = SUB_LONG( distance, compensation );
if ( val > 0 ) if ( val > 0 )
val = 0; val = 0;
} }
@ -1915,13 +1937,14 @@
if ( distance >= 0 ) if ( distance >= 0 )
{ {
val = FT_PIX_ROUND( distance + compensation ); val = FT_PIX_ROUND_LONG( ADD_LONG( distance, compensation ) );
if ( val < 0 ) if ( val < 0 )
val = 0; val = 0;
} }
else else
{ {
val = -FT_PIX_ROUND( compensation - distance ); val = NEG_LONG( FT_PIX_ROUND_LONG( SUB_LONG( compensation,
distance ) ) );
if ( val > 0 ) if ( val > 0 )
val = 0; val = 0;
} }
@ -1958,13 +1981,16 @@
if ( distance >= 0 ) if ( distance >= 0 )
{ {
val = FT_PIX_FLOOR( distance + compensation ) + 32; val = ADD_LONG( FT_PIX_FLOOR( ADD_LONG( distance, compensation ) ),
32 );
if ( val < 0 ) if ( val < 0 )
val = 32; val = 32;
} }
else else
{ {
val = -( FT_PIX_FLOOR( compensation - distance ) + 32 ); val = NEG_LONG( ADD_LONG( FT_PIX_FLOOR( SUB_LONG( compensation,
distance ) ),
32 ) );
if ( val > 0 ) if ( val > 0 )
val = -32; val = -32;
} }
@ -2001,13 +2027,13 @@
if ( distance >= 0 ) if ( distance >= 0 )
{ {
val = FT_PIX_FLOOR( distance + compensation ); val = FT_PIX_FLOOR( ADD_LONG( distance, compensation ) );
if ( val < 0 ) if ( val < 0 )
val = 0; val = 0;
} }
else else
{ {
val = -FT_PIX_FLOOR( compensation - distance ); val = NEG_LONG( FT_PIX_FLOOR( SUB_LONG( compensation, distance ) ) );
if ( val > 0 ) if ( val > 0 )
val = 0; val = 0;
} }
@ -2044,13 +2070,14 @@
if ( distance >= 0 ) if ( distance >= 0 )
{ {
val = FT_PIX_CEIL( distance + compensation ); val = FT_PIX_CEIL_LONG( ADD_LONG( distance, compensation ) );
if ( val < 0 ) if ( val < 0 )
val = 0; val = 0;
} }
else else
{ {
val = -FT_PIX_CEIL( compensation - distance ); val = NEG_LONG( FT_PIX_CEIL_LONG( SUB_LONG( compensation,
distance ) ) );
if ( val > 0 ) if ( val > 0 )
val = 0; val = 0;
} }
@ -2087,13 +2114,14 @@
if ( distance >= 0 ) if ( distance >= 0 )
{ {
val = FT_PAD_ROUND( distance + compensation, 32 ); val = FT_PAD_ROUND_LONG( ADD_LONG( distance, compensation ), 32 );
if ( val < 0 ) if ( val < 0 )
val = 0; val = 0;
} }
else else
{ {
val = -FT_PAD_ROUND( compensation - distance, 32 ); val = NEG_LONG( FT_PAD_ROUND_LONG( SUB_LONG( compensation, distance ),
32 ) );
if ( val > 0 ) if ( val > 0 )
val = 0; val = 0;
} }
@ -2134,7 +2162,8 @@
if ( distance >= 0 ) 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; val += exc->phase;
if ( val < 0 ) if ( val < 0 )
@ -2142,8 +2171,9 @@
} }
else else
{ {
val = -( ( exc->threshold - exc->phase - distance + compensation ) & val = NEG_LONG( SUB_LONG( exc->threshold - exc->phase + compensation,
-exc->period ); distance ) &
-exc->period );
val -= exc->phase; val -= exc->phase;
if ( val > 0 ) if ( val > 0 )
val = -exc->phase; val = -exc->phase;
@ -2183,7 +2213,8 @@
if ( distance >= 0 ) if ( distance >= 0 )
{ {
val = ( ( distance - exc->phase + exc->threshold + compensation ) / val = ( ADD_LONG( distance,
exc->threshold - exc->phase + compensation ) /
exc->period ) * exc->period; exc->period ) * exc->period;
val += exc->phase; val += exc->phase;
if ( val < 0 ) if ( val < 0 )
@ -2191,8 +2222,9 @@
} }
else else
{ {
val = -( ( ( exc->threshold - exc->phase - distance + compensation ) / val = NEG_LONG( ( SUB_LONG( exc->threshold - exc->phase + compensation,
exc->period ) * exc->period ); distance ) /
exc->period ) * exc->period );
val -= exc->phase; val -= exc->phase;
if ( val > 0 ) if ( val > 0 )
val = -exc->phase; val = -exc->phase;
@ -2826,7 +2858,7 @@
static void static void
Ins_ADD( FT_Long* args ) Ins_ADD( FT_Long* args )
{ {
args[0] += args[1]; args[0] = ADD_LONG( args[0], args[1] );
} }
@ -2839,7 +2871,7 @@
static void static void
Ins_SUB( FT_Long* args ) Ins_SUB( FT_Long* args )
{ {
args[0] -= args[1]; args[0] = SUB_LONG( args[0], args[1] );
} }
@ -2882,7 +2914,8 @@
static void static void
Ins_ABS( FT_Long* args ) 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 static void
Ins_NEG( FT_Long* args ) Ins_NEG( FT_Long* args )
{ {
args[0] = -args[0]; args[0] = NEG_LONG( args[0] );
} }
@ -4211,8 +4244,8 @@
p1 = exc->zp1.cur + aIdx2; p1 = exc->zp1.cur + aIdx2;
p2 = exc->zp2.cur + aIdx1; p2 = exc->zp2.cur + aIdx1;
A = p1->x - p2->x; A = SUB_LONG( p1->x, p2->x );
B = p1->y - p2->y; B = SUB_LONG( p1->y, p2->y );
/* If p1 == p2, SPvTL and SFvTL behave the same as */ /* If p1 == p2, SPvTL and SFvTL behave the same as */
/* SPvTCA[X] and SFvTCA[X], respectively. */ /* SPvTCA[X] and SFvTCA[X], respectively. */
@ -4227,9 +4260,9 @@
if ( ( opcode & 1 ) != 0 ) if ( ( opcode & 1 ) != 0 )
{ {
C = B; /* counter clockwise rotation */ C = B; /* counter clockwise rotation */
B = A; B = A;
A = -C; A = NEG_LONG( C );
} }
Normalize( A, B, Vec ); Normalize( A, B, Vec );
@ -4770,7 +4803,7 @@
K = FAST_PROJECT( &exc->zp2.cur[L] ); 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 */ /* UNDOCUMENTED! The MS rasterizer does that with */
/* twilight points (confirmed by Greg Hitchcock) */ /* twilight points (confirmed by Greg Hitchcock) */
@ -4894,12 +4927,12 @@
} }
{ {
FT_Vector* v1 = exc->zp1.org + p2; FT_Vector* v1 = exc->zp1.org + p2;
FT_Vector* v2 = exc->zp2.org + p1; FT_Vector* v2 = exc->zp2.org + p1;
A = v1->x - v2->x; A = SUB_LONG( v1->x, v2->x );
B = v1->y - v2->y; B = SUB_LONG( v1->y, v2->y );
/* If v1 == v2, SDPvTL behaves the same as */ /* If v1 == v2, SDPvTL behaves the same as */
/* SVTCA[X], respectively. */ /* SVTCA[X], respectively. */
@ -4915,9 +4948,9 @@
if ( ( opcode & 1 ) != 0 ) if ( ( opcode & 1 ) != 0 )
{ {
C = B; /* counter clockwise rotation */ C = B; /* counter clockwise rotation */
B = A; B = A;
A = -C; A = NEG_LONG( C );
} }
Normalize( A, B, &exc->GS.dualVector ); Normalize( A, B, &exc->GS.dualVector );
@ -4927,8 +4960,8 @@
FT_Vector* v2 = exc->zp2.cur + p1; FT_Vector* v2 = exc->zp2.cur + p1;
A = v1->x - v2->x; A = SUB_LONG( v1->x, v2->x );
B = v1->y - v2->y; B = SUB_LONG( v1->y, v2->y );
if ( A == 0 && B == 0 ) if ( A == 0 && B == 0 )
{ {
@ -4939,9 +4972,9 @@
if ( ( opcode & 1 ) != 0 ) if ( ( opcode & 1 ) != 0 )
{ {
C = B; /* counter clockwise rotation */ C = B; /* counter clockwise rotation */
B = A; B = A;
A = -C; A = NEG_LONG( C );
} }
Normalize( A, B, &exc->GS.projVector ); Normalize( A, B, &exc->GS.projVector );
@ -5392,7 +5425,7 @@
if ( !( SUBPIXEL_HINTING_MINIMAL && if ( !( SUBPIXEL_HINTING_MINIMAL &&
exc->backward_compatibility ) ) exc->backward_compatibility ) )
#endif #endif
exc->zp2.cur[point].x += dx; exc->zp2.cur[point].x = ADD_LONG( exc->zp2.cur[point].x, dx );
if ( touch ) if ( touch )
exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
@ -5406,7 +5439,7 @@
exc->iupx_called && exc->iupx_called &&
exc->iupy_called ) ) exc->iupy_called ) )
#endif #endif
exc->zp2.cur[point].y += dy; exc->zp2.cur[point].y = ADD_LONG( exc->zp2.cur[point].y, dy );
if ( touch ) if ( touch )
exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
@ -5781,14 +5814,17 @@
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* subpixel hinting - make MSIRP respect CVT cut-in; */ /* subpixel hinting - make MSIRP respect CVT cut-in; */
if ( SUBPIXEL_HINTING_INFINALITY && if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode && exc->ignore_x_mode &&
exc->GS.freeVector.x != 0 && exc->GS.freeVector.x != 0 &&
FT_ABS( distance - args[1] ) >= control_value_cutin ) FT_ABS( SUB_LONG( distance, args[1] ) ) >= control_value_cutin )
distance = args[1]; distance = args[1];
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ #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.rp1 = exc->GS.rp0;
exc->GS.rp2 = point; exc->GS.rp2 = point;
@ -6027,8 +6063,10 @@
FT_Vector vec; FT_Vector vec;
vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale ); vec.x = FT_MulFix( SUB_LONG( vec1->x, vec2->x ),
vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale ); exc->metrics.x_scale );
vec.y = FT_MulFix( SUB_LONG( vec1->y, vec2->y ),
exc->metrics.y_scale );
org_dist = FAST_DUALPROJ( &vec ); org_dist = FAST_DUALPROJ( &vec );
} }
@ -6081,8 +6119,8 @@
} }
else else
{ {
if ( distance > -minimum_distance ) if ( distance > NEG_LONG( minimum_distance ) )
distance = -minimum_distance; distance = NEG_LONG( minimum_distance );
} }
} }
@ -6090,7 +6128,7 @@
org_dist = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 ); 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: Fail:
exc->GS.rp1 = exc->GS.rp0; exc->GS.rp1 = exc->GS.rp0;
@ -6265,8 +6303,8 @@
} }
else else
{ {
if ( distance > -minimum_distance ) if ( distance > NEG_LONG( minimum_distance ) )
distance = -minimum_distance; distance = NEG_LONG( minimum_distance );
} }
} }
@ -6290,7 +6328,10 @@
} }
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ #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 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
if ( SUBPIXEL_HINTING_INFINALITY ) if ( SUBPIXEL_HINTING_INFINALITY )
@ -6314,7 +6355,10 @@
} }
if ( reverse_move ) 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 */ #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
@ -6380,7 +6424,7 @@
distance = PROJECT( exc->zp1.cur + point, distance = PROJECT( exc->zp1.cur + point,
exc->zp0.cur + exc->GS.rp0 ); 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--; exc->GS.loop--;
@ -6437,19 +6481,19 @@
/* Cramer's rule */ /* Cramer's rule */
dbx = exc->zp0.cur[b1].x - exc->zp0.cur[b0].x; dbx = SUB_LONG( exc->zp0.cur[b1].x, exc->zp0.cur[b0].x );
dby = exc->zp0.cur[b1].y - exc->zp0.cur[b0].y; dby = SUB_LONG( exc->zp0.cur[b1].y, exc->zp0.cur[b0].y );
dax = exc->zp1.cur[a1].x - exc->zp1.cur[a0].x; dax = SUB_LONG( exc->zp1.cur[a1].x, exc->zp1.cur[a0].x );
day = exc->zp1.cur[a1].y - exc->zp1.cur[a0].y; day = SUB_LONG( exc->zp1.cur[a1].y, exc->zp1.cur[a0].y );
dx = exc->zp0.cur[b0].x - exc->zp1.cur[a0].x; dx = SUB_LONG( exc->zp0.cur[b0].x, exc->zp1.cur[a0].x );
dy = exc->zp0.cur[b0].y - exc->zp1.cur[a0].y; dy = SUB_LONG( exc->zp0.cur[b0].y, exc->zp1.cur[a0].y );
discriminant = FT_MulDiv( dax, -dby, 0x40 ) + discriminant = ADD_LONG( FT_MulDiv( dax, NEG_LONG( dby ), 0x40 ),
FT_MulDiv( day, dbx, 0x40 ); FT_MulDiv( day, dbx, 0x40 ) );
dotproduct = FT_MulDiv( dax, dbx, 0x40 ) + dotproduct = ADD_LONG( FT_MulDiv( dax, dbx, 0x40 ),
FT_MulDiv( day, dby, 0x40 ); FT_MulDiv( day, dby, 0x40 ) );
/* The discriminant above is actually a cross product of vectors */ /* The discriminant above is actually a cross product of vectors */
/* da and db. Together with the dot product, they can be used as */ /* da and db. Together with the dot product, they can be used as */
@ -6459,30 +6503,29 @@
/* discriminant = |da||db|sin(angle) . */ /* discriminant = |da||db|sin(angle) . */
/* We use these equations to reject grazing intersections by */ /* We use these equations to reject grazing intersections by */
/* thresholding abs(tan(angle)) at 1/19, corresponding to 3 degrees. */ /* 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.x = FT_MulDiv( val, dax, discriminant );
R.y = FT_MulDiv( val, day, discriminant ); R.y = FT_MulDiv( val, day, discriminant );
/* XXX: Block in backward_compatibility and/or post-IUP? */ /* 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].x = ADD_LONG( exc->zp1.cur[a0].x, R.x );
exc->zp2.cur[point].y = exc->zp1.cur[a0].y + R.y; exc->zp2.cur[point].y = ADD_LONG( exc->zp1.cur[a0].y, R.y );
} }
else else
{ {
/* else, take the middle of the middles of A and B */ /* else, take the middle of the middles of A and B */
/* XXX: Block in backward_compatibility and/or post-IUP? */ /* XXX: Block in backward_compatibility and/or post-IUP? */
exc->zp2.cur[point].x = ( exc->zp1.cur[a0].x + exc->zp2.cur[point].x =
exc->zp1.cur[a1].x + ADD_LONG( ADD_LONG( exc->zp1.cur[a0].x, exc->zp1.cur[a1].x ),
exc->zp0.cur[b0].x + ADD_LONG( exc->zp0.cur[b0].x, exc->zp0.cur[b1].x ) ) / 4;
exc->zp0.cur[b1].x ) / 4; exc->zp2.cur[point].y =
exc->zp2.cur[point].y = ( exc->zp1.cur[a0].y + ADD_LONG( ADD_LONG( exc->zp1.cur[a0].y, exc->zp1.cur[a1].y ),
exc->zp1.cur[a1].y + ADD_LONG( exc->zp0.cur[b0].y, exc->zp0.cur[b1].y ) ) / 4;
exc->zp0.cur[b0].y +
exc->zp0.cur[b1].y ) / 4;
} }
exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH;
@ -6517,7 +6560,7 @@
distance = PROJECT( exc->zp0.cur + p2, exc->zp1.cur + p1 ) / 2; distance = PROJECT( exc->zp0.cur + p2, exc->zp1.cur + p1 ) / 2;
exc->func_move( exc, &exc->zp1, p1, distance ); 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; 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 ); 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 ); exc->metrics.y_scale );
old_range = FAST_DUALPROJ( &vec ); old_range = FAST_DUALPROJ( &vec );
@ -6627,9 +6672,11 @@
FT_Vector vec; 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 ); 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 ); exc->metrics.y_scale );
org_dist = FAST_DUALPROJ( &vec ); org_dist = FAST_DUALPROJ( &vec );
@ -6668,7 +6715,7 @@
exc->func_move( exc, exc->func_move( exc,
&exc->zp2, &exc->zp2,
(FT_UShort)point, (FT_UShort)point,
new_dist - cur_dist ); SUB_LONG( new_dist, cur_dist ) );
} }
Fail: Fail:
@ -6733,14 +6780,14 @@
FT_F26Dot6 dx; 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 ) if ( dx != 0 )
{ {
for ( i = p1; i < p; i++ ) 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++ ) 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; org2 = worker->orgs[ref2].x;
cur1 = worker->curs[ref1].x; cur1 = worker->curs[ref1].x;
cur2 = worker->curs[ref2].x; cur2 = worker->curs[ref2].x;
delta1 = cur1 - org1; delta1 = SUB_LONG( cur1, org1 );
delta2 = cur2 - org2; delta2 = SUB_LONG( cur2, org2 );
if ( cur1 == cur2 || orus1 == orus2 ) if ( cur1 == cur2 || orus1 == orus2 )
{ {
@ -6798,10 +6845,10 @@
if ( x <= org1 ) if ( x <= org1 )
x += delta1; x = ADD_LONG( x, delta1 );
else if ( x >= org2 ) else if ( x >= org2 )
x += delta2; x = ADD_LONG( x, delta2 );
else else
x = cur1; x = cur1;
@ -6822,20 +6869,23 @@
if ( x <= org1 ) if ( x <= org1 )
x += delta1; x = ADD_LONG( x, delta1 );
else if ( x >= org2 ) else if ( x >= org2 )
x += delta2; x = ADD_LONG( x, delta2 );
else else
{ {
if ( !scale_valid ) if ( !scale_valid )
{ {
scale_valid = 1; 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; worker->curs[i].x = x;
} }
@ -7310,7 +7360,11 @@
K |= 1 << 12; K |= 1 << 12;
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL #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 */ /* HINTING FOR SUBPIXEL */
@ -7345,7 +7399,7 @@
/* */ /* */
/* The only smoothing method FreeType supports unless someone sets */ /* The only smoothing method FreeType supports unless someone sets */
/* FT_LOAD_TARGET_MONO. */ /* FT_LOAD_TARGET_MONO. */
if ( ( args[0] & 2048 ) != 0 ) if ( ( args[0] & 2048 ) != 0 && exc->subpixel_hinting_lean )
K |= 1 << 18; K |= 1 << 18;
/********************************/ /********************************/
@ -7589,11 +7643,21 @@
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL #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 */ * Toggle backward compatibility according to what font wants, except
/* render glyphs correctly, e.g. DFKai-SB. Backward compatibility */ * when
/* hacks may break it. */ *
* 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 && if ( SUBPIXEL_HINTING_MINIMAL &&
exc->subpixel_hinting_lean &&
!FT_IS_TRICKY( &exc->face->root ) ) !FT_IS_TRICKY( &exc->face->root ) )
exc->backward_compatibility = !( exc->GS.instruct_control & 4 ); exc->backward_compatibility = !( exc->GS.instruct_control & 4 );
else else
@ -7639,8 +7703,7 @@
FT_MAX( 50, FT_MAX( 50,
exc->cvtSize / 10 ); exc->cvtSize / 10 );
else else
exc->loopcall_counter_max = FT_MAX( 100, exc->loopcall_counter_max = 300 + 8 * exc->cvtSize;
10 * exc->cvtSize );
/* as a protection against an unreasonable number of CVT entries */ /* as a protection against an unreasonable number of CVT entries */
/* we assume at most 100 control values per glyph for the counter */ /* we assume at most 100 control values per glyph for the counter */

View File

@ -253,23 +253,38 @@ FT_BEGIN_HEADER
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
/* /*
* Modern TrueType fonts are usually rendered through Microsoft's * FreeType supports ClearType-like hinting of TrueType fonts through
* collection of rendering techniques called ClearType (e.g., subpixel * the version 40 interpreter. This is achieved through several hacks
* rendering and subpixel hinting). When ClearType was introduced, most * in the base (v35) interpreter, as detailed below.
* 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).
* *
* The minimal subpixel hinting code (interpreter version 40) employs a * ClearType is an umbrella term for several rendering techniques
* small list of font-agnostic hacks to bludgeon non-native-ClearType * employed by Microsoft's various GUI and rendering toolkit
* fonts (except tricky ones[1]) into submission. It will not try to * implementations, most importantly: subpixel rendering for using the
* toggle hacks for specific fonts for performance and complexity * RGB subpixels of LCDs to approximately triple the perceived
* reasons. The focus is on modern (web)fonts rather than legacy fonts * resolution on the x-axis and subpixel hinting for positioning stems
* that were made for black-and-white rendering. * 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 * 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 */ /* version switches. `_lean' to differentiate from the Infinality */
/* `subpixel_hinting', which is managed differently. */ /* `subpixel_hinting', which is managed differently. */
FT_Bool subpixel_hinting_lean; FT_Bool subpixel_hinting_lean;

View File

@ -576,9 +576,11 @@
/* We must also be able to accept Mac/GX fonts, as well as OT ones. */ /* We must also be able to accept Mac/GX fonts, as well as OT ones. */
/* The 0x00020000 tag is completely undocumented; some fonts from */ /* The 0x00020000 tag is completely undocumented; some fonts from */
/* Arphic made for Chinese Windows 3.1 have this. */ /* Arphic made for Chinese Windows 3.1 have this. */
if ( face->format_tag != 0x00010000L && /* MS fonts */ if ( face->format_tag != 0x00010000L && /* MS fonts */
face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */ face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */
face->format_tag != TTAG_true ) /* Mac fonts */ 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" )); FT_TRACE2(( " not a TTF font\n" ));
goto Bad_Format; goto Bad_Format;
@ -1230,7 +1232,9 @@
/* <Input> */ /* <Input> */
/* size :: A handle to the target size object. */ /* size :: A handle to the target size object. */
/* */ /* */
/* only_height :: Only recompute ascender, descender, and height. */ /* 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 ) FT_LOCAL_DEF( FT_Error )
tt_size_reset( TT_Size size, tt_size_reset( TT_Size size,
@ -1277,7 +1281,11 @@
size->ttmetrics.valid = TRUE; size->ttmetrics.valid = TRUE;
if ( only_height ) 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; return FT_Err_Ok;
}
if ( face->header.Flags & 8 ) if ( face->header.Flags & 8 )
{ {

View File

@ -247,13 +247,13 @@
if ( pos2 > face->glyf_len ) if ( pos2 > face->glyf_len )
{ {
/* We try to sanitize the last `loca' entry. */ /* 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:" 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", " truncating at the end of `glyf' table to %ld bytes\n",
pos2, gindex + 1, face->glyf_len )); pos2 - pos1, gindex, face->glyf_len - pos1 ));
pos2 = face->glyf_len; pos2 = face->glyf_len;
} }
else else

View File

@ -329,8 +329,8 @@
for ( i = 0; i < mmaster.num_axis; i++ ) for ( i = 0; i < mmaster.num_axis; i++ )
{ {
mmvar->axis[i].name = mmaster.axis[i].name; mmvar->axis[i].name = mmaster.axis[i].name;
mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum); 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].maximum = INT_TO_FIXED( mmaster.axis[i].maximum );
mmvar->axis[i].def = ( mmvar->axis[i].minimum + mmvar->axis[i].def = ( mmvar->axis[i].minimum +
mmvar->axis[i].maximum ) / 2; mmvar->axis[i].maximum ) / 2;
/* Does not apply. But this value is in range */ /* Does not apply. But this value is in range */

View File

@ -555,12 +555,6 @@
if ( clazz ) if ( clazz )
error = FT_CMap_New( clazz, NULL, &charmap, NULL ); error = FT_CMap_New( clazz, NULL, &charmap, NULL );
#if 0
/* Select default charmap */
if (root->num_charmaps)
root->charmap = root->charmaps[0];
#endif
} }
} }

View File

@ -394,12 +394,6 @@
if ( clazz ) if ( clazz )
error = FT_CMap_New( clazz, NULL, &charmap, NULL ); error = FT_CMap_New( clazz, NULL, &charmap, NULL );
#if 0
/* Select default charmap */
if ( root->num_charmaps )
root->charmap = root->charmaps[0];
#endif
} }
} }
Exit: Exit:

View File

@ -859,10 +859,6 @@
NULL ); NULL );
if ( error ) if ( error )
goto Fail; goto Fail;
/* Select default charmap */
if ( root->num_charmaps )
root->charmap = root->charmaps[0];
} }
/* set up remaining flags */ /* set up remaining flags */
@ -1095,7 +1091,7 @@
/* note: since glyphs are stored in columns and not in rows we */ /* note: since glyphs are stored in columns and not in rows we */
/* can't use ft_glyphslot_set_bitmap */ /* 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; goto Exit;
column = (FT_Byte*)bitmap->buffer; column = (FT_Byte*)bitmap->buffer;