#!/usr/bin/perl # # This examples shows how to print a (lined) buffer, wrapping lines if they are # too long for the page boundaries. (ebassi) use strict; use warnings; use Gtk2 '-init'; use Gnome2::Print; use constant FONT_NAME => 'Bitstream Vera Sans Roman'; use constant FONT_SIZE => 16.0; use constant LEFT_BORDER => 100; use constant BOTTOM_BORDER => 100; our $d = create_dialog(); $d->show; Gtk2->main; 0; sub render_job { my $job = shift; my $conf = $job->get_config; my $pc = $job->get_context; my $buffer = [ "Twinkle Twinkle", "Little Star", "Twinkle Twinkle", "Where You Are", "", "This is some text created just for testing purposes. It's longer than a single line, and it's wider than the page margin, in order to verify that the text wrapping mechanism is working properly.", "", "Hope it'll all go well.", ]; my $font = Gnome2::Print::Font->find_closest(FONT_NAME, FONT_SIZE); my $font_height = $font->get_descender + $font->get_ascender; my $line_spacing = 1.2 * $font->get_size; my @adv = $font->get_glyph_stadvance($font->lookup_default(ord(' '))); my $space_advance = $adv[0]; my ($width, $height) = $job->get_page_size; my $font_name = $font->get_name; printf "Found: %s (%.1f)\n", $font_name, $font->get_size; # start cursor. my $cur_x = LEFT_BORDER; my $cur_y = $height - BOTTOM_BORDER; # begin page my $page_n = 1; print "(cur_x, cur_y) = $cur_x, $cur_y\n"; # init $pc->beginpage(sprintf("%d", $page_n++)); $pc->moveto($cur_x, $cur_y); $pc->setfont($font); foreach my $line (@$buffer) { # fetch line width my $line_width = $font->get_width_utf8($line); print "line width: $line_width\n"; if ($line_width < ($width - 2 * LEFT_BORDER - 1)) { # fastpath for lines smaller than page width $pc->show($line); $cur_y -= ($font_height + $line_spacing); # start a new page if we hit this page's bottom border if ($cur_y < BOTTOM_BORDER) { $cur_y = $height - BOTTOM_BORDER; $pc->showpage; $pc->beginpage(sprintf("%d", $page_n++)); $pc->setfont($font); } print "(cur_x, cur_y) = $cur_x, $cur_y\n"; $pc->moveto($cur_x, $cur_y); } else { # word wrapping at word boundaries. my @words = split /\s/, $line; foreach my $w (@words) { my $word_width = $font->get_width_utf8($w); printf "*** word (%s[%d]) width: %d\n", $w, length($w), $word_width; if ($cur_x < ($width - 2 * LEFT_BORDER - 1)) { # word still inside page boundary; remember the space! $cur_x += ($word_width + $space_advance); $pc->show(sprintf("%s ", $w)); $pc->moveto($cur_x, $cur_y); } else { # wrapping print "*** wrapping at '$w'!\n"; $cur_x = LEFT_BORDER; $cur_y -= ($font_height + $line_spacing); # start a new page if we hit this page's bottom border if ($cur_y < BOTTOM_BORDER) { $cur_y = $height - BOTTOM_BORDER; $pc->showpage; $pc->beginpage(sprintf("%d", $page_n++)); $pc->setfont($font); } $pc->show(sprintf("%s", $w)); $pc->moveto($cur_x, $cur_y); } print "(cur_x, cur_y) = $cur_x, $cur_y\n"; } # move to next line $cur_x = LEFT_BORDER; $cur_y -= ($font_height + $line_spacing); $pc->moveto($cur_x, $cur_y); } } $pc->showpage; $job->close; } sub create_dialog { my $job = Gnome2::Print::Job->new; my $dialog = Gnome2::Print::Dialog->new($job, "Sample print dialog", 0); $dialog->signal_connect(delete_event => sub { $dialog->destroy; }); $dialog->signal_connect(destroy => sub { Gtk2->main_quit; }); $dialog->signal_connect(response => sub { my ($d, $response_id, $job) = @_; my $conf = $d->get_config; my $j = Gnome2::Print::Job->new($conf); if (1 eq $response_id) { render_job($j); my $pc = Gnome2::Print::Context->new($conf); $j->render($pc); $pc->close; $d->destroy; } elsif (2 eq $response_id) { render_job($j); my $preview = Gnome2::Print::JobPreview->new($j, "Sample preview dialog"); $preview->set_property("allow-grow" => 1); $preview->set_property("allow-shrink" => 1); $preview->set_transient_for($d); $preview->show_all; } else { $d->destroy; } }, $job); return $dialog; }