[cairo] Using Pango+Cairo to layout non-standard / international text

Kalle Vahlman kalle.vahlman at gmail.com
Thu Apr 10 13:25:24 PDT 2008


2008/4/10, robertk54 at aol.com <robertk54 at aol.com>:
>  I assumed that to handle right-to-left (i.e. Hebrew) or vertical (i.e.
> Chinese) fonts I would need to adjust the gravity attribute (and possibly
> rotate the text?) but this does not seem to work.  I am currently using
> english fonts such (i.e. Arial) and would hope to see the text rendered
> vertically instead of horizontally (I am not yet rotating so I guess I would
> expect the characters to be rotated but the text layed out horizontally?).
> If I use anything but the default setting the text is rendered as small,
> hollow boxes.  Can anyone provide some insight into how to properly achieve
> this?

I've had this thread

  http://lists.cairographics.org/archives/cairo/2007-October/011792.html

in my inbox as a todo for quite some time so I guess it's time to get
it over with.

Judging by the fact that you referred to the gravity setting, I'm
assuming you have read the original description from

  http://library.gnome.org/devel/pango/stable/pango-Vertical-Text.html

I'll paste my proposal for an enhanced version here, in hopes that
this is not too offtopic for the cairo list. It seems to be a
recurring question here after all.

I have also made a demonstration of different orientations while
figuring it out for myself, available from here:

  http://iki.fi/zuh/pango-rotated.c

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).

---8<---

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 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.

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...

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.

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.

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.

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.

---8>---

-- 
Kalle Vahlman, zuh at iki.fi
Powered by http://movial.fi
Interesting stuff at http://syslog.movial.fi


More information about the cairo mailing list