* src/base/ftcalc.c (FT_MulDiv_No_Round): New function (32 and

64 bit version).
* include/freetype/internal/ftcalc.h: Updated.

* src/truetype/ttinterp.c (TT_MULDIV_NO_ROUND): New macro.
(TT_INT64): Removed.
(DO_DIV): Use TT_MULDIV_NO_ROUND.

* src/pfr/pfrdrivr.c (pfr_get_metrics): Directly use
metrics->x_scale and metrics->y_scale.
This commit is contained in:
Werner Lemberg 2003-11-25 18:15:56 +00:00
parent 4ff243d90a
commit 9f051a7fa4
5 changed files with 119 additions and 24 deletions

View File

@ -1,3 +1,16 @@
2003-11-23 Werner Lemberg <wl@gnu.org>
* src/base/ftcalc.c (FT_MulDiv_No_Round): New function (32 and
64 bit version).
* include/freetype/internal/ftcalc.h: Updated.
* src/truetype/ttinterp.c (TT_MULDIV_NO_ROUND): New macro.
(TT_INT64): Removed.
(DO_DIV): Use TT_MULDIV_NO_ROUND.
* src/pfr/pfrdrivr.c (pfr_get_metrics): Directly use
metrics->x_scale and metrics->y_scale.
2003-11-22 Rogier van Dalen <R.C.van.Dalen@umail.leidenuniv.nl> 2003-11-22 Rogier van Dalen <R.C.van.Dalen@umail.leidenuniv.nl>
* src/truetype/ttinterp.c (CUR_Func_move_orig): New macro. * src/truetype/ttinterp.c (CUR_Func_move_orig): New macro.

View File

@ -4,7 +4,7 @@
/* */ /* */
/* Arithmetic computations (specification). */ /* Arithmetic computations (specification). */
/* */ /* */
/* Copyright 1996-2001, 2002 by */ /* Copyright 1996-2001, 2002, 2003 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -27,7 +27,8 @@
FT_BEGIN_HEADER FT_BEGIN_HEADER
FT_EXPORT( FT_Int32 ) FT_SqrtFixed( FT_Int32 x ); FT_EXPORT( FT_Int32 )
FT_SqrtFixed( FT_Int32 x );
#define SQRT_32( x ) FT_Sqrt32( x ) #define SQRT_32( x ) FT_Sqrt32( x )
@ -59,6 +60,35 @@ FT_BEGIN_HEADER
/*************************************************************************/ /*************************************************************************/
/*************************************************************************/
/* */
/* <Function> */
/* FT_MulDiv_No_Round */
/* */
/* <Description> */
/* A very simple function used to perform the computation `(a*b)/c' */
/* (without rounding) with maximal accuracy (it uses a 64-bit */
/* intermediate integer whenever necessary). */
/* */
/* This function isn't necessarily as fast as some processor specific */
/* operations, but is at least completely portable. */
/* */
/* <Input> */
/* a :: The first multiplier. */
/* b :: The second multiplier. */
/* c :: The divisor. */
/* */
/* <Return> */
/* The result of `(a*b)/c'. This function never traps when trying to */
/* divide by zero; it simply returns `MaxInt' or `MinInt' depending */
/* on the signs of `a' and `b'. */
/* */
FT_BASE( FT_Long )
FT_MulDiv_No_Round( FT_Long a,
FT_Long b,
FT_Long c );
#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) #define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 )
#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) #define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 )
#define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) #define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 )

View File

