#!/usr/bin/perl use strict; use warnings; use utf8; use Cairo; use constant { WIDTH => 450, HEIGHT => 600, TEXT => 'hëllø, wôrld', NUM_GLYPHS => 10, M_PI => 4 * atan2(1, 1), }; sub box_text { my ($cr, $utf8, $x, $y) = @_; $cr->save; my $extents = $cr->text_extents ($utf8); my $line_width = $cr->get_line_width; $cr->rectangle ($x + $extents->{x_bearing} - $line_width, $y + $extents->{y_bearing} - $line_width, $extents->{width} + 2 * $line_width, $extents->{height} + 2 *$line_width); $cr->stroke; $cr->move_to ($x, $y); $cr->show_text ($utf8); $cr->move_to ($x, $y); $cr->text_path ($utf8); $cr->set_source_rgb (1, 0, 0); $cr->set_line_width (1.0); $cr->stroke; $cr->restore; } sub box_glyphs { my ($cr, $x, $y, @glyphs) = @_; $cr->save; my $extents = $cr->glyph_extents (@glyphs); my $line_width = $cr->get_line_width; $cr->rectangle ($x + $extents->{x_bearing} - $line_width, $y + $extents->{y_bearing} - $line_width, $extents->{width} + 2 * $line_width, $extents->{height} + 2 * $line_width); $cr->stroke; foreach my $glyph (@glyphs) { $glyph->{x} += $x; $glyph->{y} += $y; } $cr->show_glyphs (@glyphs); $cr->glyph_path (@glyphs); $cr->set_source_rgb (1, 0, 0); $cr->set_line_width (1.0); $cr->stroke; foreach my $glyph (@glyphs) { $glyph->{x} -= $x; $glyph->{y} -= $y; } $cr->restore; } { my $surface = Cairo::ImageSurface->create ('argb32', WIDTH, HEIGHT); my $cr = Cairo::Context->create ($surface); $cr->set_source_rgb (0, 0, 0); $cr->set_line_width (2.0); $cr->save; $cr->rectangle (0, 0, WIDTH, HEIGHT); $cr->set_source_rgba (0, 0, 0, 0); $cr->set_operator ('source'); $cr->fill; $cr->restore; $cr->select_font_face ('sans', 'normal', 'normal'); $cr->set_font_size (40); if (1) { my $matrix = Cairo::Matrix->init_scale (40, -40); $cr->set_font_matrix ($matrix); $cr->scale (1, -1); $cr->translate (0, - HEIGHT); } my $font_extents = $cr->font_extents; my $height = $font_extents->{height}; my @glyphs = (); my $dx = 0; my $dy = 0; foreach (0 .. NUM_GLYPHS - 1) { my $glyph = { index => $_ + 4, x => $dx, y => $dy }; my $extents = $cr->glyph_extents ($glyph); $dx += $extents->{x_advance}; $dy += $extents->{y_advance}; push @glyphs, $glyph; } box_text ($cr, TEXT, 10, $height); $cr->translate (0, $height); $cr->save; { $cr->translate (10, $height); $cr->rotate (10 * M_PI / 180); box_text ($cr, TEXT, 0, 0); } $cr->restore; $cr->translate (0, 2 * $height); $cr->save; { my $matrix = Cairo::Matrix->init_identity; $matrix->scale (40, -40); $matrix->rotate (-10 * M_PI / 180); $cr->set_font_matrix ($matrix); box_text ($cr, TEXT, 10, $height); } $cr->restore; $cr->translate (0, 2 * $height); box_glyphs ($cr, 10, $height, @glyphs); $cr->translate (10, 2 * $height); $cr->save; { $cr->rotate (10 * M_PI / 180); box_glyphs ($cr, 0, 0, @glyphs); } $cr->restore; $cr->translate (0, $height); foreach (0 .. NUM_GLYPHS - 1) { $glyphs[$_]->{y} += $_ * 5; } box_glyphs ($cr, 10, $height, @glyphs); $surface->write_to_png ('text.png'); }