Pango Interaction

Pango Interaction — Using Pango in GDK

Synopsis


#include <gdk/gdk.h>


            GdkPangoRenderer;
            GdkPangoRendererClass;
PangoRenderer* gdk_pango_renderer_new       (GdkScreen *screen);
PangoRenderer* gdk_pango_renderer_get_default
                                            (GdkScreen *screen);
void        gdk_pango_renderer_set_drawable (GdkPangoRenderer *gdk_renderer,
                                             GdkDrawable *drawable);
void        gdk_pango_renderer_set_gc       (GdkPangoRenderer *gdk_renderer,
                                             GdkGC *gc);
void        gdk_pango_renderer_set_stipple  (GdkPangoRenderer *gdk_renderer,
                                             PangoRenderPart part,
                                             GdkBitmap *stipple);
void        gdk_pango_renderer_set_override_color
                                            (GdkPangoRenderer *gdk_renderer,
                                             PangoRenderPart part,
                                             const GdkColor *color);
PangoContext* gdk_pango_context_get         (void);
PangoContext* gdk_pango_context_get_for_screen
                                            (GdkScreen *screen);
void        gdk_pango_context_set_colormap  (PangoContext *context,
                                             GdkColormap *colormap);
            GdkPangoAttrEmbossed;
            GdkPangoAttrStipple;
PangoAttribute* gdk_pango_attr_embossed_new (gboolean embossed);
PangoAttribute* gdk_pango_attr_stipple_new  (GdkBitmap *stipple);
GdkRegion*  gdk_pango_layout_get_clip_region
                                            (PangoLayout *layout,
                                             gint x_origin,
                                             gint y_origin,
                                             gint *index_ranges,
                                             gint n_ranges);
GdkRegion*  gdk_pango_layout_line_get_clip_region
                                            (PangoLayoutLine *line,
                                             gint x_origin,
                                             gint y_origin,
                                             gint *index_ranges,
                                             gint n_ranges);


Object Hierarchy


  GObject
   +----PangoRenderer
         +----GdkPangoRenderer

Properties


  "screen"               GdkScreen             : Read / Write / Construct Only

Description

Pango is the text layout system used by GDK and GTK+. The functions and types in this section are used to render Pango objects to GDK. drawables, and also extend the set of Pango attributes to include stippling and embossing.

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 gdk_draw_layout(); you can also draw pieces of the layout with gdk_draw_layout() or gdk_draw_glyphs(). GdkPangoRenderer is a subclass of PangoRenderer that is used internally to implement these functions. Using it directly or subclassing it can be useful in some cases. See the GdkPangoRenderer documentation for details.

Example 7. Using GdkPangoRenderer to draw transformed text

define RADIUS 100
define N_WORDS 10
define FONT "Sans Bold 18"
  
GdkScreen *screen = gdk_drawable_get_screen (drawable);
PangoRenderer *renderer;
GdkGC *gc;

PangoMatrix matrix = PANGO_MATRIX_INIT;
PangoContext *context;
PangoLayout *layout;
PangoFontDescription *desc;

double device_radius;
int width, height;
int i;

/* Get the default renderer for the screen, and set it up for drawing  */
renderer = gdk_pango_renderer_get_default (screen);
gdk_pango_renderer_set_drawable (GDK_PANGO_RENDERER (renderer), drawable);

gc = gdk_gc_new (drawable);
gdk_pango_renderer_set_gc (GDK_PANGO_RENDERER (renderer), gc);

/* 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 */
gdk_drawable_get_size (drawable, &width, &height);
device_radius = MIN (width, height) / 2.;

pango_matrix_translate (&matrix,
                        device_radius + (width - 2 * device_radius) / 2,
                        device_radius + (height - 2 * device_radius) / 2);
