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
- Upstream: https://www.freetype.org
- Version: 2.8
- Version: 2.8.1
- License: FreeType License (BSD-like)
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 */
/* (a.k.a. LCD rendering, or ClearType) in this build of the library. */
/* Uncomment the line below if you want to activate LCD rendering */
/* technology similar to ClearType in this build of the library. This */
/* technology triples the resolution in the direction color subpixels. */
/* To mitigate color fringes inherent to this technology, you also need */
/* to explicitly set up LCD filtering. */
/* */
/* Note that this feature is covered by several Microsoft patents */
/* and should not be activated in any default build of the library. */
/* */
/* This macro has no impact on the FreeType API, only on its */
/* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */
/* FT_Render_Glyph still generates a bitmap that is 3 times wider than */
/* the original size in case this macro isn't defined; however, each */
/* triplet of subpixels has R=G=B. */
/* */
/* This is done to allow FreeType clients to run unmodified, forcing */
/* them to display normal gray-level anti-aliased glyphs. */
/* When this macro is not defined, FreeType offers alternative LCD */
/* rendering technology that produces excellent output without LCD */
/* filtering. */
/* */
/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
@ -327,7 +324,7 @@ FT_BEGIN_HEADER
/* */
/* - The TrueType driver will provide its own set of glyph names, */
/* if you build it to support postscript names in the TrueType */
/* `post' table. */
/* `post' table, but will not synthesize a missing Unicode charmap. */
/* */
/* - The Type 1 driver will not be able to synthesize a Unicode */
/* charmap out of the glyphs found in the fonts. */

View File

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

View File

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

View File

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

View File

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

View File

@ -231,6 +231,12 @@ FT_BEGIN_HEADER
/* <Return> */
/* 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_Get_Glyph( FT_GlyphSlot slot,
FT_Glyph *aglyph );
@ -566,6 +572,9 @@ FT_BEGIN_HEADER
/* <Note> */
/* The result is undefined if either `a' or `b' is zero. */
/* */
/* Since the function uses wrap-around arithmetic, results become */
/* meaningless if the arguments are very large. */
/* */
FT_EXPORT( void )
FT_Matrix_Multiply( const FT_Matrix* a,
FT_Matrix* b );

View File

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

View File

@ -44,9 +44,16 @@ FT_BEGIN_HEADER
* Reduce color fringes of subpixel-rendered bitmaps.
*
* @description:
* Subpixel rendering exploits the color-striped structure of LCD
* pixels, increasing the available resolution in the direction of the
* stripe (usually horizontal RGB) by a factor of~3. Since these
* Should you #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your
* `ftoption.h', which enables patented ClearType-style rendering,
* the LCD-optimized glyph bitmaps should be filtered to reduce color
* fringes inherent to this technology. The default FreeType LCD
* rendering uses different technology, and API described below,
* although available, does nothing.
*
* ClearType-style LCD rendering exploits the color-striped structure of
* LCD pixels, increasing the available resolution in the direction of
* the stripe (usually horizontal RGB) by a factor of~3. Since these
* subpixels are color pixels, using them unfiltered creates severe
* color fringes. Use the @FT_Library_SetLcdFilter API to specify a
* low-pass filter, which is then applied to subpixel-rendered bitmaps
@ -54,12 +61,6 @@ FT_BEGIN_HEADER
* the higher resolution to reduce color fringes, making the glyph image
* slightly blurrier. Positional improvements will remain.
*
* Note that no filter is active by default, and that this function is
* *not* implemented in default builds of the library. You need to
* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your `ftoption.h' file
* in order to activate it and explicitly call @FT_Library_SetLcdFilter
* to enable it.
*
* A filter should have two properties:
*
* 1) It should be normalized, meaning the sum of the 5~components

View File

@ -35,11 +35,12 @@
FT_BEGIN_HEADER
/* gcc-3.4.1 and later can warn about functions tagged as deprecated */
/* gcc-3.1 and later can warn about functions tagged as deprecated */
#ifndef FT_DEPRECATED_ATTRIBUTE
#if defined(__GNUC__) && \
((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
#define FT_DEPRECATED_ATTRIBUTE __attribute__((deprecated))
#if defined( __GNUC__ ) && \
( ( __GNUC__ >= 4 ) || \
( ( __GNUC__ == 3 ) && ( __GNUC_MINOR__ >= 1 ) ) )
#define FT_DEPRECATED_ATTRIBUTE __attribute__(( deprecated ))
#else
#define FT_DEPRECATED_ATTRIBUTE
#endif

View File

@ -178,7 +178,8 @@ FT_BEGIN_HEADER
/* strid :: The entry in `name' table identifying this instance. */
/* */
/* psid :: The entry in `name' table identifying a PostScript name */
/* for this instance. */
/* for this instance. Value 0xFFFF indicates a missing */
/* entry. */
/* */
typedef struct FT_Var_Named_Style_
{
@ -195,7 +196,7 @@ FT_BEGIN_HEADER
/* FT_MM_Var */
/* */
/* <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. */
/* */
/* Some fields are specific to one format and not to the others. */
@ -321,6 +322,11 @@ FT_BEGIN_HEADER
/* <Return> */
/* 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_Set_MM_Design_Coordinates( FT_Face face,
FT_UInt num_coords,
@ -351,6 +357,11 @@ FT_BEGIN_HEADER
/* <Return> */
/* 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_Set_Var_Design_Coordinates( FT_Face face,
FT_UInt num_coords,
@ -415,6 +426,11 @@ FT_BEGIN_HEADER
/* <Return> */
/* 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_Set_MM_Blend_Coordinates( FT_Face face,
FT_UInt num_coords,
@ -479,6 +495,50 @@ FT_BEGIN_HEADER
FT_UInt num_coords,
FT_Fixed* coords );
/*************************************************************************/
/* */
/* <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 */
/* directions. */
/* */
/* <Since> */
/* 2.4.10 */
/* */
FT_EXPORT( FT_Error )
FT_Outline_EmboldenXY( FT_Outline* outline,
FT_Pos xstrength,

View File

@ -399,16 +399,42 @@ FT_BEGIN_HEADER
#endif /* 0 */
#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 )
#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 )
#define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 )
#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 )
#define FLOAT_TO_FIXED( x ) ( (FT_Long)( x * 65536.0 ) )
#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) * 64 ) /* << 6 */
#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) * 16384 ) /* << 14 */
#define INT_TO_FIXED( x ) ( (FT_Long)(x) * 65536 ) /* << 16 */
#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) * 4 ) /* << 2 */
#define FIXED_TO_INT( x ) ( FT_RoundFix( x ) >> 16 )
#define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \
: ( -( ( 32 - (x) ) & -64 ) ) )
/*
* The following macros have two purposes.
*
* . Tag places where overflow is expected and harmless.
*
* . Avoid run-time sanitizer errors.
*
* Use with care!
*/
#define ADD_LONG( a, b ) \
(FT_Long)( (FT_ULong)(a) + (FT_ULong)(b) )
#define SUB_LONG( a, b ) \
(FT_Long)( (FT_ULong)(a) - (FT_ULong)(b) )
#define MUL_LONG( a, b ) \
(FT_Long)( (FT_ULong)(a) * (FT_ULong)(b) )
#define NEG_LONG( a ) \
(FT_Long)( (FT_ULong)0 - (FT_ULong)(a) )
#define ADD_INT32( a, b ) \
(FT_Int32)( (FT_UInt32)(a) + (FT_UInt32)(b) )
#define SUB_INT32( a, b ) \
(FT_Int32)( (FT_UInt32)(a) - (FT_UInt32)(b) )
#define MUL_INT32( a, b ) \
(FT_Int32)( (FT_UInt32)(a) * (FT_UInt32)(b) )
#define NEG_INT32( a ) \
(FT_Int32)( (FT_UInt32)0 - (FT_UInt32)(a) )
FT_END_HEADER

View File

@ -36,6 +36,7 @@
#include FT_INTERNAL_AUTOHINT_H
#include FT_INTERNAL_SERVICE_H
#include FT_INTERNAL_PIC_H
#include FT_INTERNAL_CALC_H
#ifdef FT_CONFIG_OPTION_INCREMENTAL
#include FT_INCREMENTAL_H
@ -85,13 +86,29 @@ FT_BEGIN_HEADER
/* we use FT_TYPEOF to suppress signedness compilation warnings */
#define FT_PAD_FLOOR( x, n ) ( (x) & ~FT_TYPEOF( x )( (n)-1 ) )
#define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + ((n)/2), n )
#define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + ((n)-1), n )
#define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + (n)/2, n )
#define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + (n)-1, n )
#define FT_PIX_FLOOR( x ) ( (x) & ~FT_TYPEOF( x )63 )
#define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 )
#define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 )
/* specialized versions (for signed values) */
/* that don't produce run-time errors due to integer overflow */
#define FT_PAD_ROUND_LONG( x, n ) FT_PAD_FLOOR( ADD_LONG( (x), (n) / 2 ), \
n )
#define FT_PAD_CEIL_LONG( x, n ) FT_PAD_FLOOR( ADD_LONG( (x), (n) - 1 ), \
n )
#define FT_PIX_ROUND_LONG( x ) FT_PIX_FLOOR( ADD_LONG( (x), 32 ) )
#define FT_PIX_CEIL_LONG( x ) FT_PIX_FLOOR( ADD_LONG( (x), 63 ) )
#define FT_PAD_ROUND_INT32( x, n ) FT_PAD_FLOOR( ADD_INT32( (x), (n) / 2 ), \
n )
#define FT_PAD_CEIL_INT32( x, n ) FT_PAD_FLOOR( ADD_INT32( (x), (n) - 1 ), \
n )
#define FT_PIX_ROUND_INT32( x ) FT_PIX_FLOOR( ADD_INT32( (x), 32 ) )
#define FT_PIX_CEIL_INT32( x ) FT_PIX_FLOOR( ADD_INT32( (x), 63 ) )
/*
* character classification functions -- since these are used to parse
@ -856,11 +873,6 @@ FT_BEGIN_HEADER
/* */
/* auto_hinter :: The auto-hinter module interface. */
/* */
/* raster_pool :: The raster object's render pool. This can */
/* ideally be changed dynamically at run-time. */
/* */
/* raster_pool_size :: The size of the render pool in bytes. */
/* */
/* debug_hooks :: An array of four function pointers that allow */
/* debuggers to hook into a font format's */
/* interpreter. Currently, only the TrueType */
@ -869,9 +881,6 @@ FT_BEGIN_HEADER
/* lcd_filter :: If subpixel rendering is activated, the */
/* selected LCD filter mode. */
/* */
/* lcd_extra :: If subpixel rendering is activated, the number */
/* of extra pixels needed for the LCD filter. */
/* */
/* lcd_weights :: If subpixel rendering is activated, the LCD */
/* filter weights, if any. */
/* */
@ -903,15 +912,10 @@ FT_BEGIN_HEADER
FT_Renderer cur_renderer; /* current outline renderer */
FT_Module auto_hinter;
FT_Byte* raster_pool; /* scan-line conversion */
/* render pool */
FT_ULong raster_pool_size; /* size of render pool in bytes */
FT_DebugHook_Func debug_hooks[4];
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
FT_LcdFilter lcd_filter;
FT_Int lcd_extra; /* number of extra pixels */
FT_LcdFiveTapFilter lcd_weights; /* filter weights, if any */
FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */
#endif

