[haiku-development] Re: Text rendering

Claudio Leite wrote (2007-06-12, 17:29:08 [+0200]):
> Hi,
>  I'm interested in implementing subpixel text rendering using FreeType's
> new-ish LCD filter. I'm poking around, trying to discover where FreeType
> is called within Haiku--so far all I'm seeing is AGG. Before I start
> hacking away at AGG, I would just like to confirm: is this the right
> place?
>  Basically, all this should involve is reading an RGB8 bitmap back from
> FreeType, rather than 8-bit grayscale. I'm not entirely sure yet how the
> different AA pixel colors would get blended back properly onto the screen 
> and
> against different background colors, so if anyone could chime in on that
> I'd appreciate it.
>  (Yes, I'm aware of the patent issues, but I'd like to make this an
> option for those willing to recompile parts of Haiku from source.)

It will be very nice if you can make this work.

Text rendering is implemented here:

see src/servers/app/drawing/Painter/font_support
and src/servers/app/drawing/Painter/drawing_modes

You need to have a bit of background on how AGG works. I try to tell you 
the most important bits. You have these classes:

* "rendering buffer"
* "pixel format"
* "renderer"
* "rasterizer"

The rasterizer produces a scanline of alpha values (so one uint8 value per 
pixel). It then uses a renderer, which in turn uses a pixel format instance 
to "blend" this scanline into the existing rendering buffer. In the 
"drawing_modes" folder, you see how there is a PixelFormat implementation, 
which "dispatches" the functions which a pixel format must implement for 
the renderer to the BeOS drawing modes.

Text rendering works in two ways (see font_support/AGGTextRenderer). Either 
a native freetype bitmap (gray8) is used (in which the rasterizer is 
bypassed). Or the text is rendererd by the AGG rasterizer in case of 
transformed text (btw, it would produce exactly the same as the freetype 
rasterizer for non-transformed text). As far as the pipeline is concerned 
from that on, it just deals with scanlines of alpha values, which it blends 
according to the current drawing mode.

So what do you need to do?

You need to reimplement every DrawingMode for text. These special versions 
will have to treat the alpha values from the scanlines as alpha versions 
per subpixel (so triplets of alpha values). You need to apply filtering 
(weighting!) or you will get colored glyph edges. See the agg mailing list 
archive for the code for that (or libfreetype). Then you need to make 
freetype render the glyph bitmaps with triple horizontal resolution for 
non-transformed glyphs, as well as the rasterizer for transformed glyphs. 
The first one is accomplished by changing agg_font_freetype, the second one 
might be tricky because the rasterizer needs to be made to think the 
available rendering buffer is two times larger in width.

Another option is to simply change *the existing* drawing mode 
implementations to work with subpixel alpha scanlines (so that you don't 
have to special case text). This would give you LCD subpixel rendering for 
all vector shapes, not just text. And that would of course seriously rock 
(no one does that as far as I know), only downside being that it has three 
times the rendering time. Which might not matter much, since we bypass the 
vector rendering in most usage cases anyways.

Hope this help, please ask if anything is unclear!

Best regards,

Other related posts: