| Index: third_party/freetype/src/truetype/ttinterp.c
|
| diff --git a/core/src/fxge/fx_freetype/fxft2.5.01/src/truetype/ttinterp.c b/third_party/freetype/src/truetype/ttinterp.c
|
| similarity index 96%
|
| rename from core/src/fxge/fx_freetype/fxft2.5.01/src/truetype/ttinterp.c
|
| rename to third_party/freetype/src/truetype/ttinterp.c
|
| index b7d2b62b3da728f1a8b154ae2a85bf3d3ab1a461..6bdffbca52762b0515f8ae9bf0adf8089cea965c 100644
|
| --- a/core/src/fxge/fx_freetype/fxft2.5.01/src/truetype/ttinterp.c
|
| +++ b/third_party/freetype/src/truetype/ttinterp.c
|
| @@ -4,7 +4,7 @@
|
| /* */
|
| /* TrueType bytecode interpreter (body). */
|
| /* */
|
| -/* Copyright 1996-2013 */
|
| +/* Copyright 1996-2014 */
|
| /* by David Turner, Robert Wilhelm, and Werner Lemberg. */
|
| /* */
|
| /* This file is part of the FreeType project, and may only be used, */
|
| @@ -20,12 +20,12 @@
|
| /* issues; many thanks! */
|
|
|
|
|
| -#include "../../include/ft2build.h"
|
| -#include "../../include/freetype/internal/ftdebug.h"
|
| -#include "../../include/freetype/internal/ftcalc.h"
|
| -#include "../../include/freetype/fttrigon.h"
|
| -#include "../../include/freetype/ftsystem.h"
|
| -#include "../../include/freetype/ftttdrv.h"
|
| +#include <ft2build.h>
|
| +#include FT_INTERNAL_DEBUG_H
|
| +#include FT_INTERNAL_CALC_H
|
| +#include FT_TRIGONOMETRY_H
|
| +#include FT_SYSTEM_H
|
| +#include FT_TRUETYPE_DRIVER_H
|
|
|
| #include "ttinterp.h"
|
| #include "tterrors.h"
|
| @@ -172,6 +172,9 @@
|
| #define CUR_Func_round( d, c ) \
|
| CUR.func_round( EXEC_ARG_ d, c )
|
|
|
| +#define CUR_Func_cur_ppem() \
|
| + CUR.func_cur_ppem( EXEC_ARG )
|
| +
|
| #define CUR_Func_read_cvt( index ) \
|
| CUR.func_read_cvt( EXEC_ARG_ index )
|
|
|
| @@ -184,12 +187,6 @@
|
| #define CURRENT_Ratio() \
|
| Current_Ratio( EXEC_ARG )
|
|
|
| -#define CURRENT_Ppem() \
|
| - Current_Ppem( EXEC_ARG )
|
| -
|
| -#define CUR_Ppem() \
|
| - Cur_PPEM( EXEC_ARG )
|
| -
|
| #define INS_SxVTL( a, b, c, d ) \
|
| Ins_SxVTL( EXEC_ARG_ a, b, c, d )
|
|
|
| @@ -282,10 +279,7 @@
|
| /* <InOut> */
|
| /* exec :: The target execution context. */
|
| /* */
|
| - /* <Return> */
|
| - /* FreeType error code. 0 means success. */
|
| - /* */
|
| - FT_LOCAL_DEF( FT_Error )
|
| + FT_LOCAL_DEF( void )
|
| TT_Goto_CodeRange( TT_ExecContext exec,
|
| FT_Int range,
|
| FT_Long IP )
|
| @@ -309,8 +303,6 @@
|
| exec->codeSize = coderange->size;
|
| exec->IP = IP;
|
| exec->curRange = range;
|
| -
|
| - return FT_Err_Ok;
|
| }
|
|
|
|
|
| @@ -332,10 +324,7 @@
|
| /* <InOut> */
|
| /* exec :: The target execution context. */
|
| /* */
|
| - /* <Return> */
|
| - /* FreeType error code. 0 means success. */
|
| - /* */
|
| - FT_LOCAL_DEF( FT_Error )
|
| + FT_LOCAL_DEF( void )
|
| TT_Set_CodeRange( TT_ExecContext exec,
|
| FT_Int range,
|
| void* base,
|
| @@ -345,8 +334,6 @@
|
|
|
| exec->codeRangeTable[range - 1].base = (FT_Byte*)base;
|
| exec->codeRangeTable[range - 1].size = length;
|
| -
|
| - return FT_Err_Ok;
|
| }
|
|
|
|
|
| @@ -364,13 +351,7 @@
|
| /* <InOut> */
|
| /* exec :: The target execution context. */
|
| /* */
|
| - /* <Return> */
|
| - /* FreeType error code. 0 means success. */
|
| - /* */
|
| - /* <Note> */
|
| - /* Does not set the Error variable. */
|
| - /* */
|
| - FT_LOCAL_DEF( FT_Error )
|
| + FT_LOCAL_DEF( void )
|
| TT_Clear_CodeRange( TT_ExecContext exec,
|
| FT_Int range )
|
| {
|
| @@ -378,8 +359,6 @@
|
|
|
| exec->codeRangeTable[range - 1].base = NULL;
|
| exec->codeRangeTable[range - 1].size = 0;
|
| -
|
| - return FT_Err_Ok;
|
| }
|
|
|
|
|
| @@ -403,13 +382,10 @@
|
| /* */
|
| /* memory :: A handle to the parent memory object. */
|
| /* */
|
| - /* <Return> */
|
| - /* FreeType error code. 0 means success. */
|
| - /* */
|
| /* <Note> */
|
| /* Only the glyph loader and debugger should call this function. */
|
| /* */
|
| - FT_LOCAL_DEF( FT_Error )
|
| + FT_LOCAL_DEF( void )
|
| TT_Done_Context( TT_ExecContext exec )
|
| {
|
| FT_Memory memory = exec->memory;
|
| @@ -436,8 +412,6 @@
|
| exec->face = NULL;
|
|
|
| FT_FREE( exec );
|
| -
|
| - return FT_Err_Ok;
|
| }
|
|
|
|
|
| @@ -664,13 +638,10 @@
|
| /* <InOut> */
|
| /* size :: A handle to the target size object. */
|
| /* */
|
| - /* <Return> */
|
| - /* FreeType error code. 0 means success. */
|
| - /* */
|
| /* <Note> */
|
| /* Only the glyph loader and debugger should call this function. */
|
| /* */
|
| - FT_LOCAL_DEF( FT_Error )
|
| + FT_LOCAL_DEF( void )
|
| TT_Save_Context( TT_ExecContext exec,
|
| TT_Size size )
|
| {
|
| @@ -688,8 +659,6 @@
|
|
|
| for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
|
| size->codeRangeTable[i] = exec->codeRangeTable[i];
|
| -
|
| - return FT_Err_Ok;
|
| }
|
|
|
|
|
| @@ -721,12 +690,7 @@
|
| TT_Run_Context( TT_ExecContext exec,
|
| FT_Bool debug )
|
| {
|
| - FT_Error error;
|
| -
|
| -
|
| - if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) )
|
| - != FT_Err_Ok )
|
| - return error;
|
| + TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 );
|
|
|
| exec->zp0 = exec->pts;
|
| exec->zp1 = exec->pts;
|
| @@ -796,16 +760,18 @@
|
| FT_EXPORT_DEF( TT_ExecContext )
|
| TT_New_Context( TT_Driver driver )
|
| {
|
| - TT_ExecContext exec;
|
| - FT_Memory memory;
|
| + FT_Memory memory;
|
|
|
|
|
| + if ( !driver )
|
| + goto Fail;
|
| +
|
| memory = driver->root.root.memory;
|
| - exec = driver->context;
|
|
|
| if ( !driver->context )
|
| {
|
| - FT_Error error;
|
| + FT_Error error;
|
| + TT_ExecContext exec;
|
|
|
|
|
| /* allocate object */
|
| @@ -1437,8 +1403,107 @@
|
|
|
| #undef PACK
|
|
|
| -#if 1
|
|
|
| +#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER
|
| +
|
| +#if defined( __arm__ ) && \
|
| + ( defined( __thumb2__ ) || !defined( __thumb__ ) )
|
| +
|
| +#define TT_MulFix14 TT_MulFix14_arm
|
| +
|
| + static FT_Int32
|
| + TT_MulFix14_arm( FT_Int32 a,
|
| + FT_Int b )
|
| + {
|
| + FT_Int32 t, t2;
|
| +
|
| +
|
| +#if defined( __CC_ARM ) || defined( __ARMCC__ )
|
| +
|
| + __asm
|
| + {
|
| + smull t2, t, b, a /* (lo=t2,hi=t) = a*b */
|
| + mov a, t, asr #31 /* a = (hi >> 31) */
|
| + add a, a, #0x2000 /* a += 0x2000 */
|
| + adds t2, t2, a /* t2 += a */
|
| + adc t, t, #0 /* t += carry */
|
| + mov a, t2, lsr #14 /* a = t2 >> 14 */
|
| + orr a, a, t, lsl #18 /* a |= t << 18 */
|
| + }
|
| +
|
| +#elif defined( __GNUC__ )
|
| +
|
| + __asm__ __volatile__ (
|
| + "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */
|
| + "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */
|
| +#if defined( __clang__ ) && defined( __thumb2__ )
|
| + "add.w %0, %0, #0x2000\n\t" /* %0 += 0x2000 */
|
| +#else
|
| + "add %0, %0, #0x2000\n\t" /* %0 += 0x2000 */
|
| +#endif
|
| + "adds %1, %1, %0\n\t" /* %1 += %0 */
|
| + "adc %2, %2, #0\n\t" /* %2 += carry */
|
| + "mov %0, %1, lsr #14\n\t" /* %0 = %1 >> 16 */
|
| + "orr %0, %0, %2, lsl #18\n\t" /* %0 |= %2 << 16 */
|
| + : "=r"(a), "=&r"(t2), "=&r"(t)
|
| + : "r"(a), "r"(b)
|
| + : "cc" );
|
| +
|
| +#endif
|
| +
|
| + return a;
|
| + }
|
| +
|
| +#endif /* __arm__ && ( __thumb2__ || !__thumb__ ) */
|
| +
|
| +#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
|
| +
|
| +
|
| +#if defined( __GNUC__ ) && \
|
| + ( defined( __i386__ ) || defined( __x86_64__ ) )
|
| +
|
| +#define TT_MulFix14 TT_MulFix14_long_long
|
| +
|
| + /* Temporarily disable the warning that C90 doesn't support `long long'. */
|
| +#if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406
|
| +#pragma GCC diagnostic push
|
| +#endif
|
| +#pragma GCC diagnostic ignored "-Wlong-long"
|
| +
|
| + /* This is declared `noinline' because inlining the function results */
|
| + /* in slower code. The `pure' attribute indicates that the result */
|
| + /* only depends on the parameters. */
|
| + static __attribute__(( noinline ))
|
| + __attribute__(( pure )) FT_Int32
|
| + TT_MulFix14_long_long( FT_Int32 a,
|
| + FT_Int b )
|
| + {
|
| +
|
| + long long ret = (long long)a * b;
|
| +
|
| + /* The following line assumes that right shifting of signed values */
|
| + /* will actually preserve the sign bit. The exact behaviour is */
|
| + /* undefined, but this is true on x86 and x86_64. */
|
| + long long tmp = ret >> 63;
|
| +
|
| +
|
| + ret += 0x2000 + tmp;
|
| +
|
| + return (FT_Int32)( ret >> 14 );
|
| + }
|
| +
|
| +#if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406
|
| +#pragma GCC diagnostic pop
|
| +#endif
|
| +
|
| +#endif /* __GNUC__ && ( __i386__ || __x86_64__ ) */
|
| +
|
| +
|
| +#ifndef TT_MulFix14
|
| +
|
| + /* Compute (a*b)/2^14 with maximum accuracy and rounding. */
|
| + /* This is optimized to be faster than calling FT_MulFix() */
|
| + /* for platforms where sizeof(int) == 2. */
|
| static FT_Int32
|
| TT_MulFix14( FT_Int32 a,
|
| FT_Int b )
|
| @@ -1470,37 +1535,50 @@
|
| return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid;
|
| }
|
|
|
| -#else
|
| +#endif /* !TT_MulFix14 */
|
|
|
| - /* compute (a*b)/2^14 with maximum accuracy and rounding */
|
| - static FT_Int32
|
| - TT_MulFix14( FT_Int32 a,
|
| - FT_Int b )
|
| - {
|
| - FT_Int32 m, s, hi;
|
| - FT_UInt32 l, lo;
|
|
|
| +#if defined( __GNUC__ ) && \
|
| + ( defined( __i386__ ) || \
|
| + defined( __x86_64__ ) || \
|
| + defined( __arm__ ) )
|
|
|
| - /* compute ax*bx as 64-bit value */
|
| - l = (FT_UInt32)( ( a & 0xFFFFU ) * b );
|
| - m = ( a >> 16 ) * b;
|
| +#define TT_DotFix14 TT_DotFix14_long_long
|
|
|
| - lo = l + ( (FT_UInt32)m << 16 );
|
| - hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l );
|
| +#if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406
|
| +#pragma GCC diagnostic push
|
| +#endif
|
| +#pragma GCC diagnostic ignored "-Wlong-long"
|
|
|
| - /* divide the result by 2^14 with rounding */
|
| - s = hi >> 31;
|
| - l = lo + (FT_UInt32)s;
|
| - hi += s + ( l < lo );
|
| - lo = l;
|
| + static __attribute__(( pure )) FT_Int32
|
| + TT_DotFix14_long_long( FT_Int32 ax,
|
| + FT_Int32 ay,
|
| + FT_Int bx,
|
| + FT_Int by )
|
| + {
|
| + /* Temporarily disable the warning that C90 doesn't support */
|
| + /* `long long'. */
|
|
|
| - l = lo + 0x2000U;
|
| - hi += l < lo;
|
| + long long temp1 = (long long)ax * bx;
|
| + long long temp2 = (long long)ay * by;
|
| +
|
| +
|
| + temp1 += temp2;
|
| + temp2 = temp1 >> 63;
|
| + temp1 += 0x2000 + temp2;
|
| +
|
| + return (FT_Int32)( temp1 >> 14 );
|
|
|
| - return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) );
|
| }
|
| +
|
| +#if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406
|
| +#pragma GCC diagnostic pop
|
| #endif
|
|
|
| +#endif /* __GNUC__ && (__arm__ || __i386__ || __x86_64__) */
|
| +
|
| +
|
| +#ifndef TT_DotFix14
|
|
|
| /* compute (ax*bx+ay*by)/2^14 with maximum accuracy and rounding */
|
| static FT_Int32
|
| @@ -1543,6 +1621,8 @@
|
| return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) );
|
| }
|
|
|
| +#endif /* TT_DotFix14 */
|
| +
|
|
|
| /*************************************************************************/
|
| /* */
|
| @@ -1595,9 +1675,16 @@
|
| }
|
|
|
|
|
| - static FT_Long
|
| + FT_CALLBACK_DEF( FT_Long )
|
| Current_Ppem( EXEC_OP )
|
| {
|
| + return CUR.tt_metrics.ppem;
|
| + }
|
| +
|
| +
|
| + FT_CALLBACK_DEF( FT_Long )
|
| + Current_Ppem_Stretched( EXEC_OP )
|
| + {
|
| return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() );
|
| }
|
|
|
| @@ -1936,7 +2023,7 @@
|
| if ( distance >= 0 )
|
| {
|
| val = distance + compensation;
|
| - if ( distance && val < 0 )
|
| + if ( val < 0 )
|
| val = 0;
|
| }
|
| else
|
| @@ -1976,10 +2063,8 @@
|
|
|
| if ( distance >= 0 )
|
| {
|
| - val = distance + compensation + 32;
|
| - if ( distance && val > 0 )
|
| - val &= ~63;
|
| - else
|
| + val = FT_PIX_ROUND( distance + compensation );
|
| + if ( val < 0 )
|
| val = 0;
|
| }
|
| else
|
| @@ -2021,14 +2106,14 @@
|
| if ( distance >= 0 )
|
| {
|
| val = FT_PIX_FLOOR( distance + compensation ) + 32;
|
| - if ( distance && val < 0 )
|
| - val = 0;
|
| + if ( val < 0 )
|
| + val = 32;
|
| }
|
| else
|
| {
|
| val = -( FT_PIX_FLOOR( compensation - distance ) + 32 );
|
| if ( val > 0 )
|
| - val = 0;
|
| + val = -32;
|
| }
|
|
|
| return val;
|
| @@ -2062,15 +2147,13 @@
|
|
|
| if ( distance >= 0 )
|
| {
|
| - val = distance + compensation;
|
| - if ( distance && val > 0 )
|
| - val &= ~63;
|
| - else
|
| + val = FT_PIX_FLOOR( distance + compensation );
|
| + if ( val < 0 )
|
| val = 0;
|
| }
|
| else
|
| {
|
| - val = -( ( compensation - distance ) & -64 );
|
| + val = -FT_PIX_FLOOR( compensation - distance );
|
| if ( val > 0 )
|
| val = 0;
|
| }
|
| @@ -2106,10 +2189,8 @@
|
|
|
| if ( distance >= 0 )
|
| {
|
| - val = distance + compensation + 63;
|
| - if ( distance && val > 0 )
|
| - val &= ~63;
|
| - else
|
| + val = FT_PIX_CEIL( distance + compensation );
|
| + if ( val < 0 )
|
| val = 0;
|
| }
|
| else
|
| @@ -2150,10 +2231,8 @@
|
|
|
| if ( distance >= 0 )
|
| {
|
| - val = distance + compensation + 16;
|
| - if ( distance && val > 0 )
|
| - val &= ~31;
|
| - else
|
| + val = FT_PAD_ROUND( distance + compensation, 32 );
|
| + if ( val < 0 )
|
| val = 0;
|
| }
|
| else
|
| @@ -2200,17 +2279,17 @@
|
| {
|
| val = ( distance - CUR.phase + CUR.threshold + compensation ) &
|
| -CUR.period;
|
| - if ( distance && val < 0 )
|
| - val = 0;
|
| val += CUR.phase;
|
| + if ( val < 0 )
|
| + val = CUR.phase;
|
| }
|
| else
|
| {
|
| val = -( ( CUR.threshold - CUR.phase - distance + compensation ) &
|
| -CUR.period );
|
| - if ( val > 0 )
|
| - val = 0;
|
| val -= CUR.phase;
|
| + if ( val > 0 )
|
| + val = -CUR.phase;
|
| }
|
|
|
| return val;
|
| @@ -2248,17 +2327,17 @@
|
| {
|
| val = ( ( distance - CUR.phase + CUR.threshold + compensation ) /
|
| CUR.period ) * CUR.period;
|
| - if ( distance && val < 0 )
|
| - val = 0;
|
| val += CUR.phase;
|
| + if ( val < 0 )
|
| + val = CUR.phase;
|
| }
|
| else
|
| {
|
| val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) /
|
| CUR.period ) * CUR.period );
|
| - if ( val > 0 )
|
| - val = 0;
|
| val -= CUR.phase;
|
| + if ( val > 0 )
|
| + val = -CUR.phase;
|
| }
|
|
|
| return val;
|
| @@ -2966,19 +3045,22 @@
|
| CUR.GS.auto_flip = FALSE;
|
|
|
|
|
| -#define DO_SDB \
|
| - CUR.GS.delta_base = (FT_Short)args[0];
|
| +#define DO_SDB \
|
| + CUR.GS.delta_base = (FT_UShort)args[0];
|
|
|
|
|
| -#define DO_SDS \
|
| - CUR.GS.delta_shift = (FT_Short)args[0];
|
| +#define DO_SDS \
|
| + if ( (FT_ULong)args[0] > 6UL ) \
|
| + CUR.error = FT_THROW( Bad_Argument ); \
|
| + else \
|
| + CUR.GS.delta_shift = (FT_UShort)args[0];
|
|
|
|
|
| #define DO_MD /* nothing */
|
|
|
|
|
| #define DO_MPPEM \
|
| - args[0] = CURRENT_Ppem();
|
| + args[0] = CUR_Func_cur_ppem();
|
|
|
|
|
| /* Note: The pointSize should be irrelevant in a given font program; */
|
| @@ -2991,7 +3073,7 @@
|
| #else
|
|
|
| #define DO_MPS \
|
| - args[0] = CURRENT_Ppem();
|
| + args[0] = CUR_Func_cur_ppem();
|
|
|
| #endif /* 0 */
|
|
|
| @@ -3037,42 +3119,42 @@
|
| }
|
|
|
|
|
| -#define DO_JROT \
|
| - if ( args[1] != 0 ) \
|
| - { \
|
| - if ( args[0] == 0 && CUR.args == 0 ) \
|
| - CUR.error = FT_THROW( Bad_Argument ); \
|
| - CUR.IP += args[0]; \
|
| - if ( CUR.IP < 0 || \
|
| - ( CUR.callTop > 0 && \
|
| - CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \
|
| - CUR.error = FT_THROW( Bad_Argument ); \
|
| - CUR.step_ins = FALSE; \
|
| +#define DO_JROT \
|
| + if ( args[1] != 0 ) \
|
| + { \
|
| + if ( args[0] == 0 && CUR.args == 0 ) \
|
| + CUR.error = FT_THROW( Bad_Argument ); \
|
| + CUR.IP += args[0]; \
|
| + if ( CUR.IP < 0 || \
|
| + ( CUR.callTop > 0 && \
|
| + CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) ) \
|
| + CUR.error = FT_THROW( Bad_Argument ); \
|
| + CUR.step_ins = FALSE; \
|
| }
|
|
|
|
|
| -#define DO_JMPR \
|
| - if ( args[0] == 0 && CUR.args == 0 ) \
|
| - CUR.error = FT_THROW( Bad_Argument ); \
|
| - CUR.IP += args[0]; \
|
| - if ( CUR.IP < 0 || \
|
| - ( CUR.callTop > 0 && \
|
| - CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \
|
| - CUR.error = FT_THROW( Bad_Argument ); \
|
| +#define DO_JMPR \
|
| + if ( args[0] == 0 && CUR.args == 0 ) \
|
| + CUR.error = FT_THROW( Bad_Argument ); \
|
| + CUR.IP += args[0]; \
|
| + if ( CUR.IP < 0 || \
|
| + ( CUR.callTop > 0 && \
|
| + CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) ) \
|
| + CUR.error = FT_THROW( Bad_Argument ); \
|
| CUR.step_ins = FALSE;
|
|
|
|
|
| -#define DO_JROF \
|
| - if ( args[1] == 0 ) \
|
| - { \
|
| - if ( args[0] == 0 && CUR.args == 0 ) \
|
| - CUR.error = FT_THROW( Bad_Argument ); \
|
| - CUR.IP += args[0]; \
|
| - if ( CUR.IP < 0 || \
|
| - ( CUR.callTop > 0 && \
|
| - CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \
|
| - CUR.error = FT_THROW( Bad_Argument ); \
|
| - CUR.step_ins = FALSE; \
|
| +#define DO_JROF \
|
| + if ( args[1] == 0 ) \
|
| + { \
|
| + if ( args[0] == 0 && CUR.args == 0 ) \
|
| + CUR.error = FT_THROW( Bad_Argument ); \
|
| + CUR.IP += args[0]; \
|
| + if ( CUR.IP < 0 || \
|
| + ( CUR.callTop > 0 && \
|
| + CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) ) \
|
| + CUR.error = FT_THROW( Bad_Argument ); \
|
| + CUR.step_ins = FALSE; \
|
| }
|
|
|
|
|
| @@ -4788,7 +4870,7 @@
|
| if ( pRec->Cur_Count > 0 )
|
| {
|
| CUR.callTop++;
|
| - CUR.IP = pRec->Cur_Restart;
|
| + CUR.IP = pRec->Def->start;
|
| }
|
| else
|
| /* Loop through the current function */
|
| @@ -4878,8 +4960,7 @@
|
| pCrec->Caller_Range = CUR.curRange;
|
| pCrec->Caller_IP = CUR.IP + 1;
|
| pCrec->Cur_Count = 1;
|
| - pCrec->Cur_Restart = def->start;
|
| - pCrec->Cur_End = def->end;
|
| + pCrec->Def = def;
|
|
|
| CUR.callTop++;
|
|
|
| @@ -4967,8 +5048,7 @@
|
| pCrec->Caller_Range = CUR.curRange;
|
| pCrec->Caller_IP = CUR.IP + 1;
|
| pCrec->Cur_Count = (FT_Int)args[0];
|
| - pCrec->Cur_Restart = def->start;
|
| - pCrec->Cur_End = def->end;
|
| + pCrec->Def = def;
|
|
|
| CUR.callTop++;
|
|
|
| @@ -5829,7 +5909,6 @@
|
| }
|
| #endif
|
|
|
| - if (CUR.zp2.cur == NULL) return; /* Security fix: Google Chris6 ufuzz109.pdf page #1 */
|
| if ( CUR.GS.freeVector.x != 0 )
|
| {
|
| CUR.zp2.cur[point].x += dx;
|
| @@ -5995,11 +6074,8 @@
|
| /* use end of last contour. */
|
| if ( CUR.GS.gep2 == 0 )
|
| limit = (FT_UShort)CUR.zp2.n_points;
|
| - else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 ) {
|
| + else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 )
|
| limit = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] + 1 );
|
| - if (limit >= CUR.zp2.n_points) /* XYQ 2010-10-01: security fix: validate last point index */
|
| - limit = CUR.zp2.n_points - 1;
|
| - }
|
| else
|
| limit = 0;
|
|
|
| @@ -6566,9 +6642,9 @@
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
|
| - /* Security fix: Google 07_oobread4.pdf page #1, cvtEntry > CUR.cvtSize + 1 will cause array index oob. */
|
| +
|
| if ( BOUNDS( point, CUR.zp1.n_points ) ||
|
| - BOUNDS( cvtEntry, CUR.cvtSize + 1 ) ||
|
| + BOUNDSL( cvtEntry, CUR.cvtSize + 1 ) ||
|
| BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
|
| {
|
| if ( CUR.pedantic_hinting )
|
| @@ -7061,7 +7137,7 @@
|
| org_dist = CUR_fast_dualproj( &vec );
|
| }
|
|
|
| - cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base );
|
| + cur_dist = CUR_Func_project( &CUR.zp2.cur[point], cur_base );
|
|
|
| if ( org_dist )
|
| {
|
| @@ -7072,14 +7148,20 @@
|
| /* This is the same as what MS does for the invalid case: */
|
| /* */
|
| /* delta = (Original_Pt - Original_RP1) - */
|
| - /* (Current_Pt - Current_RP1) */
|
| + /* (Current_Pt - Current_RP1) ; */
|
| /* */
|
| /* In FreeType speak: */
|
| /* */
|
| - /* new_dist = cur_dist - */
|
| - /* org_dist - cur_dist; */
|
| + /* delta = org_dist - cur_dist . */
|
| + /* */
|
| + /* We move `point' by `new_dist - cur_dist' after leaving */
|
| + /* this block, thus we have */
|
| + /* */
|
| + /* new_dist - cur_dist = delta , */
|
| + /* new_dist - cur_dist = org_dist - cur_dist , */
|
| + /* new_dist = org_dist . */
|
|
|
| - new_dist = -org_dist;
|
| + new_dist = org_dist;
|
| }
|
| }
|
| else
|
| @@ -7376,9 +7458,9 @@
|
| static void
|
| Ins_DELTAP( INS_ARG )
|
| {
|
| - FT_ULong k, nump;
|
| + FT_ULong nump, k;
|
| FT_UShort A;
|
| - FT_ULong C;
|
| + FT_ULong C, P;
|
| FT_Long B;
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| FT_UShort B1, B2;
|
| @@ -7412,6 +7494,7 @@
|
| }
|
| #endif
|
|
|
| + P = (FT_ULong)CUR_Func_cur_ppem();
|
| nump = (FT_ULong)args[0]; /* some points theoretically may occur more
|
| than once, thus UShort isn't enough */
|
|
|
| @@ -7456,12 +7539,12 @@
|
|
|
| C += CUR.GS.delta_base;
|
|
|
| - if ( CURRENT_Ppem() == (FT_Long)C )
|
| + if ( P == C )
|
| {
|
| B = ( (FT_ULong)B & 0xF ) - 8;
|
| if ( B >= 0 )
|
| B++;
|
| - B = B * 64 / ( 1L << CUR.GS.delta_shift );
|
| + B *= 1L << ( 6 - CUR.GS.delta_shift );
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
|
|
| @@ -7470,42 +7553,33 @@
|
| /*
|
| * Allow delta move if
|
| *
|
| - * - not using ignore_x_mode rendering
|
| - * - glyph is specifically set to allow it
|
| - * - glyph is composite and freedom vector is not subpixel
|
| - * vector
|
| + * - not using ignore_x_mode rendering,
|
| + * - glyph is specifically set to allow it, or
|
| + * - glyph is composite and freedom vector is not in subpixel
|
| + * direction.
|
| */
|
| if ( !CUR.ignore_x_mode ||
|
| ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
|
| ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) )
|
| CUR_Func_move( &CUR.zp0, A, B );
|
|
|
| - /* Otherwise apply subpixel hinting and */
|
| - /* compatibility mode rules */
|
| - else if ( CUR.ignore_x_mode )
|
| + /* Otherwise, apply subpixel hinting and compatibility mode */
|
| + /* rules, always skipping deltas in subpixel direction. */
|
| + else if ( CUR.ignore_x_mode && CUR.GS.freeVector.y != 0 )
|
| {
|
| - if ( CUR.GS.freeVector.y != 0 )
|
| - B1 = CUR.zp0.cur[A].y;
|
| - else
|
| - B1 = CUR.zp0.cur[A].x;
|
| + /* save the y value of the point now; compare after move */
|
| + B1 = (FT_UShort)CUR.zp0.cur[A].y;
|
|
|
| -#if 0
|
| - /* Standard Subpixel Hinting: Allow y move. */
|
| - /* This messes up dejavu and may not be needed... */
|
| - if ( !CUR.face->sph_compatibility_mode &&
|
| - CUR.GS.freeVector.y != 0 )
|
| + /* Standard subpixel hinting: Allow y move for y-touched */
|
| + /* points. This messes up DejaVu ... */
|
| + if ( !CUR.face->sph_compatibility_mode &&
|
| + ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
|
| CUR_Func_move( &CUR.zp0, A, B );
|
| - else
|
| -#endif /* 0 */
|
|
|
| - /* Compatibility Mode: Allow x or y move if point touched in */
|
| - /* Y direction. */
|
| - if ( CUR.face->sph_compatibility_mode &&
|
| - !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
|
| + /* compatibility mode */
|
| + else if ( CUR.face->sph_compatibility_mode &&
|
| + !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
|
| {
|
| - /* save the y value of the point now; compare after move */
|
| - B1 = CUR.zp0.cur[A].y;
|
| -
|
| if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
|
| B = FT_PIX_ROUND( B1 + B ) - B1;
|
|
|
| @@ -7516,7 +7590,7 @@
|
| CUR_Func_move( &CUR.zp0, A, B );
|
| }
|
|
|
| - B2 = CUR.zp0.cur[A].y;
|
| + B2 = (FT_UShort)CUR.zp0.cur[A].y;
|
|
|
| /* Reverse this move if it results in a disallowed move */
|
| if ( CUR.GS.freeVector.y != 0 &&
|
| @@ -7556,7 +7630,7 @@
|
| Ins_DELTAC( INS_ARG )
|
| {
|
| FT_ULong nump, k;
|
| - FT_ULong A, C;
|
| + FT_ULong A, C, P;
|
| FT_Long B;
|
|
|
|
|
| @@ -7580,6 +7654,7 @@
|
| }
|
| #endif
|
|
|
| + P = (FT_ULong)CUR_Func_cur_ppem();
|
| nump = (FT_ULong)args[0];
|
|
|
| for ( k = 1; k <= nump; k++ )
|
| @@ -7625,12 +7700,12 @@
|
|
|
| C += CUR.GS.delta_base;
|
|
|
| - if ( CURRENT_Ppem() == (FT_Long)C )
|
| + if ( P == C )
|
| {
|
| B = ( (FT_ULong)B & 0xF ) - 8;
|
| if ( B >= 0 )
|
| B++;
|
| - B = B * 64 / ( 1L << CUR.GS.delta_shift );
|
| + B *= 1L << ( 6 - CUR.GS.delta_shift );
|
|
|
| CUR_Func_move_cvt( A, B );
|
| }
|
| @@ -7712,26 +7787,16 @@
|
| CUR.ignore_x_mode &&
|
| CUR.rasterizer_version >= TT_INTERPRETER_VERSION_35 )
|
| {
|
| - /********************************/
|
| - /* HINTING FOR GRAYSCALE */
|
| - /* Selector Bit: 5 */
|
| - /* Return Bit(s): 12 */
|
| - /* */
|
| - if ( ( args[0] & 32 ) != 0 && CUR.grayscale_hinting )
|
| - K |= 1 << 12;
|
| -
|
| - /********************************/
|
| - /* HINTING FOR SUBPIXEL */
|
| - /* Selector Bit: 6 */
|
| - /* Return Bit(s): 13 */
|
| - /* */
|
| - if ( ( args[0] & 64 ) != 0 &&
|
| - CUR.subpixel_hinting &&
|
| - CUR.rasterizer_version >= 37 )
|
| - {
|
| - K |= 1 << 13;
|
|
|
| - /* the stuff below is irrelevant if subpixel_hinting is not set */
|
| + if ( CUR.rasterizer_version >= 37 )
|
| + {
|
| + /********************************/
|
| + /* HINTING FOR SUBPIXEL */
|
| + /* Selector Bit: 6 */
|
| + /* Return Bit(s): 13 */
|
| + /* */
|
| + if ( ( args[0] & 64 ) != 0 && CUR.subpixel )
|
| + K |= 1 << 13;
|
|
|
| /********************************/
|
| /* COMPATIBLE WIDTHS ENABLED */
|
| @@ -7807,8 +7872,7 @@
|
| call->Caller_Range = CUR.curRange;
|
| call->Caller_IP = CUR.IP + 1;
|
| call->Cur_Count = 1;
|
| - call->Cur_Restart = def->start;
|
| - call->Cur_End = def->end;
|
| + call->Def = def;
|
|
|
| INS_Goto_CodeRange( def->range, def->start );
|
|
|
| @@ -8162,6 +8226,9 @@
|
|
|
|
|
| #ifdef TT_CONFIG_OPTION_STATIC_RASTER
|
| + if ( !exc )
|
| + return FT_THROW( Invalid_Argument );
|
| +
|
| cur = *exc;
|
| #endif
|
|
|
| @@ -8169,11 +8236,12 @@
|
| CUR.iup_called = FALSE;
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| - /* set CVT functions */
|
| + /* set PPEM and CVT functions */
|
| CUR.tt_metrics.ratio = 0;
|
| if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem )
|
| {
|
| /* non-square pixels, use the stretched routines */
|
| + CUR.func_cur_ppem = Current_Ppem_Stretched;
|
| CUR.func_read_cvt = Read_CVT_Stretched;
|
| CUR.func_write_cvt = Write_CVT_Stretched;
|
| CUR.func_move_cvt = Move_CVT_Stretched;
|
| @@ -8181,6 +8249,7 @@
|
| else
|
| {
|
| /* square pixels, use normal routines */
|
| + CUR.func_cur_ppem = Current_Ppem;
|
| CUR.func_read_cvt = Read_CVT;
|
| CUR.func_write_cvt = Write_CVT;
|
| CUR.func_move_cvt = Move_CVT;
|
| @@ -8864,8 +8933,7 @@
|
| callrec->Caller_Range = CUR.curRange;
|
| callrec->Caller_IP = CUR.IP + 1;
|
| callrec->Cur_Count = 1;
|
| - callrec->Cur_Restart = def->start;
|
| - callrec->Cur_End = def->end;
|
| + callrec->Def = def;
|
|
|
| if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE )
|
| goto LErrorLabel_;
|
| @@ -8936,10 +9004,13 @@
|
| /* If any errors have occurred, function tables may be broken. */
|
| /* Force a re-execution of `prep' and `fpgm' tables if no */
|
| /* bytecode debugger is run. */
|
| - if ( CUR.error && !CUR.instruction_trap )
|
| + if ( CUR.error
|
| + && !CUR.instruction_trap
|
| + && CUR.curRange == tt_coderange_glyph )
|
| {
|
| FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error ));
|
| - exc->size->cvt_ready = FALSE;
|
| + exc->size->bytecode_ready = -1;
|
| + exc->size->cvt_ready = -1;
|
| }
|
|
|
| return CUR.error;
|
|
|