[ftraster] Fix rounding issue causing visual artifacts.

Problem reported by jola <hans-jochen.lau@lhsystems.com>; 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'.
This commit is contained in:
Werner Lemberg 2012-06-06 13:24:04 +02:00
parent 5715ff4606
commit 495bd3cc4f
3 changed files with 39 additions and 5 deletions

View File

@ -1,3 +1,15 @@
2012-06-06 Werner Lemberg <wl@gnu.org>
[ftraster] Fix rounding issue causing visual artifacts.
Problem reported by jola <hans-jochen.lau@lhsystems.com>; 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 <apodtele@gmail.com>
* src/base/ftoutln.c (FT_Outline_Get_Orientation): Simplify.

View File

@ -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__ */

View File

@ -60,7 +60,7 @@
#include <ft2build.h>
#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;
}