Pango Markup Language and writing direction

According to the docs, I can assign a font to a segment of text but not a writing direction. This means that when I have a LTR text with a phrase that is RTL I have to rely on the underlying harfbuzz library to guess (hb_buffer_guess_segment_properties()) the correct writing direction. Harfbuzz discourages this since it is a guess, it won’t always make the right choice.

Shouldn’t there be a way to designate writing direction (and, while on the topic, script) in the markup language?

Text direction isn’t really a style, it’s something inherent to the text, which I believe is why pango doesn’t have an attribute for it (and thus no markup)

Of course pango is all about unicode and clearly you have unicode text so unicode:

U+200F RIGHT-TO-LEFT MARK
U+200E LEFT-TO-RIGHT MARK

While RLM and LRM can help in some circumstances, HTML has a dir attribute that can be used in span (and other elements) to help cover all cases. Apparently with good reasons.

Writing direction is highly contextual, and figuring out that context starts with the user’s locale. When GTK gets initialized, it figures out the text direction from the locale (am I in an English locale? in an Arabic locale?), and saves it in a global variable. When widgets get created, they get PangoContext objects created for them, and each context gets told to use that text direction.

You can override a widget’s default direction with gtk_widget_set_direction.

Pango markup is not “a little HTML” and GTK’s widget tree is not a DOM; they have different concepts :slight_smile:

Is there any specific problem that you are trying to solve? Maybe displaying user-entered text in a table where you don’t know the text direction for each cell?

What I try to find out is if I can use Pango for generic typesetting. So no GTK context, no widgets, preferrably no Cairo.
I would like to just use Pango layout. Call set_markup() and get back a list of glyphs and where to put them. And yes, the texts are user-supplied.

You can, it’s perfectly possible, but if you want to do low level text rendering you get to handle low level text rending and figure stuff like the base direction yourself

Well, that is actually what I would like to avoid… Placing glyphs in e.g. PDF is a piece of cake. Finding out what glyphs to place where is the hard part. And this is something Pango already excels in.

From Pango’s perspective you are low-level, e.g. the docs for pango_context_new

Creates a new PangoContext initialized to default values.

This function is not particularly useful as it should always be followed by a pango_context_set_font_map() call, and the function pango_font_map_create_context() does these two steps together and hence users are recommended to use that.

If you are using Pango as part of a higher-level system, that system may have it’s own way of create a PangoContext. For instance, the GTK+ toolkit has, among others, gdk_pango_context_get_for_screen() , and gtk_widget_get_pango_context() . Use those instead.

The boilerplate you’ll need should be fairly minimal, but by using pango directly your going to have to write an amount of boilerplate

No problem to write some boilerplate code. Unfortunately the documentation on doing so is virtually nonexistent. I also heard that the pango web site (and documentation there) is very outdated…
Any pointers to more recent/usable materials?

The Pango website is indeed out of date. The Pango reference is up to date, but outside of the API reference you may not find a lot of documentation on how to use Pango completely stand alone.

Hmm. In that case I must revise my ‘No problem to write some boilerplate code’ :unamused:

I think you may be in a similar situation to librsvg, which uses Pango to draw text that comes from SVG documents. It uses Cairo but not GTK; the caller of the library passes a Cairo context to it, and the library draws everything to that cairo_t, including text with Pango.

You create a PangoLayout from a PangoContext; in the case of librsvg this is a context created from a PangoCairoFontMap. The basic codes goes like this:

PangoLayout does the hard work of running the Unicode bidi algorithm on your string, itemizing it, figuring out the direction of items, shaping each glyph string, etc. If you want to access the low-level stages, you can use PangoLayoutIter and pango_layout_iter_next_cluster, for example, and then draw items individually with pango_cairo_show_glyph_string.

PangoLayout is complex because it doesn’t just do the job of dissecting a string for drawing; it can also answer questions like, “given an (x, y) point, what glyph is under the mouse cursor”, or “point me to the next cluster as if the user had hit the Right arrow key”. If your typesetting system doesn’t need that, it’s possible to not use Pango, but the lower-level libraries directly (Harfbuzz to do shaping, maybe Fontconfig to enumerate fonts if your platform is happy with it, etc.). Librsvg may in fact have to do that eventually to get fine typographical control of each glyph, which is something SVG wants but Pango can’t really do directly.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.