[GSOC 2024] Complex Font Rendering Update

Hello, this is an update from the last post about complex font rendering.

Here is a draft proposal after reviewing Harfbuzz and taking into account the discussion about it.

I have a few questions regarding the app_server and interface kit,

  1. What is the significance of the textview sub directory? textview_support « interface « kits « src - haiku - Haiku's main repository?
  2. Where would the initialisation of harfbuzz happen in the app_server? Is it the FontEngine.cpp file?

"PulkoMandy implemented some more features in HaikuDepot’s custom TextView (which is a prototype replacement for BTextView with a much cleaner design), including clickable text (for hyperlinks), underlines, and forcing a relayout of the document when things change.”

Look: Renamed BTextView folder to textview_support · haiku/haiku@b31b14e · GitHub

Here is a bit of reference, who can explain it better is @stippi :

1 Like

Thanks. For the B_CHAR_SPACING support, would this need to be worked upon as well while implementing the complex font renders? I can think of one use case where some characters in a word would need extra space if they are preceded by a particular letter in Arabic.

This is the implementation of BTextView, the main widget that handles text input. For complex font rendering, strictly speaking, you don’t need to touch this. In the end it just calls (one of the variants of) BView::DrawString to let app_server render the text.

Yes, but you should also not need to touch this one. Same thing: in the end it just sends the text to app_server using BView::DrawString.

There is some discussion of DrawString in BeOS documentation here: The Be Book - Classes And Methods - The Interface Kit

The various spacing types are explained here: The Be Book - Classes And Methods - The Interface Kit

But I think at first, let’s make the basic case work: the application sends a complete string to DrawString, that string gets rendered on screen and the cursor advanced where it needs to for the next string. In arabic, that means advancing the cursor to the left instead of to the right, of course. So, for this initial version, it will need some cooperation from the application (to initialize the cursor at the top right instead of the top left). Once we have this working, we can see about how to integrate it with BTextView and all the other things that draw text in Haiku.

The way the pap_server work is it receives commands from the application’s windows and views, in the case of string drawing the entry point into app_server will be here: ServerWindow.cpp « app « servers « src - haiku - Haiku's main repository this ends up calling drawingEngine->DrawString which is here: DrawingEngine.cpp « drawing « app « servers « src - haiku - Haiku's main repository and that gets us into the painter Painter.cpp « Painter « drawing « app « servers « src - haiku - Haiku's main repository which in turn lets the TextRenderer do the work: AGGTextRenderer.cpp « Painter « drawing « app « servers « src - haiku - Haiku's main repository

This is supported by two classes: StringRenderer (AGGTextRenderer.cpp « Painter « drawing « app « servers « src - haiku - Haiku's main repository) to do the actual drawing, and GlyphLayoutEngine (GlyphLayoutEngine.h « font « app « servers « src - haiku - Haiku's main repository) to convert the UTF-8 string into glyphs. Both of these will probably need some changes, as, currently, the glyph layout engine loops on unicode codepoints (through UTF8ToCharCode), which may not be appropriate (at this point you may know better than me how it is supposed to work for arabic text?)

Some other things that may be useful for this project: I suggest you make a test app that just has a window and calls DrawString in the simplest way as a test ground. Depending on how you work, it may also be much faster to do this using the test_app_server: this is an application that runs essentially a second app_server in a window. This means you can start and stop it without having to recompile the whole system. If you edit and compile your code inside Haiku, this will be much faster. Otherwise your development cycle will involve rebuilding a complete OS image or at least the complete Haiku package, and booting and rebooting a lot to test your changes. So, using test_app_server could save a lot of time. It is also a lot easier to put it into a Debugger if that’s needed.

1 Like