[haiku-development] Re: Text rendering

  • From: Stephan Assmus <superstippi@xxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Mon, 18 Jun 2007 18:29:53 +0200

Claudio Leite wrote (2007-06-18, 16:45:28 [+0200]):
> Hello again,
> 
>  Maxim replied on the AGG list and advised to implement this on a lower
> level (below scanlines). But it seems AGGTextRenderer uses scanlines and
> renderers even when using a FT bitmap. I'm thinking it might be useful
> to bypass AGG totally in this case--since the functionality is all
> there in FT--and just blend the FT alpha bitmap to the screen buffer in
> DrawString() or some new class I create. My question is, thus, where does 
> the
> screen buffer actually get written, and how could I access its values in
> order to do the blending?
> 
>  I must admit I'm proposing this alternative because I'm still having
> major difficulties figuring out AGG and Painter and where they
> intersect. You said in the README that you wrote a news article
> explaining the basics--where can I access this? In any case, it seems as
> though the relevant parts of AGGTextRenderer boil down to only a few
> functions, and unfortunately it seems agg_font_freetype and AGG itself
> are rather committed to the idea of gray8 and mono, nothing else.

I have read the reply from Maxim. Unfortunately, he doesn't really answer 
your question with regards to how the scanline adaptor in the font manager 
works.

I would urge you to trust me on this and take my advice. I know the 
FreeType->AGG->Painter->app_server design best, and I tried to convince you 
of the best approach. Maxim does not know this design, but basically, he 
told you the same thing as I, which is that you have to implement your own 
"pixel format". This is the same thing what I meant when I wrote, you need 
to reimplement the "DrawingMode" classes. I explained this in my first 
email.

The reason why I am suggesting not to bypass the existing framework, is 
that you need to support all those drawing modes that the Be API defines 
anyways. I mean, ok, if you wanted, you could implement it only for 
B_OP_COPY, B_OP_OVER and B_OP_ALPHA at first... to get things started. But 
then you need to check if the drawing mode is one of those, and handle it 
specially, and only when rendering text.

I know how it feels to try and understand an existing codebase, but it will 
be worth the effort. I will try to explain some more in this email.

The Painter class is "attached" to a rendering buffer. It happens in 
Painter::AttachToBuffer(). Most times, this is the frame buffer in the 
graphics card, but it could be a BBitmap prepared for drawing into, or it 
could be a copy of the frame buffer in main memory for doing double 
buffering (which is done when the color space of the frame buffer is not 32 
bits!).

There are several classes involved in the AGG rendering pipeline:

rendering buffer:
  knows the address and size of the memory allocated for the buffer and
  keeps a pointer to the beginning of every line of pixels

pixel format:
  is attached to a rendering buffer, and it knows how to write color
  information into pixels
  it needs to implement a certain interface (blend_solid_hline()...)

(The Painter implementation is called "PixelFormat", and lives in 
src/servers/app/drawing/Painter/drawing_modes/... it dispatches the needed 
implementation of each "pixel format" function to a DrawingMode instance, 
which implement the blending for the Be API defined drawing modes such as 
B_OP_COPY, B_OP_ADD, B_OP_INVERT...) In Painter::_UpdateDrawingMode(), the 
PixelFormat is configured so that it uses the correct DrawingMode 
implementation. It even knows if we are about to render text, so you can 
use this information.

renderer:
  provides the connection between the pixel format and the rasterizer

(Painter uses just the AGG provided implementation, but attaches it to the 
custom PixelFormat implementation above.)

rasterizer:
  produces "scanlines" of alpha values, based on the coverage of
  vector shapes over pixels areas and uses a renderer to write
  these scanlines into pixels

(Again, Painter uses the stock AGG implementation.)

For text rendering, AGG uses a "font manager" implementation. The back end 
for that is the "font engine", for which Painter again uses a custom 
implementation, which is based on ServerFonts, the app_server's font 
representation.

*Somewhere*, Maxim has written a scanline adaptor in the "font manager" so 
that it can _copy_ scanlines from FT_Bitmaps, instead of having the 
rasterizer generate this output. The code must be there, and if I had some 
time, I would go look for it myself. It shouldn't be that hard to find. The 
AGG library lives in src/libs/agg.


My article on Painter is called "Painter and How AGG Works", but it seems 
to have completely disappeared from our site. I have no idea why, I know it 
used to be there. :-(


As mentioned, have a look at Painter::AttachToBuffer() to see how the 
pipeline is set up.


Best regards,
-Stephan


Other related posts: