On Friday, 25 October 2024 at 12:49:36 UTC, cookiewitch wrote:
Looking through Pango's documentation and code, [integrating it with Fluid might be tricky](https://git.samerion.com/Samerion/Fluid/issues/197). This topic is also complex and there are things I don't understand about Pango's approach that I can't find an explanation of. This is probably something I'll have to spend a lot of time on to get a proper grasp of.

I'd really appreciate it if there were some other, more comprehensive learning resources. Do you know any?

Sorry for my late reply! Anyway, here we go…

## Easy compromises
I was able to figure out how to use it for *static* text pretty easily from just the official docs. I found it best to look at what you want at the end (e.g. rendering the text), find how you do that, and then work backwards from there.

This might not help you that much, but here's a step-by-step outline on getting started using Pango, with links to the relevant documentation, which provide a decent amount of insight into what each class is/does. This boils down to [about 20 lines of code from my example](https://github.com/BindBC/bindbc-pango/blob/master/example/source/app.d#L54). - First you need a [`PangoFontMap`](https://docs.gtk.org/Pango/class.FontMap.html). You can, for instance, get a `PangoFontMap` implemented using FreeType with `pango_ft2_font_map_new`. - Then, create a [`PangoContext`](https://docs.gtk.org/Pango/class.Context.html) from the `PangoFontMap`. - Create a [`PangoFontDescription`](https://docs.gtk.org/Pango/struct.FontDescription.html) (e.g. using `pango_font_description_new`) and use whichever setter functions on it to provide info about what font you want it to use, how large it should be, et cetera. Pango automatically uses fallback fonts when needed, which is why you don't *just* give it which font to use. This way, when users write glyphs that are not included in your preferred font, the overall appearance of the text can remain more-or-less consistent. In my example I only set the size of a `PangoFontDescription`, so Pango will basically default to using the system's preferred default fonts. - Set the `PangoContext`'s `PangoFontDescription` to the one you just created/populated. - Create a [`PangoLayout`](https://docs.gtk.org/Pango/class.Layout.html) from the `PangoContext`. This layout object handles a lot of things for you that you can mostly otherwise do yourself with components of the Pango library like .
- You can set the layout's contents with:
- an unformatted string: [`pango_layout_set_text`](https://docs.gtk.org/Pango/method.Layout.set_text.html) - a string formatted with [Pango Markup](https://docs.gtk.org/Pango/pango_markup.html): [`pango_layout_set_markup`](https://docs.gtk.org/Pango/method.Layout.set_markup.html) - a string specially-formatted by your own code: `pango_layout_set_text` and [`pango_layout_set_attributes`](https://docs.gtk.org/Pango/method.Layout.set_attributes.html)

From there, you'd mostly be interacting with the layout.

A few things to note:
- Pango uses reference counting for basically everything, so make sure to read up on how you're supposed to `unref` objects you've created so that they get deallocated. Often this is done with `g_object_unref` instead of a function from Pango. - The API & API reference use the term 'character' confusingly. Mostly it seems to refer to code-points, but occasionally I believe it is used to refer to individual bytes (i.e. code-units).

## So many problems
I really don't think the stock `PangoLayout` implementation provides a way to make using ropes work in a fast manner without just capitulating and using strings. However, you could re-implement **most** (but not all) of `PangoLayout`'s layout functionality from functions that Pango exposes. [This page should give you an idea](https://docs.gtk.org/Pango/pango_rendering.html).

Pango is far from perfect, and in some ways using it is an inherent compromise between what you want, and what's possible using libraries out there today. Even TextKit is [not without its problems](https://atadistance.net/2021/07/13/apple-text-layout-architecture-evolution-textkit-reboot/).

## The baby and the bathwater
There is one way around all of this, which is building a new text layout engine…

Some consideration should be given to where to start. For instance, one could build up from HarfBuzz. However, HarfBuzz is another GLib-based FSF C library, just like Pango, so perhaps this would just shift the compromises further down the line. Say we want *no* compromises; then we have to do everything 100% in D. Certainly neither of these options are trivial, and it would be a fool's errand to embark upon them alone. Having a full D text layout engine is a pet dream of mine of course, so if you're interested in contributing to a project like that then I might be able to dedicate some of my spare time to it.

Reply via email to