Text in Cairo
last modified July 17, 2023
In this part of the Cairo graphics tutorial we work with text.
Soulmate
In the first example we display some lyrics on the GTK+ window.
static void do_drawing(cairo_t *cr) { cairo_set_source_rgb(cr, 0.1, 0.1, 0.1); cairo_select_font_face(cr, "Purisa", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 13); cairo_move_to(cr, 20, 30); cairo_show_text(cr, "Most relationships seem so transitory"); cairo_move_to(cr, 20, 60); cairo_show_text(cr, "They're all good but not the permanent one"); cairo_move_to(cr, 20, 120); cairo_show_text(cr, "Who doesn't long for someone to hold"); cairo_move_to(cr, 20, 150); cairo_show_text(cr, "Who knows how to love you without being told"); cairo_move_to(cr, 20, 180); cairo_show_text(cr, "Somebody tell me why I'm on my own"); cairo_move_to(cr, 20, 210); cairo_show_text(cr, "If there's a soulmate for everyone"); }
In this example, we display part of the lyrics from the Natasha Bedingfield's Soulmate song.
cairo_select_font_face(cr, "Purisa", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
Here we select the font face. The function takes three parameters, the font family, font slant and the font weight.
cairo_set_font_size(cr, 13);
Here we specify the font size.
cairo_move_to(cr, 20, 30); cairo_show_text(cr, "Most relationships seem so transitory");
We display the text on the window by specifying the position of the text and
calling the cairo_show_text
function.
Centered text
Next we show how to center text on the window.
static void do_drawing(cairo_t *cr, GtkWidget *widget) { cairo_text_extents_t extents; GtkWidget *win = gtk_widget_get_toplevel(widget); gint w, h; gtk_window_get_size(GTK_WINDOW(win), &w, &h); cairo_select_font_face(cr, "Courier", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 60); cairo_text_extents(cr, "ZetCode", &extents); cairo_move_to(cr, w/2 - extents.width/2, h/2); cairo_show_text(cr, "ZetCode"); }
The code will center a text on the window. It remains centered, even if we resize the window.
GtkWidget *win = gtk_widget_get_toplevel(widget); gint w, h; gtk_window_get_size(GTK_WINDOW(win), &w, &h);
To center a text on the window, it is necessary to get the size of of the parent window.
cairo_select_font_face(cr, "Courier", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 60);
We select a font and its size to be displayed.
cairo_text_extents(cr, "ZetCode", &extents);
We get the text extents. These are some numbers that describe the text. We need the width of the text for our example.
cairo_move_to(cr, w/2 - extents.width/2, h/2); cairo_show_text(cr, "ZetCode");
We position the text into the middle of the window and show it using the
cairo_show_text
method.
Shaded text
Now we show a shaded text on the window.
static void do_drawing(cairo_t *cr, GtkWidget *widget) { cairo_select_font_face(cr, "Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 50); cairo_set_source_rgb(cr, 0, 0, 0); cairo_move_to(cr, 40, 60); cairo_show_text(cr, "ZetCode"); cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); cairo_move_to(cr, 43, 63); cairo_show_text(cr, "ZetCode"); }
To create a shade, we draw the text twice. In different colours. The second text is moved a bit to the right and bottom.
cairo_set_source_rgb(cr, 0, 0, 0); cairo_move_to(cr, 40, 60); cairo_show_text(cr, "ZetCode");
The first text is drawn in black ink. It serves as a shade.
cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); cairo_move_to(cr, 43, 63); cairo_show_text(cr, "ZetCode");
The second text is drawn in some gray ink. It is moved by 3px to the right and to the bottom.
Text filled with gradient
The following example will create a nice effect. We fill a text with some linear gradient.
static void do_drawing(cairo_t *cr, GtkWidget *widget) { cairo_pattern_t *pat; cairo_set_source_rgb(cr, 0.2, 0.2, 0.2); cairo_paint(cr); gint h = 90; cairo_select_font_face(cr, "Serif", CAIRO_FONT_SLANT_ITALIC, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, h); pat = cairo_pattern_create_linear(0, 15, 0, h*0.8); cairo_pattern_set_extend(pat, CAIRO_EXTEND_REPEAT); cairo_pattern_add_color_stop_rgb(pat, 0.0, 1, 0.6, 0); cairo_pattern_add_color_stop_rgb(pat, 0.5, 1, 0.3, 0); cairo_move_to(cr, 15, 80); cairo_text_path(cr, "ZetCode"); cairo_set_source(cr, pat); cairo_fill(cr); }
We draw a text on the window filled with a linear gradient. The colours are some orange colours.
cairo_set_source_rgb(cr, 0.2, 0.2, 0.2); cairo_paint(cr);
To make it more visually appealing, we paint the background in dark gray colour.
pat = cairo_pattern_create_linear(0, 15, 0, h*0.8); cairo_pattern_set_extend(pat, CAIRO_EXTEND_REPEAT); cairo_pattern_add_color_stop_rgb(pat, 0.0, 1, 0.6, 0); cairo_pattern_add_color_stop_rgb(pat, 0.5, 1, 0.3, 0);
The linear gradient is created.
cairo_move_to(cr, 15, 80); cairo_text_path(cr, "ZetCode"); cairo_set_source(cr, pat); cairo_fill(cr);
The text is displayed on the window. We use the gradient as a source for painting.
Glyphs
The cairo_show_text
method is only suitable for simple text
rendering. Cairo developers call it a toy method. More professional text
rendering is done with glyphs. A glyph is a graphic symbol which
provides a form for a character. A character provides a meaning. It can
have multiple glyphs. A character has no intrinsic appearance.
A glyph has no intrinsic meaning.
Note that many common programming requirements conserning text are addressed by the Pango library.
static void do_drawing(cairo_t *cr, GtkWidget *widget) { cairo_select_font_face(cr, "Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, 13); const int n_glyphs = 20 * 35; cairo_glyph_t glyphs[n_glyphs]; gint i = 0; gint x, y; for (y=0; y<20; y++) { for (x=0; x<35; x++) { glyphs[i] = (cairo_glyph_t) {i, x*15 + 20, y*18 + 20}; i++; } } cairo_show_glyphs(cr, glyphs, n_glyphs); }
This code shows 700 glyphs of a chosen font.
const int n_glyphs = 20 * 35; cairo_glyph_t glyphs[n_glyphs];
The glyphs array will store three integer values. The first value is the index of the glyph to the chosen font type. The second and the third values are x, y positions of a glyph.
cairo_show_glyphs(cr, glyphs, n_glyphs);
The cairo_show_glyphs
method shows the glyphs
on the window.
This chapter covered text in Cairo.