View File

@ -106,6 +106,12 @@ FT_BEGIN_HEADER
#define TTAG_VVAR FT_MAKE_TAG( 'V', 'V', 'A', 'R' )
#define TTAG_wOFF FT_MAKE_TAG( 'w', 'O', 'F', 'F' )
/* used by "Keyboard.dfont" on legacy Mac OS X */
#define TTAG_0xA5kbd FT_MAKE_TAG( 0xA5, 'k', 'b', 'd' )
/* used by "LastResort.dfont" on legacy Mac OS X */
#define TTAG_0xA5lst FT_MAKE_TAG( 0xA5, 'l', 's', 't' )
FT_END_HEADER

View File

@ -592,9 +592,6 @@
{ AF_BLUE_STRING_KAYAH_LI_DESCENDER, 0 },
{ AF_BLUE_STRING_KAYAH_LI_LARGE_DESCENDER, 0 },
{ AF_BLUE_STRING_MAX, 0 },
{ AF_BLUE_STRING_KANNADA_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
{ AF_BLUE_STRING_KANNADA_BOTTOM, 0 },
{ AF_BLUE_STRING_MAX, 0 },
{ AF_BLUE_STRING_KHMER_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
{ AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP, AF_BLUE_PROPERTY_LATIN_SUB_TOP },
@ -606,6 +603,9 @@
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
{ AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM, 0 },
{ AF_BLUE_STRING_MAX, 0 },
{ AF_BLUE_STRING_KANNADA_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
{ AF_BLUE_STRING_KANNADA_BOTTOM, 0 },
{ AF_BLUE_STRING_MAX, 0 },
{ AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
{ AF_BLUE_STRING_LAO_BOTTOM, 0 },
@ -701,6 +701,9 @@
{ AF_BLUE_STRING_TELUGU_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
{ AF_BLUE_STRING_TELUGU_BOTTOM, 0 },
{ AF_BLUE_STRING_MAX, 0 },
{ AF_BLUE_STRING_TIFINAGH, AF_BLUE_PROPERTY_LATIN_TOP },
{ AF_BLUE_STRING_TIFINAGH, 0 },
{ AF_BLUE_STRING_MAX, 0 },
{ AF_BLUE_STRING_THAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
{ AF_BLUE_STRING_THAI_BOTTOM, 0 },
@ -710,9 +713,6 @@
{ AF_BLUE_STRING_THAI_LARGE_DESCENDER, 0 },
{ AF_BLUE_STRING_THAI_DIGIT_TOP, 0 },
{ AF_BLUE_STRING_MAX, 0 },
{ AF_BLUE_STRING_TIFINAGH, AF_BLUE_PROPERTY_LATIN_TOP },
{ AF_BLUE_STRING_TIFINAGH, 0 },
{ AF_BLUE_STRING_MAX, 0 },
{ AF_BLUE_STRING_VAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
{ AF_BLUE_STRING_VAI_BOTTOM, 0 },
{ AF_BLUE_STRING_MAX, 0 },

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_MAX, 0 }
AF_BLUE_STRINGSET_KNDA
{ AF_BLUE_STRING_KANNADA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
{ AF_BLUE_STRING_KANNADA_BOTTOM, 0 }
{ AF_BLUE_STRING_MAX, 0 }
AF_BLUE_STRINGSET_KHMR
{ AF_BLUE_STRING_KHMER_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
@ -892,6 +887,11 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN:
{ AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM, 0 }
{ AF_BLUE_STRING_MAX, 0 }
AF_BLUE_STRINGSET_KNDA
{ AF_BLUE_STRING_KANNADA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
{ AF_BLUE_STRING_KANNADA_BOTTOM, 0 }
{ AF_BLUE_STRING_MAX, 0 }
AF_BLUE_STRINGSET_LAO
{ AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
@ -1027,6 +1027,11 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN:
{ AF_BLUE_STRING_TELUGU_BOTTOM, 0 }
{ AF_BLUE_STRING_MAX, 0 }
AF_BLUE_STRINGSET_TFNG
{ AF_BLUE_STRING_TIFINAGH, AF_BLUE_PROPERTY_LATIN_TOP }
{ AF_BLUE_STRING_TIFINAGH, 0 }
{ AF_BLUE_STRING_MAX, 0 }
AF_BLUE_STRINGSET_THAI
{ AF_BLUE_STRING_THAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
@ -1038,11 +1043,6 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN:
{ AF_BLUE_STRING_THAI_DIGIT_TOP, 0 }
{ AF_BLUE_STRING_MAX, 0 }
AF_BLUE_STRINGSET_TFNG
{ AF_BLUE_STRING_TIFINAGH, AF_BLUE_PROPERTY_LATIN_TOP }
{ AF_BLUE_STRING_TIFINAGH, 0 }
{ AF_BLUE_STRING_MAX, 0 }
AF_BLUE_STRINGSET_VAII
{ AF_BLUE_STRING_VAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
{ AF_BLUE_STRING_VAI_BOTTOM, 0 }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -187,12 +187,6 @@
HINTING_BOTTOM_TO_TOP,
"\xEA\xA4\x8D \xEA\xA4\x80" ) /* ꤍ ꤀ */
SCRIPT( knda, KNDA,
"Kannada",
HB_SCRIPT_KANNADA,
HINTING_BOTTOM_TO_TOP,
"\xE0\xB3\xA6 \xE0\xB2\xAC" ) /* ಬ */
/* only digit zero has a simple shape in the Khmer script */
SCRIPT( khmr, KHMR,
"Khmer",
@ -206,6 +200,12 @@
HINTING_BOTTOM_TO_TOP,
"\xE1\xA7\xA1 \xE1\xA7\xAA" ) /* ᧡ ᧪ */
SCRIPT( knda, KNDA,
"Kannada",
HB_SCRIPT_KANNADA,
HINTING_BOTTOM_TO_TOP,
"\xE0\xB3\xA6 \xE0\xB2\xAC" ) /* ಬ */
/* only digit zero has a simple shape in the Lao script */
SCRIPT( lao, LAO,
"Lao",
@ -330,18 +330,18 @@
HINTING_BOTTOM_TO_TOP,
"\xE0\xB1\xA6 \xE0\xB1\xA7" ) /* ౧ */
SCRIPT( thai, THAI,
"Thai",
HB_SCRIPT_THAI,
HINTING_BOTTOM_TO_TOP,
"\xE0\xB8\xB2 \xE0\xB9\x85 \xE0\xB9\x90" ) /* า ๅ */
SCRIPT( tfng, TFNG,
"Tifinagh",
HB_SCRIPT_TIFINAGH,
HINTING_BOTTOM_TO_TOP,
"\xE2\xB5\x94" ) /* */
SCRIPT( thai, THAI,
"Thai",
HB_SCRIPT_THAI,
HINTING_BOTTOM_TO_TOP,
"\xE0\xB8\xB2 \xE0\xB9\x85 \xE0\xB9\x90" ) /* า ๅ */
SCRIPT( vaii, VAII,
"Vai",
HB_SCRIPT_VAI,

View File

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

View File

@ -255,13 +255,6 @@
AF_BLUE_STRINGSET_KALI,
AF_COVERAGE_DEFAULT )
STYLE( knda_dflt, KNDA_DFLT,
"Kannada default style",
AF_WRITING_SYSTEM_LATIN,
AF_SCRIPT_KNDA,
AF_BLUE_STRINGSET_KNDA,
AF_COVERAGE_DEFAULT )
STYLE( khmr_dflt, KHMR_DFLT,
"Khmer default style",
AF_WRITING_SYSTEM_LATIN,
@ -276,6 +269,13 @@
AF_BLUE_STRINGSET_KHMS,
AF_COVERAGE_DEFAULT )
STYLE( knda_dflt, KNDA_DFLT,
"Kannada default style",
AF_WRITING_SYSTEM_LATIN,
AF_SCRIPT_KNDA,
AF_BLUE_STRINGSET_KNDA,
AF_COVERAGE_DEFAULT )
STYLE( lao_dflt, LAO_DFLT,
"Lao default style",
AF_WRITING_SYSTEM_LATIN,
@ -420,13 +420,6 @@
AF_BLUE_STRINGSET_TELU,
AF_COVERAGE_DEFAULT )
STYLE( thai_dflt, THAI_DFLT,
"Thai default style",
AF_WRITING_SYSTEM_LATIN,
AF_SCRIPT_THAI,
AF_BLUE_STRINGSET_THAI,
AF_COVERAGE_DEFAULT )
STYLE( tfng_dflt, TFNG_DFLT,
"Tifinagh default style",
AF_WRITING_SYSTEM_LATIN,
@ -434,6 +427,13 @@
AF_BLUE_STRINGSET_TFNG,
AF_COVERAGE_DEFAULT )
STYLE( thai_dflt, THAI_DFLT,
"Thai default style",
AF_WRITING_SYSTEM_LATIN,
AF_SCRIPT_THAI,
AF_BLUE_STRINGSET_THAI,
AF_COVERAGE_DEFAULT )
STYLE( vaii_dflt, VAII_DFLT,
"Vai default style",
AF_WRITING_SYSTEM_LATIN,

View File

@ -226,7 +226,7 @@
}
/* otherwise allocate new buffer */
if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) )
if ( FT_QALLOC_MULT( buffer, bitmap->rows + ypixels, new_pitch ) )
return error;
/* new rows get added at the top of the bitmap, */
@ -534,8 +534,7 @@
(FT_ULong)target->rows > FT_ULONG_MAX / (FT_ULong)target_pitch )
return FT_THROW( Invalid_Argument );
if ( target->rows * (FT_ULong)target_pitch > old_size &&
FT_QREALLOC( target->buffer,
if ( FT_QREALLOC( target->buffer,
old_size, target->rows * (FT_UInt)target_pitch ) )
return error;

View File

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

View File

@ -408,12 +408,28 @@
goto Exit;
/* copy advance while converting 26.6 to 16.16 format */
if ( slot->advance.x >= 0x8000L * 64 ||
slot->advance.x <= -0x8000L * 64 )
{
FT_ERROR(( "FT_Get_Glyph: advance width too large\n" ));
error = FT_THROW( Invalid_Argument );
goto Exit2;
}
if ( slot->advance.y >= 0x8000L * 64 ||
slot->advance.y <= -0x8000L * 64 )
{
FT_ERROR(( "FT_Get_Glyph: advance height too large\n" ));
error = FT_THROW( Invalid_Argument );
goto Exit2;
}
glyph->advance.x = slot->advance.x * 1024;
glyph->advance.y = slot->advance.y * 1024;
/* now import the image from the glyph slot */
error = clazz->glyph_init( glyph, slot );
Exit2:
/* if an error occurred, destroy the glyph */
if ( error )
FT_Done_Glyph( glyph );

View File

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

View File

@ -1005,7 +1005,7 @@
/* accepts an FSRef instead of a path. */
/* */
/* This function is deprecated because Carbon data types (FSRef) */
/* are not cross-platform, and thus not suitable for the freetype API. */
/* are not cross-platform, and thus not suitable for the FreeType API. */
FT_EXPORT_DEF( FT_Error )
FT_New_Face_From_FSRef( FT_Library library,
const FSRef* ref,

View File

@ -158,7 +158,7 @@
/* check of `face' delayed to `ft_face_get_mm_service' */
if ( !coords )
if ( num_coords && !coords )
return FT_THROW( Invalid_Argument );
error = ft_face_get_mm_service( face, &service );
@ -194,7 +194,7 @@
/* check of `face' delayed to `ft_face_get_mm_service' */
if ( !coords )
if ( num_coords && !coords )
return FT_THROW( Invalid_Argument );
error = ft_face_get_mm_service( face, &service_mm );
@ -266,7 +266,7 @@
/* check of `face' delayed to `ft_face_get_mm_service' */
if ( !coords )
if ( num_coords && !coords )
return FT_THROW( Invalid_Argument );
error = ft_face_get_mm_service( face, &service_mm );
@ -313,7 +313,7 @@
/* check of `face' delayed to `ft_face_get_mm_service' */
if ( !coords )
if ( num_coords && !coords )
return FT_THROW( Invalid_Argument );
error = ft_face_get_mm_service( face, &service_mm );
@ -402,4 +402,28 @@
}
/* documentation is in ftmm.h */
FT_EXPORT_DEF( FT_Error )
FT_Get_Var_Axis_Flags( FT_MM_Var* master,
FT_UInt axis_index,
FT_UInt* flags )
{
FT_UShort* axis_flags;
if ( !master || !flags )
return FT_THROW( Invalid_Argument );
if ( axis_index >= master->num_axis )
return FT_THROW( Invalid_Argument );
/* the axis flags array immediately follows the data of `master' */
axis_flags = (FT_UShort*)&( master[1] );
*flags = axis_flags[axis_index];
return FT_Err_Ok;
}
/* END */

View File

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

View File

@ -1088,7 +1088,8 @@
v_cur.x = points[n].x >> xshift;
v_cur.y = points[n].y >> yshift;
area += ( v_cur.y - v_prev.y ) * ( v_cur.x + v_prev.x );
area = ADD_LONG( area,
( v_cur.y - v_prev.y ) * ( v_cur.x + v_prev.x ) );
v_prev = v_cur;
}

View File

@ -271,7 +271,13 @@
if ( FT_STREAM_SKIP( 4 ) ) /* mbz */
goto Exit;
if ( ref[j].res_id < 0 || temp < 0 )
/*
* According to Inside Macintosh: More Macintosh Toolbox,
* "Resource IDs" (1-46), there are some reserved IDs.
* However, FreeType2 is not a font synthesizer, no need
* to check the acceptable resource ID.
*/
if ( temp < 0 )
{
error = FT_THROW( Invalid_Table );
goto Exit;
@ -281,7 +287,7 @@
FT_TRACE3(( " [%d]:"
" resource_id=0x%04x, offset=0x%08x\n",
j, ref[j].res_id, ref[j].offset ));
j, (FT_UShort)ref[j].res_id, ref[j].offset ));
}
if ( sort_by_res_id )

View File

@ -123,7 +123,7 @@
/*
* XXX: overflow check for 16-bit system, for compatibility
* with FT_GlyphSlot_Embolden() since freetype-2.1.10.
* with FT_GlyphSlot_Embolden() since FreeType 2.1.10.
* unfortunately, this function return no informations
* about the cause of error.
*/

View File

@ -135,7 +135,7 @@
ft_mem_free( memory, block );
block = NULL;
}
else if ( new_count > FT_INT_MAX/item_size )
else if ( new_count > FT_INT_MAX / item_size )
{
error = FT_THROW( Array_Too_Large );
}
@ -143,13 +143,15 @@
{
FT_ASSERT( !block );
block = ft_mem_alloc( memory, new_count*item_size, &error );
block = memory->alloc( memory, new_count * item_size );
if ( block == NULL )
error = FT_THROW( Out_Of_Memory );
}
else
{
FT_Pointer block2;
FT_Long cur_size = cur_count*item_size;
FT_Long new_size = new_count*item_size;
FT_Long cur_size = cur_count * item_size;
FT_Long new_size = new_count * item_size;
block2 = memory->realloc( memory, cur_size, new_size, block );

View File

@ -373,7 +373,7 @@ THE SOFTWARE.
/* we have a bdf font: let's construct the face object */
face->bdffont = font;
/* BDF could not have multiple face in single font file.
/* BDF cannot have multiple faces in a single font file.
* XXX: non-zero face_index is already invalid argument, but
* Type1, Type42 driver has a convention to return
* an invalid argument error when the font could be
@ -437,46 +437,156 @@ THE SOFTWARE.
{
FT_Bitmap_Size* bsize = bdfface->available_sizes;
FT_Short resolution_x = 0, resolution_y = 0;
long value;
FT_ZERO( bsize );
/* sanity checks */
if ( font->font_ascent > 0x7FFF || font->font_ascent < -0x7FFF )
{
font->font_ascent = font->font_ascent < 0 ? -0x7FFF : 0x7FFF;
FT_TRACE0(( "BDF_Face_Init: clamping font ascent to value %d\n",
font->font_ascent ));
}
if ( font->font_descent > 0x7FFF || font->font_descent < -0x7FFF )
{
font->font_descent = font->font_descent < 0 ? -0x7FFF : 0x7FFF;
FT_TRACE0(( "BDF_Face_Init: clamping font descent to value %d\n",
font->font_descent ));
}
bsize->height = (FT_Short)( font->font_ascent + font->font_descent );
prop = bdf_get_font_property( font, "AVERAGE_WIDTH" );
if ( prop )
bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 );
{
#ifdef FT_DEBUG_LEVEL_TRACE
if ( prop->value.l < 0 )
FT_TRACE0(( "BDF_Face_Init: negative average width\n" ));
#endif
if ( prop->value.l > 0x7FFFL * 10 - 5 ||
prop->value.l < -( 0x7FFFL * 10 - 5 ) )
{
bsize->width = 0x7FFF;
FT_TRACE0(( "BDF_Face_Init: clamping average width to value %d\n",
bsize->width ));
}
else
bsize->width = FT_ABS( (FT_Short)( ( prop->value.l + 5 ) / 10 ) );
}
else
bsize->width = (FT_Short)( bsize->height * 2/3 );
{
/* this is a heuristical value */
bsize->width = (FT_Short)FT_MulDiv( bsize->height, 2, 3 );
}
prop = bdf_get_font_property( font, "POINT_SIZE" );
if ( prop )
{
#ifdef FT_DEBUG_LEVEL_TRACE
if ( prop->value.l < 0 )
FT_TRACE0(( "BDF_Face_Init: negative point size\n" ));
#endif
/* convert from 722.7 decipoints to 72 points per inch */
bsize->size =
(FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L );
if ( prop->value.l > 0x504C2L || /* 0x7FFF * 72270/7200 */
prop->value.l < -0x504C2L )
{
bsize->size = 0x7FFF;
FT_TRACE0(( "BDF_Face_Init: clamping point size to value %d\n",
bsize->size ));
}
else
bsize->size = FT_MulDiv( FT_ABS( prop->value.l ),
64 * 7200,
72270L );
}
else if ( font->point_size )
{
if ( font->point_size > 0x7FFF )
{
bsize->size = 0x7FFF;
FT_TRACE0(( "BDF_Face_Init: clamping point size to value %d\n",
bsize->size ));
}
else
bsize->size = (FT_Pos)font->point_size << 6;
}
else
bsize->size = bsize->width << 6;
{
/* this is a heuristical value */
bsize->size = bsize->width * 64;
}
prop = bdf_get_font_property( font, "PIXEL_SIZE" );
if ( prop )
bsize->y_ppem = (FT_Short)prop->value.l << 6;
{
#ifdef FT_DEBUG_LEVEL_TRACE
if ( prop->value.l < 0 )
FT_TRACE0(( "BDF_Face_Init: negative pixel size\n" ));
#endif
if ( prop->value.l > 0x7FFF || prop->value.l < -0x7FFF )
{
bsize->y_ppem = 0x7FFF << 6;
FT_TRACE0(( "BDF_Face_Init: clamping pixel size to value %d\n",
bsize->y_ppem ));
}
else
bsize->y_ppem = FT_ABS( (FT_Short)prop->value.l ) << 6;
}
prop = bdf_get_font_property( font, "RESOLUTION_X" );
if ( prop )
resolution_x = (FT_Short)prop->value.l;
value = prop->value.l;
else
value = (long)font->resolution_x;
if ( value )
{
#ifdef FT_DEBUG_LEVEL_TRACE
if ( value < 0 )
FT_TRACE0(( "BDF_Face_Init: negative X resolution\n" ));
#endif
if ( value > 0x7FFF || value < -0x7FFF )
{
resolution_x = 0x7FFF;
FT_TRACE0(( "BDF_Face_Init: clamping X resolution to value %d\n",
resolution_x ));
}
else
resolution_x = FT_ABS( (FT_Short)value );
}
prop = bdf_get_font_property( font, "RESOLUTION_Y" );
if ( prop )
resolution_y = (FT_Short)prop->value.l;
value = prop->value.l;
else
value = (long)font->resolution_y;
if ( value )
{
#ifdef FT_DEBUG_LEVEL_TRACE
if ( value < 0 )
FT_TRACE0(( "BDF_Face_Init: negative Y resolution\n" ));
#endif
if ( value > 0x7FFF || value < -0x7FFF )
{
resolution_y = 0x7FFF;
FT_TRACE0(( "BDF_Face_Init: clamping Y resolution to value %d\n",
resolution_y ));
}
else
resolution_y = FT_ABS( (FT_Short)value );
}
if ( bsize->y_ppem == 0 )
{
bsize->y_ppem = bsize->size;
if ( resolution_y )
bsize->y_ppem = bsize->y_ppem * resolution_y / 72;
bsize->y_ppem = FT_MulDiv( bsize->y_ppem, resolution_y, 72 );
}
if ( resolution_x && resolution_y )
bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y;
bsize->x_ppem = FT_MulDiv( bsize->y_ppem,
resolution_x,
resolution_y );
else
bsize->x_ppem = bsize->y_ppem;
}
@ -545,7 +655,11 @@ THE SOFTWARE.
if ( !ft_strcmp( s, "10646" ) ||
( !ft_strcmp( s, "8859" ) &&
!ft_strcmp( face->charset_encoding, "1" ) ) )
unicode_charmap = 1;
unicode_charmap = 1;
/* another name for ASCII */
else if ( !ft_strcmp( s, "646.1991" ) &&
!ft_strcmp( face->charset_encoding, "IRV" ) )
unicode_charmap = 1;
}
{
@ -566,12 +680,6 @@ THE SOFTWARE.
}
error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL );
#if 0
/* Select default charmap */
if ( bdfface->num_charmaps )
bdfface->charmap = bdfface->charmaps[0];
#endif
}
goto Exit;

View File

@ -704,7 +704,15 @@
return 0;
for ( v = 0; sbitset( ddigits, *s ); s++ )
v = v * 10 + a2i[(int)*s];
{
if ( v < ( ULONG_MAX - 9 ) / 10 )
v = v * 10 + a2i[(int)*s];
else
{
v = ULONG_MAX;
break;
}
}
return v;
}
@ -729,7 +737,15 @@
}
for ( v = 0; sbitset( ddigits, *s ); s++ )
v = v * 10 + a2i[(int)*s];
{
if ( v < ( LONG_MAX - 9 ) / 10 )
v = v * 10 + a2i[(int)*s];
else
{
v = LONG_MAX;
break;
}
}
return ( !neg ) ? v : -v;
}
@ -746,7 +762,15 @@
return 0;
for ( v = 0; sbitset( ddigits, *s ); s++ )
v = (unsigned short)( v * 10 + a2i[(int)*s] );
{
if ( v < ( USHRT_MAX - 9 ) / 10 )
v = (unsigned short)( v * 10 + a2i[(int)*s] );
else
{
v = USHRT_MAX;
break;
}
}
return v;
}
@ -771,7 +795,15 @@
}
for ( v = 0; sbitset( ddigits, *s ); s++ )
v = (short)( v * 10 + a2i[(int)*s] );
{
if ( v < ( SHRT_MAX - 9 ) / 10 )
v = (short)( v * 10 + a2i[(int)*s] );
else
{
v = SHRT_MAX;
break;
}
}
return (short)( ( !neg ) ? v : -v );
}

