freetype-devel
[Top][All Lists]

## Re: [ft-devel] "Inside the fastest font renderer in the world" - BUG FIX

 From: Raph Levien Subject: Re: [ft-devel] "Inside the fastest font renderer in the world" - BUG FIX Date: Sun, 21 Aug 2016 07:58:14 -0700

Thanks for the tip! I haven't tested font-rs against a large corpus yet, so wouldn't be surprised if there were bugs. This looks worth tracking down.

Also, Nigel Tao has done a port to Go and reports a significant speedup from using fixed point (https://github.com/google/font-rs/issues/10). Might be worth investigating.

(Right now I'm tight on time so haven't been able to investigate deeply myself)

Raph

On Sun, Aug 21, 2016 at 7:06 AM, Graham Asher wrote:
I have found the bug causing the crash in my C version of the new floating-point rasterizer.

It was possible for the accumulation array to be written using an illegal index of -1. The cause was that when the DrawLine code steps through the y values - the raster lines - it increments the x value by dxdy, which is (dx / dy). That float value will inevitably sometimes be imprecise, causing the x value to become just less than 1. For example, if a line is drawn from (0.484375,0.34375) to (0,0.771965563), dxdy ought to be -1.131147585..., but is rounded to the float value -1.13114762. In the first and only raster line, dy is 0.428215563, so x = 0.48375 and xnext (the next value of x) is x + dy * dxdy = -2.98023224e-08 - NOT zero, as it should be, but a small way below zero: so when the array index x01 is set to the next integer below nextx it becomes -1.

Therefore the statement

float x0floor = (float)floor(x0);

becomes

float x0floor = x0 <= 0.0f ? 0.0f : (float)floor(x0);

with an explanatory comment. It goes without saying that changing from float to double would not fix the problem, only make it somewhat rarer.

This was quite hard to debug because a write to the four bytes just before the start of a heap block does not cause an immediate crash. The crash happens when the block is deallocated. I added explicit array checking code, turned off optimisation in the release build of the CartoType demo (the debug build was too slow), ran it in the VS2015 debugger and caught the bug on about the thirty-one-millionth array access.

Raph, you might like to check whether your Rust code has the same problem. I suspect that it does, because the lines (lines 69-70 in raster.rs)

let x0floor = x0.floor();
let x0i = x0floor as i32;

don't appear to prevent x0floor or x0i from being negative.

- Graham

On 19/08/2016 14:33, Graham Asher wrote:
Right now I think the supposed bug doesn't exist, but was caused by forcibly closing a debug session in Visual Studio 2015.

On 19/08/2016 14:02, Graham Asher wrote:
I've fixed the clipping and winding rule bugs, and it now works well with CartoType map rendering, and seems fast although I have not benchmarked it against the older renderer. However, one note of caution: I think there is still a bug somewhere, probably a write beyond the end of an array; no doubt that is my fault. I will try to reproduce and fix it.

I have uploaded the new version.

On 19/08/2016 11:16, Graham Asher wrote:

which is going to be its home for now.

More news when I have done some more testing.

_______________________________________________
Freetype-devel mailing list