## Pango Interaction

Pango Interaction — Using Pango in GDK

## Synopsis

    #include <gdk/gdk.h>

    cairo_region_t *    gdk_pango_layout_get_clip_region    (PangoLayout *layout,
                                                             gint x_origin,
                                                             gint y_origin,
                                                             const gint *index_ranges,
                                                             gint n_ranges);
    cairo_region_t *    gdk_pango_layout_line_get_clip_region
                                                            (PangoLayoutLine *line,
                                                             gint x_origin,
                                                             gint y_origin,
                                                             const gint *index_ranges,
                                                             gint n_ranges);
    PangoContext *      gdk_pango_context_get               (void);
    PangoContext *      gdk_pango_context_get_for_screen    (GdkScreen *screen);

## Description

Pango is the text layout system used by GDK and GTK+. The functions and types in this section are used to obtain clip regions for PangoLayouts, and to get PangoContexts that can be used with GDK.

Creating a PangoLayout object is the first step in rendering text, and requires getting a handle to a PangoContext. For GTK+ programs, you'll usually want to use `gtk_widget_get_pango_context()`, or `gtk_widget_create_pango_layout()`, rather than using the lowlevel `gdk_pango_context_get_for_screen()`. Once you have a PangoLayout, you can set the text and attributes of it with Pango functions like `pango_layout_set_text()` and get its size with `pango_layout_get_size()`. (Note that Pango uses a fixed point system internally, so converting between Pango units and pixels using PANGO_SCALE or the `PANGO_PIXELS()` macro.)

Rendering a Pango layout is done most simply with `pango_cairo_show_layout()`; you can also draw pieces of the layout with `pango_cairo_show_layout_line()`.

Example 5. Draw transformed text with Pango and cairo

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62

    #define RADIUS 100
    #define N_WORDS 10
    #define FONT "Sans Bold 18"

    PangoContext *context;
    PangoLayout *layout;
    PangoFontDescription *desc;

    double radius;
    int width, height;
    int i;

    /* Set up a transformation matrix so that the user space coordinates for
     * where we are drawing are [-RADIUS, RADIUS], [-RADIUS, RADIUS]
     * We first center, then change the scale */

    width = gdk_window_get_width (window);
    height = gdk_window_get_height (window);
    radius = MIN (width, height) / 2.;

    cairo_translate (cr,
                     radius + (width - 2 * radius) / 2,
                     radius + (height - 2 * radius) / 2);
                     cairo_scale (cr, radius / RADIUS, radius / RADIUS);

    /* Create a PangoLayout, set the font and text */
    context = gdk_pango_context_get_for_screen (screen);
    layout = pango_layout_new (context);
    pango_layout_set_text (layout, "Text", -1);
    desc = pango_font_description_from_string (FONT);
    pango_layout_set_font_description (layout, desc);
    pango_font_description_free (desc);

    /* Draw the layout N_WORDS times in a circle */
    for (i = 0; i < N_WORDS; i++)
      {
        double red, green, blue;
        double angle = 2 * G_PI * i / n_words;

        cairo_save (cr);

        /* Gradient from red at angle == 60 to blue at angle == 300 */
        red = (1 + cos (angle - 60)) / 2;
        green = 0;
        blue = 1 - red;

        cairo_set_source_rgb (cr, red, green, blue);
        cairo_rotate (cr, angle);

        /* Inform Pango to re-layout the text with the new transformation matrix */
        pango_cairo_update_layout (cr, layout);

        pango_layout_get_size (layout, &width, &height);

        cairo_move_to (cr, - width / 2 / PANGO_SCALE, - DEFAULT_TEXT_RADIUS);
        pango_cairo_show_layout (cr, layout);

        cairo_restore (cr);
      }

    g_object_unref (layout);
    g_object_unref (context);

Figure 1. Output of Example 5, “Draw transformed text with Pango and cairo”

## Details

### gdk_pango_layout_get_clip_region ()

    cairo_region_t *    gdk_pango_layout_get_clip_region    (PangoLayout *layout,
                                                             gint x_origin,
                                                             gint y_origin,
                                                             const gint *index_ranges,
                                                             gint n_ranges);

Obtains a clip region which contains the areas where the given ranges of text would be drawn. `x_origin` and `y_origin` are the top left point to center the layout. `index_ranges` should contain ranges of bytes in the layout's text.

Note that the regions returned correspond to logical extents of the text ranges, not ink extents. So the drawn layout may in fact touch areas out of the clip region. The clip region is mainly useful for highlightling parts of text, such as when text is selected.

`layout` : | a PangoLayout
`x_origin` : | X pixel where you intend to draw the layout with this clip
`y_origin` : | Y pixel where you intend to draw the layout with this clip
`index_ranges` : | array of byte indexes into the layout, where even members of array are start indexes and odd elements are end indexes
`n_ranges` : | number of ranges in `index_ranges`, i.e. half the size of `index_ranges`
Returns : | a clip region containing the given ranges

### gdk_pango_layout_line_get_clip_region ()

    cairo_region_t *    gdk_pango_layout_line_get_clip_region
                                                            (PangoLayoutLine *line,
                                                             gint x_origin,
                                                             gint y_origin,
                                                             const gint *index_ranges,
                                                             gint n_ranges);

Obtains a clip region which contains the areas where the given ranges of text would be drawn. `x_origin` and `y_origin` are the top left position of the layout. `index_ranges` should contain ranges of bytes in the layout's text. The clip region will include space to the left or right of the line (to the layout bounding box) if you have indexes above or below the indexes contained inside the line. This is to draw the selection all the way to the side of the layout. However, the clip region is in line coordinates, not layout coordinates.

Note that the regions returned correspond to logical extents of the text ranges, not ink extents. So the drawn line may in fact touch areas out of the clip region. The clip region is mainly useful for highlightling parts of text, such as when text is selected.

`line` : | a PangoLayoutLine
`x_origin` : | X pixel where you intend to draw the layout line with this clip
`y_origin` : | baseline pixel where you intend to draw the layout line with this clip
`index_ranges` : | array of byte indexes into the layout, where even members of array are start indexes and odd elements are end indexes. [array]
`n_ranges` : | number of ranges in `index_ranges`, i.e. half the size of `index_ranges`
Returns : | a clip region containing the given ranges

### gdk_pango_context_get ()

    PangoContext *      gdk_pango_context_get               (void);

Creates a PangoContext for the default GDK screen.

The context must be freed when you're finished with it.

When using GTK+, normally you should use `gtk_widget_get_pango_context()` instead of this function, to get the appropriate context for the widget you intend to render text onto.

The newly created context will have the default font options (see cairo_font_options_t) for the default screen; if these options change it will not be updated. Using `gtk_widget_get_pango_context()` is more convenient if you want to keep a context around and track changes to the screen's font rendering settings.

Returns : | a new PangoContext for the default display. [transfer full]

### gdk_pango_context_get_for_screen ()

    PangoContext *      gdk_pango_context_get_for_screen    (GdkScreen *screen);

Creates a PangoContext for `screen`.

The context must be freed when you're finished with it.

When using GTK+, normally you should use `gtk_widget_get_pango_context()` instead of this function, to get the appropriate context for the widget you intend to render text onto.

The newly created context will have the default font options (see cairo_font_options_t) for the screen; if these options change it will not be updated. Using `gtk_widget_get_pango_context()` is more convenient if you want to keep a context around and track changes to the screen's font rendering settings.

`screen` : | the GdkScreen for which the context is to be created.
Returns : | a new PangoContext for `screen`. [transfer full]

Since 2.2