pango_matrix_scale (&matrix, device_radius / RADIUS, device_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++)
  {
    GdkColor color;
    PangoMatrix rotated_matrix = matrix;
    int width, height;
    double angle = (360. * i) / N_WORDS;

    /* Gradient from red at angle == 60 to blue at angle == 300 */
    color.red   = 65535 * (1 + cos ((angle - 60) * M_PI / 180.)) / 2;
    color.green = 0;
    color.blue  = 65535  - color.red;
    
    gdk_pango_renderer_set_override_color (GDK_PANGO_RENDERER (renderer),
                                           PANGO_RENDER_PART_FOREGROUND, &color);
                                             
    pango_matrix_rotate (&rotated_matrix, angle);

    pango_context_set_matrix (context, &rotated_matrix);
    
    /* Inform Pango to re-layout the text with the new transformation matrix */
    pango_layout_context_changed (layout);
    
    pango_layout_get_size (layout, &width, &height);
    pango_renderer_draw_layout (renderer, layout,
                                - width / 2, - RADIUS * PANGO_SCALE);
  }

/* Clean up default renderer, since it is shared */
gdk_pango_renderer_set_override_color (GDK_PANGO_RENDERER (renderer),
                                       PANGO_RENDER_PART_FOREGROUND, NULL);
gdk_pango_renderer_set_drawable (GDK_PANGO_RENDERER (renderer), NULL);
gdk_pango_renderer_set_gc (GDK_PANGO_RENDERER (renderer), NULL);

/* free the objects we created */
g_object_unref (layout);
g_object_unref (context);
g_object_unref (gc);


Details

GdkPangoRenderer

typedef struct _GdkPangoRenderer GdkPangoRenderer;

GdkPangoRenderer is a subclass of PangoRenderer used for rendering Pango objects into GDK drawables. The default renderer for a particular screen is obtained with gdk_pango_renderer_get_default(); Pango functions like pango_renderer_draw_layout() and pango_renderer_draw_layout_line() are then used to draw objects with the renderer.

In most simple cases, applications can just use gdk_draw_layout(), and don't need to directly use GdkPangoRenderer at all. Using the GdkPangoRenderer directly is most useful when working with a transformation such as a rotation, because the Pango drawing functions take user space coordinates (coordinates before the transformation) instead of device coordinates.

In certain cases it can be useful to subclass GdkPangoRenderer. Examples of reasons to do this are to add handling of custom attributes by overriding 'prepare_run' or to do custom drawing of embedded objects by overriding 'draw_shape'.

Since 2.6


GdkPangoRendererClass

typedef struct {
} GdkPangoRendererClass;

GdkPangoRenderer is the class structure for GdkPangoRenderer.

Since 2.6


gdk_pango_renderer_new ()

PangoRenderer* gdk_pango_renderer_new       (GdkScreen *screen);

Creates a new PangoRenderer for screen. Normally you can use the results of gdk_pango_renderer_get_default() rather than creating a new renderer.

screen : a GdkScreen
Returns : a newly created PangoRenderer. Free with g_object_unref().

Since 2.6


gdk_pango_renderer_get_default ()

PangoRenderer* gdk_pango_renderer_get_default
                                            (GdkScreen *screen);

Gets the default PangoRenderer for a screen. This default renderer is shared by all users of the display, so properties such as the color or transformation matrix set for the renderer may be overwritten by functions such as gdk_draw_layout().

Before using the renderer, you need to call gdk_pango_renderer_set_drawable() and gdk_pango_renderer_set_gc() to set the drawable and graphics context to use for drawing.

screen : a GdkScreen
Returns : the default PangoRenderer for screen. The renderer is owned by GTK+ and will be kept around until the screen is closed.

Since 2.6


gdk_pango_renderer_set_drawable ()

void        gdk_pango_renderer_set_drawable (GdkPangoRenderer *gdk_renderer,
                                             GdkDrawable *drawable);

Sets the drawable the renderer draws to.

gdk_renderer : a GdkPangoRenderer
drawable : the new target drawable, or NULL

Since 2.6


gdk_pango_renderer_set_gc ()

void        gdk_pango_renderer_set_gc       (GdkPangoRenderer *gdk_renderer,
                                             GdkGC *gc);

