[cairo] Using Pango+Cairo to layout non-standard / international text
behdad at behdad.org
Tue Apr 15 15:42:45 PDT 2008
On Thu, 2008-04-10 at 23:25 +0300, Kalle Vahlman wrote:
> I have also made a demonstration of different orientations while
> figuring it out for myself, available from here:
Please make a patch to add the functionality as
pango/examples/cairo-vertical.c. Just copy from other examples there
for the skeleton (that is, drop GTK+ requirement).
> Behdad, if you would kindly review and point out the foolish lies and
> misinformation that I might have written below (and in the above
> code), I can create a patch to the docs with a revised version and
> attach it to a bug for further iterations (I'll do that tomorrow
> anyway though).
Could have been easier if it was a patch. Will give it a try:
> Since 1.16, Pango is able to correctly lay vertical text out. In fact,
> it can set layouts of mixed vertical and non-vertical text. This
> section describes the how to work with vertical text layout in Pango.
> The way this is implemented is through the concept of gravity. Gravity
> of normal Latin text is south. One way of defining gravity is to state
> that it is the direction from the center of the glyph towards the
> baseline. So gravity value of east means that glyphs will be rotated
> ninety degrees counterclockwise.
> Instead of changing the actual direction of the text flow, Pango
> facilitiates vertical text layout by changing the gravity of the
> glyphs when the layout (or more specifically, the matrix set to the
> current PangoContext) is rotated.
This par is inaccurate. "changing the gravity of the layout when ... is
rotated" only holds true for PANGO_GRAVITY_AUTO. How about: "Instead of
changing the actual direction of the text flow, Pango facilitates
vertical text layout by requiring that the layout be rotated using the
context matrix, and then the glyphs be adjusted for vertical layout by
way of setting the right gravity."
> This has the huge advantage that
> most algorithms working on a PangoLayout do not need any change as the
> assumption that lines run in the X direction and stack in the Y
> direction holds even for vertical text layouts.
> The gravity of the glyphs is automatically adjusted by Pango according
> to the natural orientation of the script if you set the base gravity
> of the current PangoContext to PANGO_GRAVITY_AUTO with
> pango_context_set_base_gravity(). Thus when you rotate the layout by
> 90 degrees clockwise, vertically orientated scripts are laid out in
> their natural orientation, while others are rotated as usual.
The above par also relies on the default gravity hint setting.
> A basic vertical layout example looks like this:
> PangoMatrix matrix = PANGO_MATRIX_INIT;
> ...create layout...
> pango_layout_set_text(layout, "...vertical text here...");
> context = pango_layout_get_context(layout);
> pango_context_set_base_gravity(context, PANGO_GRAVITY_AUTO);
> pango_matrix_rotate(&matrix, 90.0);
> pango_context_set_matrix(context, &matrix);
> pango_layout_context_changed (layout);
> ...render the layout...
This is useful, yes.
> Each rendering backend might give further assistance on layout
> handling, for example the cairo backend offers a way to automatically
> apply the current cairo transformation to the layout so no separate
> Pango matrix rotation is needed.
Don't like the "each rendering backend" part.. Just say "using the
cairo backend"... May also make sense to note somewhere that vertical
text is currently only supported by the cairo backend and only with
> The result of the automatic orientation can be queried with
> pango_context_get_gravity(). It returns the gravity depending on the
> current transformation matrix set to the current PangoContext.
I think my original explanation is more accurate.
> To force the base gravity setting you can set the PangoGravityHint to
> PANGO_GRAVITY_HINT_STRONG. This makes Pango ignore the natural gravity
> of the script, and by setting the gravity to the opposite direction of
> your rotation you can keep the glyphs in the natural orientation. For
> example, rotate the layout 90 degrees clockwise and set the gravity to
> PANGO_GRAVITY_EAST to make Latin text flow vertically.
This is becoming confusing even to me! Maybe just file your suggestions
in bugzilla and I finish and apply them later.
> Font descriptions have a gravity property too, that can be set using
> pango_font_description_set_gravity() and accessed using
> pango_font_description_get_gravity(). However, those are rarely useful
> from application code and are mainly used by PangoLayout internally.
> Last but not least, one can create PangoAttributes for gravity and
> gravity hint using pango_attr_gravity_new() and
> pango_attr_gravity_hint_new(). The attributes are also available
> through the Pango markup language.
Good point about markup of course.
"Those who would give up Essential Liberty to purchase a little
Temporary Safety, deserve neither Liberty nor Safety."
-- Benjamin Franklin, 1759
More information about the cairo