View File

@ -304,10 +304,18 @@
if ( anode )
*anode = NULL;
if ( (FT_ULong)( type->flags - FT_INT_MIN ) > FT_UINT_MAX )
/*
* Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt',
* but public `FT_ImageType->flags' is of type `FT_Int32'.
*
* On 16bit systems, higher bits of type->flags cannot be handled.
*/
#if 0xFFFFFFFFUL > FT_UINT_MAX
if ( (type->flags & (FT_ULong)FT_UINT_MAX) )
FT_TRACE1(( "FTC_ImageCache_Lookup:"
" higher bits in load_flags 0x%x are dropped\n",
(FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) ));
#endif
query.attrs.scaler.face_id = type->face_id;
query.attrs.scaler.width = type->width;
@ -377,11 +385,18 @@
if ( anode )
*anode = NULL;
/* `FT_Load_Glyph' and `FT_Load_Char' take FT_UInt flags */
/*
* Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt',
* but public `FT_Face->face_flags' is of type `FT_Long'.
*
* On long > int systems, higher bits of load_flags cannot be handled.
*/
#if FT_ULONG_MAX > FT_UINT_MAX
if ( load_flags > FT_UINT_MAX )
FT_TRACE1(( "FTC_ImageCache_LookupScaler:"
" higher bits in load_flags 0x%x are dropped\n",
load_flags & ~((FT_ULong)FT_UINT_MAX) ));
#endif
query.attrs.scaler = scaler[0];
query.attrs.load_flags = (FT_UInt)load_flags;
@ -487,10 +502,18 @@
*ansbit = NULL;
if ( (FT_ULong)( type->flags - FT_INT_MIN ) > FT_UINT_MAX )
/*
* Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt',
* but public `FT_ImageType->flags' is of type `FT_Int32'.
*
* On 16bit systems, higher bits of type->flags cannot be handled.
*/
#if 0xFFFFFFFFUL > FT_UINT_MAX
if ( (type->flags & (FT_ULong)FT_UINT_MAX) )
FT_TRACE1(( "FTC_ImageCache_Lookup:"
" higher bits in load_flags 0x%x are dropped\n",
(FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) ));
#endif
query.attrs.scaler.face_id = type->face_id;
query.attrs.scaler.width = type->width;
@ -562,11 +585,18 @@
*ansbit = NULL;
/* `FT_Load_Glyph' and `FT_Load_Char' take FT_UInt flags */
/*
* Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt',
* but public `FT_Face->face_flags' is of type `FT_Long'.
*
* On long > int systems, higher bits of load_flags cannot be handled.
*/
#if FT_ULONG_MAX > FT_UINT_MAX
if ( load_flags > FT_UINT_MAX )
FT_TRACE1(( "FTC_ImageCache_LookupScaler:"
" higher bits in load_flags 0x%x are dropped\n",
load_flags & ~((FT_ULong)FT_UINT_MAX) ));
#endif
query.attrs.scaler = scaler[0];
query.attrs.load_flags = (FT_UInt)load_flags;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,6 +20,7 @@
#include "cffparse.h"
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_CALC_H
#include "cfferrs.h"
#include "cffpic.h"
@ -156,6 +157,22 @@
1000000000L
};
/* maximum values allowed for multiplying */
/* with the corresponding `power_tens' element */
static const FT_Long power_ten_limits[] =
{
FT_LONG_MAX / 1L,
FT_LONG_MAX / 10L,
FT_LONG_MAX / 100L,
FT_LONG_MAX / 1000L,
FT_LONG_MAX / 10000L,
FT_LONG_MAX / 100000L,
FT_LONG_MAX / 1000000L,
FT_LONG_MAX / 10000000L,
FT_LONG_MAX / 100000000L,
FT_LONG_MAX / 1000000000L,
};
/* read a real */
static FT_Fixed
@ -484,7 +501,15 @@
if ( scaling )
{
if ( FT_ABS( val ) > power_ten_limits[scaling] )
{
val = val > 0 ? 0x7FFFFFFFL : -0x7FFFFFFFL;
goto Overflow;
}
val *= power_tens[scaling];
}
if ( val > 0x7FFF )
{
@ -1585,7 +1610,7 @@
val = 0;
while ( num_args > 0 )
{
val += cff_parse_num( parser, data++ );
val = ADD_LONG( val, cff_parse_num( parser, data++ ) );
switch ( field->size )
{
case (8 / FT_CHAR_BIT):

View File

@ -9,7 +9,7 @@ gxvalid: TrueType GX validator
additional tables in TrueType font which are used by `QuickDraw GX
Text', Apple Advanced Typography (AAT). In addition, gxvalid can
validates `kern' tables which have been extended for AAT. Like the
otvalid module, gxvalid uses Freetype 2's validator framework
otvalid module, gxvalid uses FreeType 2's validator framework
(ftvalid).
You can link gxvalid with your program; before running your own layout

View File

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

View File

@ -387,7 +387,11 @@ THE SOFTWARE.
if ( !ft_strcmp( s, "10646" ) ||
( !ft_strcmp( s, "8859" ) &&
!ft_strcmp( face->charset_encoding, "1" ) ) )
unicode_charmap = 1;
unicode_charmap = 1;
/* another name for ASCII */
else if ( !ft_strcmp( s, "646.1991" ) &&
!ft_strcmp( face->charset_encoding, "IRV" ) )
unicode_charmap = 1;
}
}
@ -409,12 +413,6 @@ THE SOFTWARE.
}
error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL );
#if 0
/* Select default charmap */
if ( pcfface->num_charmaps )
pcfface->charmap = pcfface->charmaps[0];
#endif
}
}

