diff options
author | Alexei Podtelezhnikov <apodtele@gmail.com> | 2013-01-12 23:05:55 -0500 |
---|---|---|
committer | Alexei Podtelezhnikov <apodtele@gmail.com> | 2013-01-12 23:05:55 -0500 |
commit | 0e0fdc5dc89e5079898c5da67b56f994c439fee1 (patch) | |
tree | f7cb5875551458ec61b59ff509cd1a18c6061977 | |
parent | 081aba390a648fc10c7ae5e169861f2e9aae2aea (diff) | |
download | freetype2-0e0fdc5dc89e5079898c5da67b56f994c439fee1.tar.gz |
[truetype] Improve accuracy of normalization of short vectors.
Unit vector components are stored as 2.14 fixed-point numbers. In
order to calculate all 14 bits accurately, a short vector to be
normalized has to be upscaled to at least 14 bits before its length
is calculated. This has been safe since accurate CORDIC algorithms
were adopted.
* src/truetype/ttinterp.c (Normalize): Scale short vectors by 0x4000.
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | src/truetype/ttinterp.c | 10 |
2 files changed, 16 insertions, 6 deletions
@@ -1,5 +1,17 @@ 2013-01-12 Alexei Podtelezhnikov <apodtele@gmail.com> + [truetype] Improve accuracy of normalization of short vectors. + + Unit vector components are stored as 2.14 fixed-point numbers. In + order to calculate all 14 bits accurately, a short vector to be + normalized has to be upscaled to at least 14 bits before its length + is calculated. This has been safe since accurate CORDIC algorithms + were adopted. + + * src/truetype/ttinterp.c (Normalize): Scale short vectors by 0x4000. + +2013-01-12 Alexei Podtelezhnikov <apodtele@gmail.com> + [truetype] Kill very old vector normalization hacks. Back in the days, vector length calculations were not very accurate diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index f86232080..1cbb351ad 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -2635,8 +2635,6 @@ /* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */ /* R is undefined. */ /* */ - - static FT_Bool Normalize( EXEC_OP_ FT_F26Dot6 Vx, FT_F26Dot6 Vy, @@ -2647,17 +2645,17 @@ FT_UNUSED_EXEC; - if ( FT_ABS( Vx ) < 0x10000L && FT_ABS( Vy ) < 0x10000L ) + if ( FT_ABS( Vx ) < 0x4000L && FT_ABS( Vy ) < 0x4000L ) { - Vx *= 0x100; - Vy *= 0x100; - if ( Vx == 0 && Vy == 0 ) { /* XXX: UNDOCUMENTED! It seems that it is possible to try */ /* to normalize the vector (0,0). Return immediately. */ return SUCCESS; } + + Vx *= 0x4000; + Vy *= 0x4000; } W = TT_VecLen( Vx, Vy ); |