@ -155,6 +155,29 @@
} }
/* documentation is in ftcalc.h */
FT_BASE_DEF( FT_Long )
FT_MulDiv_No_Round( FT_Long a,
FT_Long b,
FT_Long c )
{
FT_Int s;
FT_Long d;
s = 1;
if ( a < 0 ) { a = -a; s = -1; }
if ( b < 0 ) { b = -b; s = -s; }
if ( c < 0 ) { c = -c; s = -s; }
d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c
: 0x7FFFFFFFL );
return ( s > 0 ) ? d : -d;
}
/* documentation is in freetype.h */ /* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Long ) FT_EXPORT_DEF( FT_Long )
@ -303,9 +326,8 @@
s ^= c; c = ABS( c ); s ^= c; c = ABS( c );
if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 ) if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 )
{
a = ( a * b + ( c >> 1 ) ) / c; a = ( a * b + ( c >> 1 ) ) / c;
}
else if ( c > 0 ) else if ( c > 0 )
{ {
FT_Int64 temp, temp2; FT_Int64 temp, temp2;
@ -325,6 +347,39 @@
} }
FT_BASE_DEF( FT_Long )
FT_MulDiv_No_Round( FT_Long a,
FT_Long b,
FT_Long c )
{
long s;
if ( a == 0 || b == c )
return a;
s = a; a = ABS( a );
s ^= b; b = ABS( b );
s ^= c; c = ABS( c );
if ( a <= 46340L && b <= 46340L && c > 0 )
a = a * b / c;
else if ( c > 0 )
{
FT_Int64 temp;
ft_multo64( a, b, &temp );
a = ft_div64by32( temp.hi, temp.lo, c );
}
else
a = 0x7FFFFFFFL;
return ( s < 0 ? -a : a );
}
/* documentation is in freetype.h */ /* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Long ) FT_EXPORT_DEF( FT_Long )

View File

@ -62,12 +62,12 @@
static FT_Error static FT_Error
pfr_get_advance( PFR_Face face, pfr_get_advance( PFR_Face face,
FT_UInt gindex, FT_UInt gindex,
FT_Pos *aadvance ) FT_Pos *anadvance )
{ {
FT_Error error = PFR_Err_Bad_Argument; FT_Error error = PFR_Err_Bad_Argument;
*aadvance = 0; *anadvance = 0;
if ( face ) if ( face )
{ {
PFR_PhyFont phys = &face->phy_font; PFR_PhyFont phys = &face->phy_font;
@ -75,7 +75,7 @@
if ( gindex < phys->num_chars ) if ( gindex < phys->num_chars )
{ {
*aadvance = phys->chars[gindex].advance; *anadvance = phys->chars[gindex].advance;
error = 0; error = 0;
} }
} }
@ -86,7 +86,7 @@
static FT_Error static FT_Error
pfr_get_metrics( PFR_Face face, pfr_get_metrics( PFR_Face face,
FT_UInt *aoutline_resolution, FT_UInt *anoutline_resolution,
FT_UInt *ametrics_resolution, FT_UInt *ametrics_resolution,
FT_Fixed *ametrics_x_scale, FT_Fixed *ametrics_x_scale,
FT_Fixed *ametrics_y_scale ) FT_Fixed *ametrics_y_scale )
@ -96,8 +96,8 @@
FT_Size size = face->root.size; FT_Size size = face->root.size;
if ( aoutline_resolution ) if ( anoutline_resolution )
*aoutline_resolution = phys->outline_resolution; *anoutline_resolution = phys->outline_resolution;
if ( ametrics_resolution ) if ( ametrics_resolution )
*ametrics_resolution = phys->metrics_resolution; *ametrics_resolution = phys->metrics_resolution;
@ -107,11 +107,8 @@
if ( size ) if ( size )
{ {
x_scale = FT_DivFix( size->metrics.x_ppem << 6, x_scale = size->metrics.x_scale;
phys->metrics_resolution ); y_scale = size->metrics.y_scale;
y_scale = FT_DivFix( size->metrics.y_ppem << 6,
phys->metrics_resolution );
} }
if ( ametrics_x_scale ) if ( ametrics_x_scale )

View File

@ -30,9 +30,10 @@
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
#define TT_MULFIX FT_MulFix #define TT_MULFIX FT_MulFix
#define TT_MULDIV FT_MulDiv #define TT_MULDIV FT_MulDiv
#define TT_INT64 FT_Int64 #define TT_MULDIV_NO_ROUND FT_MulDiv_No_Round
/*************************************************************************/ /*************************************************************************/
/* */ /* */
@ -2973,12 +2974,11 @@
args[0] -= args[1]; args[0] -= args[1];
#define DO_DIV \ #define DO_DIV \
if ( args[1] == 0 ) \ if ( args[1] == 0 ) \
CUR.error = TT_Err_Divide_By_Zero; \ CUR.error = TT_Err_Divide_By_Zero; \
else \ else \
/* Should args[0] be cast to FT_Int64 first? */ \ args[0] = TT_MULDIV_NO_ROUND( args[0], 64L, args[1] );
args[0] = ( args[0] * 64L ) / args[1];
#define DO_MUL \ #define DO_MUL \