View File

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

View File

@ -264,12 +264,6 @@
charmap.encoding = FT_ENCODING_UNICODE;
error = FT_CMap_New( &pfr_cmap_class_rec, NULL, &charmap, NULL );
#if 0
/* select default charmap */
if ( pfrface->num_charmaps )
pfrface->charmap = pfrface->charmaps[0];
#endif
}
/* check whether we have loaded any kerning pairs */

View File

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

View File

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

View File

@ -23,8 +23,21 @@
#include "psmodule.h"
/*
* The file `pstables.h' with its arrays and its function
* `ft_get_adobe_glyph_index' is useful for other projects also (for
* example, `pdfium' is using it). However, if used as a C++ header,
* including it in two different source files makes it necessary to use
* `extern const' for the declaration of its arrays, otherwise the data
* would be duplicated as mandated by the C++ standard.
*
* For this reason, we use `DEFINE_PS_TABLES' to guard the function
* definitions, and `DEFINE_PS_TABLES_DATA' to provide both proper array
* declarations and definitions.
*/
#include "pstables.h"
#define DEFINE_PS_TABLES
#define DEFINE_PS_TABLES_DATA
#include "pstables.h"
#include "psnamerr.h"

View File

@ -19,7 +19,7 @@
/* This file has been generated automatically -- do not edit! */
#ifndef DEFINE_PS_TABLES
#ifndef DEFINE_PS_TABLES_DATA
#ifdef __cplusplus
extern "C"
#else
@ -27,7 +27,7 @@
#endif
#endif
const char ft_standard_glyph_names[3696]
#ifdef DEFINE_PS_TABLES
#ifdef DEFINE_PS_TABLES_DATA
=
{
'.','n','u','l','l', 0,
@ -451,7 +451,7 @@
'R','o','m','a','n', 0,
'S','e','m','i','b','o','l','d', 0,
}
#endif /* DEFINE_PS_TABLES */
#endif /* DEFINE_PS_TABLES_DATA */
;
@ -459,7 +459,7 @@
/* Values are offsets into the `ft_standard_glyph_names' table */
#ifndef DEFINE_PS_TABLES
#ifndef DEFINE_PS_TABLES_DATA
#ifdef __cplusplus
extern "C"
#else
@ -467,7 +467,7 @@
#endif
#endif
const short ft_mac_names[FT_NUM_MAC_NAMES]
#ifdef DEFINE_PS_TABLES
#ifdef DEFINE_PS_TABLES_DATA
=
{
253, 0, 6, 261, 267, 274, 283, 294, 301, 309, 758, 330, 340, 351,
@ -490,7 +490,7 @@
1270,1313,1323,1171,1290,1332,1211,1235,1276, 169, 175, 182, 189, 200,
209, 218, 225, 232, 239, 246
}
#endif /* DEFINE_PS_TABLES */
#endif /* DEFINE_PS_TABLES_DATA */
;
@ -498,7 +498,7 @@
/* Values are offsets into the `ft_standard_glyph_names' table */
#ifndef DEFINE_PS_TABLES
#ifndef DEFINE_PS_TABLES_DATA
#ifdef __cplusplus
extern "C"
#else
@ -506,7 +506,7 @@
#endif
#endif
const short ft_sid_names[FT_NUM_SID_NAMES]
#ifdef DEFINE_PS_TABLES
#ifdef DEFINE_PS_TABLES_DATA
=
{
253, 261, 267, 274, 283, 294, 301, 309, 319, 330, 340, 351, 360, 365,
@ -538,12 +538,12 @@
3418,3430,3442,3454,3471,3483,3498,3506,3518,3530,3542,3559,3574,3586,
3597,3612,3620,3628,3636,3644,3650,3655,3660,3666,3673,3681,3687
}
#endif /* DEFINE_PS_TABLES */
#endif /* DEFINE_PS_TABLES_DATA */
;
/* the following are indices into the SID name table */
#ifndef DEFINE_PS_TABLES
#ifndef DEFINE_PS_TABLES_DATA
#ifdef __cplusplus
extern "C"
#else
@ -551,7 +551,7 @@
#endif
#endif
const unsigned short t1_standard_encoding[256]
#ifdef DEFINE_PS_TABLES
#ifdef DEFINE_PS_TABLES_DATA
=
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -571,12 +571,12 @@
0,138, 0,139, 0, 0, 0, 0,140,141,142,143, 0, 0, 0, 0,
0,144, 0, 0, 0,145, 0, 0,146,147,148,149, 0, 0, 0, 0
}
#endif /* DEFINE_PS_TABLES */
#endif /* DEFINE_PS_TABLES_DATA */
;
/* the following are indices into the SID name table */
#ifndef DEFINE_PS_TABLES
#ifndef DEFINE_PS_TABLES_DATA
#ifdef __cplusplus
extern "C"
#else
@ -584,7 +584,7 @@
#endif
#endif
const unsigned short t1_expert_encoding[256]
#ifdef DEFINE_PS_TABLES
#ifdef DEFINE_PS_TABLES_DATA
=
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -604,7 +604,7 @@
347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,
363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378
}
#endif /* DEFINE_PS_TABLES */
#endif /* DEFINE_PS_TABLES_DATA */
;
@ -619,7 +619,7 @@
#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
#ifndef DEFINE_PS_TABLES
#ifndef DEFINE_PS_TABLES_DATA
#ifdef __cplusplus
extern "C"
#else
@ -627,7 +627,7 @@
#endif
#endif
const unsigned char ft_adobe_glyph_list[55997L]
#ifdef DEFINE_PS_TABLES
#ifdef DEFINE_PS_TABLES_DATA
=
{
0, 52, 0,106, 2,167, 3, 63, 4,220, 6,125, 9,143, 10, 23,
@ -4131,7 +4131,7 @@
182,117, 2,218,167,218,178,232,233,242,225,231,225,238, 97,128,
48, 90,235,225,244,225,235,225,238, 97,128, 48,186
}
#endif /* DEFINE_PS_TABLES */
#endif /* DEFINE_PS_TABLES_DATA */
;

