From 495bd3cc4f54f5f4604709391a716fcd0c033277 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Wed, 6 Jun 2012 13:24:04 +0200 Subject: [PATCH] [ftraster] Fix rounding issue causing visual artifacts. Problem reported by jola ; see http://lists.gnu.org/archive/html/freetype-devel/2012-05/msg00036.html * src/raster/ftraster.c (SMulDiv_No_Round): New macro. (Line_Up): Use it. * src/raster/ftmisc.h (FT_MulDiv_No_Round): Copied from `ftcalc.c'. --- ChangeLog | 12 ++++++++++++ src/raster/ftmisc.h | 21 +++++++++++++++++++++ src/raster/ftraster.c | 11 ++++++----- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index d2f646585..cbf96797e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2012-06-06 Werner Lemberg + + [ftraster] Fix rounding issue causing visual artifacts. + + Problem reported by jola ; see + + http://lists.gnu.org/archive/html/freetype-devel/2012-05/msg00036.html + + * src/raster/ftraster.c (SMulDiv_No_Round): New macro. + (Line_Up): Use it. + * src/raster/ftmisc.h (FT_MulDiv_No_Round): Copied from `ftcalc.c'. + 2012-05-28 Alexei Podtelezhnikov * src/base/ftoutln.c (FT_Outline_Get_Orientation): Simplify. diff --git a/src/raster/ftmisc.h b/src/raster/ftmisc.h index 7773924fe..703155a42 100644 --- a/src/raster/ftmisc.h +++ b/src/raster/ftmisc.h @@ -115,6 +115,27 @@ return ( s > 0 ) ? d : -d; } + + static 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; + } + #endif /* __FTMISC_H__ */ diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c index f85845ec6..7d5bcaef5 100644 --- a/src/raster/ftraster.c +++ b/src/raster/ftraster.c @@ -60,7 +60,7 @@ #include #include "ftraster.h" -#include FT_INTERNAL_CALC_H /* for FT_MulDiv only */ +#include FT_INTERNAL_CALC_H /* for FT_MulDiv and FT_MulDiv_No_Round */ #include "rastpic.h" @@ -255,7 +255,8 @@ /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */ /* for clipping computations. It simply uses the FT_MulDiv() function */ /* defined in `ftcalc.h'. */ -#define SMulDiv FT_MulDiv +#define SMulDiv FT_MulDiv +#define SMulDiv_No_Round FT_MulDiv_No_Round /* The rasterizer is a very general purpose component; please leave */ /* the following redefinitions there (you never know your target */ @@ -1150,14 +1151,14 @@ if ( Dx > 0 ) { - Ix = SMulDiv( ras.precision, Dx, Dy); + Ix = SMulDiv_No_Round( ras.precision, Dx, Dy ); Rx = ( ras.precision * Dx ) % Dy; Dx = 1; } else { - Ix = SMulDiv( ras.precision, -Dx, Dy) * -1; - Rx = ( ras.precision * -Dx ) % Dy; + Ix = -SMulDiv_No_Round( ras.precision, -Dx, Dy ); + Rx = ( ras.precision * -Dx ) % Dy; Dx = -1; }