Sets the GC the renderer draws with. Note that the GC must not be modified until it is unset by calling the function again with NULL for the gc parameter, since GDK may make internal copies of the GC which won't be updated to follow changes to the original GC.

gdk_renderer : a GdkPangoRenderer
gc : the new GC to use for drawing, or NULL

Since 2.6


gdk_pango_renderer_set_stipple ()

void        gdk_pango_renderer_set_stipple  (GdkPangoRenderer *gdk_renderer,
                                             PangoRenderPart part,
                                             GdkBitmap *stipple);

Sets the stipple for one render part (foreground, background, underline, etc.) Note that this is overwritten when iterating through the individual styled runs of a PangoLayout or PangoLayoutLine. This function is thus only useful when you call low level functions like pango_renderer_draw_glyphs() directly, or in the 'prepare_run' virtual function of a subclass of GdkPangoRenderer.

gdk_renderer : a GdkPangoRenderer
part : the part to render with the stipple
stipple : the new stipple value.

Since 2.6


gdk_pango_renderer_set_override_color ()

void        gdk_pango_renderer_set_override_color
                                            (GdkPangoRenderer *gdk_renderer,
                                             PangoRenderPart part,
                                             const GdkColor *color);

Sets the color for a particular render part (foreground, background, underline, etc.), overriding any attributes on the layouts renderered with this renderer.

gdk_renderer : a GdkPangoRenderer
part : the part to render to set the color of
color : the color to use, or NULL to unset a previously set override color.

Since 2.6


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

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

Since 2.2


gdk_pango_context_set_colormap ()

void        gdk_pango_context_set_colormap  (PangoContext *context,
                                             GdkColormap *colormap);

Warning

gdk_pango_context_set_colormap is deprecated and should not be used in newly-written code.

This function used to set the colormap to be used for drawing with context. The colormap is now always derived from the graphics context used for drawing, so calling this function is no longer necessary.

context : a PangoContext
colormap : a GdkColormap

GdkPangoAttrEmbossed

typedef struct {
  PangoAttribute attr;
  gboolean embossed;
} GdkPangoAttrEmbossed;

A Pango text attribute containing a embossed bitmap to be used when rendering the text.

PangoAttribute attr; the PangoAttribute.
gboolean embossed; the embossed bitmap.

GdkPangoAttrStipple

typedef struct {
  PangoAttribute attr;
  GdkBitmap *stipple;
} GdkPangoAttrStipple;

A Pango text attribute containing a stipple bitmap to be used when rendering the text.

PangoAttribute attr; the PangoAttribute.
GdkBitmap *stipple; the stipple bitmap.

gdk_pango_attr_embossed_new ()

PangoAttribute* gdk_pango_attr_embossed_new (gboolean embossed);

Creates a new attribute containing a embossed bitmap to be used when rendering the text.

embossed : a bitmap to be set as embossed
Returns : new PangoAttribute

gdk_pango_attr_stipple_new ()

PangoAttribute* gdk_pango_attr_stipple_new  (GdkBitmap *stipple);

Creates a new attribute containing a stipple bitmap to be used when rendering the text.

stipple : a bitmap to be set as stipple
Returns : new PangoAttribute

gdk_pango_layout_get_clip_region ()

GdkRegion*  gdk_pango_layout_get_clip_region
                                            (PangoLayout *layout,
                                             gint x_origin,
                                             gint y_origin,
                                             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 same position you would pass to gdk_draw_layout_line(). 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 ()

GdkRegion*  gdk_pango_layout_line_get_clip_region
                                            (PangoLayoutLine *line,
                                             gint x_origin,
                                             gint y_origin,
                                             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 same position you would pass to gdk_draw_layout_line(). 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
n_ranges : number of ranges in index_ranges, i.e. half the size of index_ranges
Returns : a clip region containing the given ranges

Property Details

The "screen" property

  "screen"               GdkScreen             : Read / Write / Construct Only

the GdkScreen for the renderer.