View File

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

View File

@ -49,18 +49,82 @@
}
/* Premultiplies data and converts RGBA bytes => native endian. */
/* Premultiplies data and converts RGBA bytes => BGRA. */
static void
premultiply_data( png_structp png,
png_row_infop row_info,
png_bytep data )
{
unsigned int i;
unsigned int i = 0, limit;
/* The `vector_size' attribute was introduced in gcc 3.1, which */
/* predates clang; the `__BYTE_ORDER__' preprocessor symbol was */
/* introduced in gcc 4.6 and clang 3.2, respectively. */
/* `__builtin_shuffle' for gcc was introduced in gcc 4.7.0. */
#if ( ( defined( __GNUC__ ) && \
( ( __GNUC__ >= 5 ) || \
( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 7 ) ) ) ) || \
( defined( __clang__ ) && \
( ( __clang_major__ >= 4 ) || \
( ( __clang_major__ == 3 ) && ( __clang_minor__ >= 2 ) ) ) ) ) && \
defined( __OPTIMIZE__ ) && \
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#ifdef __clang__
/* the clang documentation doesn't cover the two-argument case of */
/* `__builtin_shufflevector'; however, it is is implemented since */
/* version 2.8 */
#define vector_shuffle __builtin_shufflevector
#else
#define vector_shuffle __builtin_shuffle
#endif
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 );
for ( i = 0; i < row_info->rowbytes; i += 4 )
limit = row_info->rowbytes;
for ( ; i < limit; i += 4 )
{
unsigned char* base = &data[i];
unsigned int alpha = base[3];

View File

@ -787,6 +787,8 @@
tag != TTAG_OTTO &&
tag != TTAG_true &&
tag != TTAG_typ1 &&
tag != TTAG_0xA5kbd &&
tag != TTAG_0xA5lst &&
tag != 0x00020000UL )
{
FT_TRACE2(( " not a font using the SFNT container format\n" ));
@ -1224,7 +1226,10 @@
goto Exit;
}
if ( face->header.Units_Per_EM == 0 )
/* OpenType 1.8.2 introduced limits to this value; */
/* however, they make sense for older SFNT fonts also */
if ( face->header.Units_Per_EM < 16 ||
face->header.Units_Per_EM > 16384 )
{
error = FT_THROW( Invalid_Table );
@ -1464,7 +1469,8 @@
/* Polish the charmaps. */
/* */
/* Try to set the charmap encoding according to the platform & */
/* encoding ID of each charmap. */
/* encoding ID of each charmap. Emulate Unicode charmap if one */
/* is missing. */
/* */
tt_face_build_cmaps( face ); /* ignore errors */
@ -1472,7 +1478,10 @@
/* set the encoding fields */
{
FT_Int m;
FT_Int m;
#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
FT_Bool has_unicode = FALSE;
#endif
for ( m = 0; m < root->num_charmaps; m++ )
@ -1483,14 +1492,34 @@
charmap->encoding = sfnt_find_encoding( charmap->platform_id,
charmap->encoding_id );
#if 0
if ( !root->charmap &&
charmap->encoding == FT_ENCODING_UNICODE )
{
/* set 'root->charmap' to the first Unicode encoding we find */
root->charmap = charmap;
}
#endif
#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
if ( charmap->encoding == FT_ENCODING_UNICODE ||
charmap->encoding == FT_ENCODING_MS_SYMBOL ) /* PUA */
has_unicode = TRUE;
}
/* synthesize Unicode charmap if one is missing */
if ( !has_unicode )
{
FT_CharMapRec cmaprec;
cmaprec.face = root;
cmaprec.platform_id = TT_PLATFORM_MICROSOFT;
cmaprec.encoding_id = TT_MS_ID_UNICODE_CS;
cmaprec.encoding = FT_ENCODING_UNICODE;
error = FT_CMap_New( (FT_CMap_Class)&tt_cmap_unicode_class_rec,
NULL, &cmaprec, NULL );
if ( error &&
FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) )
goto Exit;
error = FT_Err_Ok;
#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
}
}

View File

@ -23,8 +23,10 @@
#include FT_INTERNAL_VALIDATE_H
#include FT_INTERNAL_STREAM_H
#include FT_SERVICE_POSTSCRIPT_CMAPS_H
#include "ttload.h"
#include "ttcmap.h"
#include "ttpost.h"
#include "sfntpic.h"
@ -3622,6 +3624,110 @@
#endif /* TT_CONFIG_CMAP_FORMAT_14 */
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** SYNTHETIC UNICODE *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* This charmap is generated using postscript glyph names. */
#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
FT_CALLBACK_DEF( const char * )
tt_get_glyph_name( TT_Face face,
FT_UInt idx )
{
FT_String* PSname;
tt_face_get_ps_name( face, idx, &PSname );
return PSname;
}
FT_CALLBACK_DEF( FT_Error )
tt_cmap_unicode_init( PS_Unicodes unicodes,
FT_Pointer pointer )
{
TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
FT_Memory memory = FT_FACE_MEMORY( face );
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
FT_UNUSED( pointer );
return psnames->unicodes_init( memory,
unicodes,
face->root.num_glyphs,
(PS_GetGlyphNameFunc)&tt_get_glyph_name,
(PS_FreeGlyphNameFunc)NULL,
(FT_Pointer)face );
}
FT_CALLBACK_DEF( void )
tt_cmap_unicode_done( PS_Unicodes unicodes )
{
FT_Face face = FT_CMAP_FACE( unicodes );
FT_Memory memory = FT_FACE_MEMORY( face );
FT_FREE( unicodes->maps );
unicodes->num_maps = 0;
}
FT_CALLBACK_DEF( FT_UInt )
tt_cmap_unicode_char_index( PS_Unicodes unicodes,
FT_UInt32 char_code )
{
TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
return psnames->unicodes_char_index( unicodes, char_code );
}
FT_CALLBACK_DEF( FT_UInt32 )
tt_cmap_unicode_char_next( PS_Unicodes unicodes,
FT_UInt32 *pchar_code )
{
TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
return psnames->unicodes_char_next( unicodes, pchar_code );
}
FT_DEFINE_TT_CMAP(
tt_cmap_unicode_class_rec,
sizeof ( PS_UnicodesRec ),
(FT_CMap_InitFunc) tt_cmap_unicode_init, /* init */
(FT_CMap_DoneFunc) tt_cmap_unicode_done, /* done */
(FT_CMap_CharIndexFunc)tt_cmap_unicode_char_index, /* char_index */
(FT_CMap_CharNextFunc) tt_cmap_unicode_char_next, /* char_next */
(FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
(FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
(FT_CMap_VariantListFunc) NULL, /* variant_list */
(FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
(FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
~0U,
(TT_CMap_ValidateFunc)NULL, /* validate */
(TT_CMap_Info_GetFunc)NULL /* get_cmap_info */
)
#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
#ifndef FT_CONFIG_OPTION_PIC
static const TT_CMap_Class tt_cmap_classes[] =
@ -3801,8 +3907,10 @@
FT_CMap cmap = (FT_CMap)charmap;
TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz;
return clazz->get_cmap_info( charmap, cmap_info );
if ( clazz->get_cmap_info )
return clazz->get_cmap_info( charmap, cmap_info );
else
return FT_THROW( Invalid_CharMap_Format );
}

View File

@ -141,6 +141,8 @@ FT_BEGIN_HEADER
#define TT_VALID_GLYPH_COUNT( x ) TT_VALIDATOR( x )->num_glyphs
FT_CALLBACK_TABLE const TT_CMap_ClassRec tt_cmap_unicode_class_rec;
FT_LOCAL( FT_Error )
tt_face_build_cmaps( TT_Face face );

View File

@ -85,7 +85,7 @@
for ( nn = 0; nn < num_tables; nn++ )
{
FT_UInt num_pairs, length, coverage;
FT_UInt num_pairs, length, coverage, format;
FT_Byte* p_next;
FT_UInt32 mask = (FT_UInt32)1UL << nn;
@ -107,6 +107,12 @@
if ( p_next > p_limit ) /* handle broken table */
p_next = p_limit;
format = coverage >> 8;
/* we currently only support format 0 kerning tables */
if ( format != 0 )
goto NextTable;
/* only use horizontal kerning tables */
if ( ( coverage & 3U ) != 0x0001 ||
p + 8 > p_next )

View File

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

View File

@ -448,6 +448,15 @@
metrics->max_advance =
FT_MulDiv( hori->advance_Width_Max, ppem_ * 64, upem );
/* set the scale values (in 16.16 units) so advances */
/* from the hmtx and vmtx table are scaled correctly */
metrics->x_scale = FT_MulDiv( metrics->x_ppem,
64 * 0x10000,
face->header.Units_Per_EM );
metrics->y_scale = FT_MulDiv( metrics->y_ppem,
64 * 0x10000,
face->header.Units_Per_EM );
return error;
}
@ -1439,10 +1448,17 @@
return FT_THROW( Invalid_Table );
NoBitmap:
if ( recurse_count )
{
FT_TRACE4(( "tt_sbit_decoder_load_image:"
" missing subglyph sbit with glyph index %d\n",
glyph_index ));
return FT_THROW( Invalid_Composite );
}
FT_TRACE4(( "tt_sbit_decoder_load_image:"
" no sbit found for glyph index %d\n", glyph_index ));
return FT_THROW( Invalid_Argument );
return FT_THROW( Missing_Bitmap );
}

View File

@ -141,6 +141,16 @@
#define FT_INT_MAX INT_MAX
#define FT_ULONG_MAX ULONG_MAX
#define ADD_LONG( a, b ) \
(long)( (unsigned long)(a) + (unsigned long)(b) )
#define SUB_LONG( a, b ) \
(long)( (unsigned long)(a) - (unsigned long)(b) )
#define MUL_LONG( a, b ) \
(long)( (unsigned long)(a) * (unsigned long)(b) )
#define NEG_LONG( a ) \
(long)( -(unsigned long)(a) )
#define ft_memset memset
#define ft_setjmp setjmp
@ -264,6 +274,7 @@ typedef ptrdiff_t FT_PtrDist;
#include "ftgrays.h"
#include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_CALC_H
#include FT_OUTLINE_H
#include "ftsmerrs.h"
@ -1135,7 +1146,7 @@ typedef ptrdiff_t FT_PtrDist;
/* s is L * the perpendicular distance from P1 to the line P0-P3. */
dx1 = arc[1].x - arc[0].x;
dy1 = arc[1].y - arc[0].y;
s = FT_ABS( dy * dx1 - dx * dy1 );
s = FT_ABS( SUB_LONG( MUL_LONG( dy, dx1 ), MUL_LONG( dx, dy1 ) ) );
if ( s > s_limit )
goto Split;
@ -1143,7 +1154,7 @@ typedef ptrdiff_t FT_PtrDist;
/* s is L * the perpendicular distance from P2 to the line P0-P3. */
dx2 = arc[2].x - arc[0].x;
dy2 = arc[2].y - arc[0].y;
s = FT_ABS( dy * dx2 - dx * dy2 );
s = FT_ABS( SUB_LONG( MUL_LONG( dy, dx2 ), MUL_LONG( dx, dy2 ) ) );
if ( s > s_limit )
goto Split;

View File

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

View File

@ -87,7 +87,7 @@
/*************************************************************************/
/* */
/* Return the vertical metrics in font units for a given glyph. */
/* See macro `TT_LOADER_SET_PP' below for explanations. */
/* See function `tt_loader_set_pp' below for explanations. */
/* */
FT_LOCAL_DEF( void )
TT_Get_VMetrics( TT_Face face,
@ -825,7 +825,7 @@
/* compatibility mode, where no movement on the x axis means no reason */
/* to change bearings or advance widths. */
if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
!loader->exec->backward_compatibility ) )
loader->exec->backward_compatibility ) )
{
#endif
loader->pp1 = zone->cur[zone->n_points - 4];
@ -1686,7 +1686,7 @@
/***********************************************************************/
/* otherwise, load a composite! */
else if ( loader->n_contours == -1 )
else if ( loader->n_contours < 0 )
{
FT_Memory memory = face->root.memory;
@ -1697,6 +1697,9 @@
FT_ListNode node, node2;
/* normalize the `n_contours' value */
loader->n_contours = -1;
/*
* We store the glyph index directly in the `node->data' pointer,
* following the glib solution (cf. macro `GUINT_TO_POINTER') with a
@ -1991,12 +1994,6 @@
}
}
}
else
{
/* invalid composite count (negative but not -1) */
error = FT_THROW( Invalid_Outline );
goto Exit;
}
/***********************************************************************/
/***********************************************************************/
@ -2100,8 +2097,8 @@
}
/* set glyph dimensions */
glyph->metrics.width = bbox.xMax - bbox.xMin;
glyph->metrics.height = bbox.yMax - bbox.yMin;
glyph->metrics.width = SUB_LONG( bbox.xMax, bbox.xMin );
glyph->metrics.height = SUB_LONG( bbox.yMax, bbox.yMin );
/* Now take care of vertical metrics. In the case where there is */
/* no vertical information within the font (relatively common), */
@ -2137,7 +2134,8 @@
/* table in the font. Otherwise, we use the */
/* values defined in the horizontal header. */
height = (FT_Short)FT_DivFix( bbox.yMax - bbox.yMin,
height = (FT_Short)FT_DivFix( SUB_LONG( bbox.yMax,
bbox.yMin ),
y_scale );
if ( face->os2.version != 0xFFFFU )
advance = (FT_Pos)( face->os2.sTypoAscender -
@ -2339,13 +2337,19 @@
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
{
subpixel_hinting_lean = TRUE;
grayscale_cleartype = !FT_BOOL( load_flags &
FT_LOAD_TARGET_LCD ||
load_flags &
FT_LOAD_TARGET_LCD_V );
exec->vertical_lcd_lean = FT_BOOL( load_flags &
FT_LOAD_TARGET_LCD_V );
subpixel_hinting_lean =
FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
FT_RENDER_MODE_MONO );
grayscale_cleartype =
FT_BOOL( subpixel_hinting_lean &&
!( ( load_flags &
FT_LOAD_TARGET_LCD ) ||
( load_flags &
FT_LOAD_TARGET_LCD_V ) ) );
exec->vertical_lcd_lean =
FT_BOOL( subpixel_hinting_lean &&
( load_flags &
FT_LOAD_TARGET_LCD_V ) );
}
else
{
@ -2621,7 +2625,64 @@
IS_DEFAULT_INSTANCE )
{
error = load_sbit_image( size, glyph, glyph_index, load_flags );
if ( !error )
if ( FT_ERR_EQ( error, Missing_Bitmap ) )
{
/* the bitmap strike is incomplete and misses the requested glyph; */
/* if we have a bitmap-only font, return an empty glyph */
if ( !FT_IS_SCALABLE( glyph->face ) )
{
TT_Face face = (TT_Face)glyph->face;
FT_Short left_bearing = 0, top_bearing = 0;
FT_UShort advance_width = 0, advance_height = 0;
/* to return an empty glyph, however, we need metrics data */
/* from the `hmtx' (or `vmtx') table; the assumption is that */
/* empty glyphs are missing intentionally, representing */
/* whitespace - not having at least horizontal metrics is */
/* thus considered an error */
if ( !face->horz_metrics_size )
return error;
/* we now construct an empty bitmap glyph */
TT_Get_HMetrics( face, glyph_index,
&left_bearing,
&advance_width );
TT_Get_VMetrics( face, glyph_index,
0,
&top_bearing,
&advance_height );
glyph->outline.n_points = 0;
glyph->outline.n_contours = 0;
glyph->metrics.width = 0;
glyph->metrics.height = 0;
glyph->metrics.horiBearingX = left_bearing;
glyph->metrics.horiBearingY = 0;
glyph->metrics.horiAdvance = advance_width;
glyph->metrics.vertBearingX = 0;
glyph->metrics.vertBearingY = top_bearing;
glyph->metrics.vertAdvance = advance_height;
glyph->format = FT_GLYPH_FORMAT_BITMAP;
glyph->bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
glyph->bitmap_left = 0;
glyph->bitmap_top = 0;
return FT_Err_Ok;
}
}
else if ( error )
{
/* return error if font is not scalable */
if ( !FT_IS_SCALABLE( glyph->face ) )
return error;
}
else
{
if ( FT_IS_SCALABLE( glyph->face ) )
{

View File

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

View File

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

View File

@ -253,23 +253,38 @@ FT_BEGIN_HEADER
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
/*
* Modern TrueType fonts are usually rendered through Microsoft's
* collection of rendering techniques called ClearType (e.g., subpixel
* rendering and subpixel hinting). When ClearType was introduced, most
* fonts were not ready. Microsoft decided to implement a backward
* compatibility mode that employed several simple to complicated
* assumptions and tricks that modified the interpretation of the
* bytecode contained in these fonts to make them look ClearType-y
* somehow. Most (web)fonts that were released since then have come to
* rely on these hacks to render correctly, even some of Microsoft's
* flagship ClearType fonts (Calibri, Cambria, Segoe UI).
* FreeType supports ClearType-like hinting of TrueType fonts through
* the version 40 interpreter. This is achieved through several hacks
* in the base (v35) interpreter, as detailed below.
*
* The minimal subpixel hinting code (interpreter version 40) employs a
* small list of font-agnostic hacks to bludgeon non-native-ClearType
* fonts (except tricky ones[1]) into submission. It will not try to
* toggle hacks for specific fonts for performance and complexity
* reasons. The focus is on modern (web)fonts rather than legacy fonts
* that were made for black-and-white rendering.
* ClearType is an umbrella term for several rendering techniques
* employed by Microsoft's various GUI and rendering toolkit
* implementations, most importantly: subpixel rendering for using the
* RGB subpixels of LCDs to approximately triple the perceived
* resolution on the x-axis and subpixel hinting for positioning stems
* on subpixel borders. TrueType programming is explicit, i.e., fonts
* must be programmed to take advantage of ClearType's possibilities.
*
* When ClearType was introduced, it seemed unlikely that all fonts
* would be reprogrammed, so Microsoft decided to implement a backward
* compatibility mode. It employs several simple to complicated
* assumptions and tricks, many of them font-dependent, that modify the
* interpretation of the bytecode contained in these fonts to retrofit
* them into a ClearType-y look. The quality of the results varies.
* Most (web)fonts that were released since then have come to rely on
* these hacks to render correctly, even some of Microsoft's flagship
* fonts (e.g., Calibri, Cambria, Segoe UI).
*
* FreeType's minimal subpixel hinting code (interpreter version 40)
* employs a small list of font-agnostic hacks loosely based on the
* public information available on Microsoft's compatibility mode[2].
* The focus is on modern (web)fonts rather than legacy fonts that were
* made for monochrome rendering. It will not match ClearType rendering
* exactly. Unlike the `Infinality' code (interpreter version 38) that
* came before, it will not try to toggle hacks for specific fonts for
* performance and complexity reasons. It will fall back to version 35
* behavior for tricky fonts[1] or when monochrome rendering is
* requested.
*
* Major hacks
*
@ -347,7 +362,8 @@ FT_BEGIN_HEADER
*
*/
/* Using v40 implies subpixel hinting. Used to detect interpreter */
/* Using v40 implies subpixel hinting, unless FT_RENDER_MODE_MONO has been
* requested. Used to detect interpreter */
/* version switches. `_lean' to differentiate from the Infinality */
/* `subpixel_hinting', which is managed differently. */
FT_Bool subpixel_hinting_lean;

View File

@ -576,9 +576,11 @@
/* We must also be able to accept Mac/GX fonts, as well as OT ones. */
/* The 0x00020000 tag is completely undocumented; some fonts from */
/* Arphic made for Chinese Windows 3.1 have this. */
if ( face->format_tag != 0x00010000L && /* MS fonts */
face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */
face->format_tag != TTAG_true ) /* Mac fonts */
if ( face->format_tag != 0x00010000L && /* MS fonts */
face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */
face->format_tag != TTAG_true && /* Mac fonts */
face->format_tag != TTAG_0xA5kbd && /* `Keyboard.dfont' (legacy Mac OS X) */
face->format_tag != TTAG_0xA5lst ) /* `LastResort.dfont' (legacy Mac OS X) */
{
FT_TRACE2(( " not a TTF font\n" ));
goto Bad_Format;
@ -1230,7 +1232,9 @@
/* <Input> */
/* size :: A handle to the target size object. */
/* */
/* only_height :: Only recompute ascender, descender, and height. */
/* only_height :: Only recompute ascender, descender, and height; */
/* this flag is used for variation fonts where */
/* `tt_size_reset' is used as an iterator function. */
/* */
FT_LOCAL_DEF( FT_Error )
tt_size_reset( TT_Size size,
@ -1277,7 +1281,11 @@
size->ttmetrics.valid = TRUE;
if ( only_height )
{
/* we must not recompute the scaling values here since */
/* `tt_size_reset' was already called (with only_height = 0) */
return FT_Err_Ok;
}
if ( face->header.Flags & 8 )
{

View File

@ -247,13 +247,13 @@
if ( pos2 > face->glyf_len )
{
/* We try to sanitize the last `loca' entry. */
if ( gindex == face->num_locations - 1 )
if ( gindex == face->num_locations - 2 )
{
FT_TRACE1(( "tt_face_get_location:"
" too large offset (0x%08lx) found for glyph index %ld,\n"
" too large size (%ld bytes) found for glyph index %ld,\n"
" "
" truncating at the end of `glyf' table (0x%08lx)\n",
pos2, gindex + 1, face->glyf_len ));
" truncating at the end of `glyf' table to %ld bytes\n",
pos2 - pos1, gindex, face->glyf_len - pos1 ));
pos2 = face->glyf_len;
}
else

View File

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

View File

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

View File

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

View File

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