[perl-cairo] Add example file for PDF outline support bindings
- From: Torsten Schönfeld <tsch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [perl-cairo] Add example file for PDF outline support bindings
- Date: Sun, 8 Nov 2020 21:07:24 +0000 (UTC)
commit 0a666e39220ce9a31d54ce32e4c90f03d9cc9fec
Author: Raymond S Brand <rsbx acm org>
Date: Thu Nov 5 15:06:38 2020 -0500
Add example file for PDF outline support bindings
examples/pdf-tagged-text.pl | 345 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 345 insertions(+)
---
diff --git a/examples/pdf-tagged-text.pl b/examples/pdf-tagged-text.pl
new file mode 100755
index 0000000..5bf64a1
--- /dev/null
+++ b/examples/pdf-tagged-text.pl
@@ -0,0 +1,345 @@
+#! /usr/bin/perl
+
+# Adapted and translated to Perl from the file test/pdf-tagged-test.c in the
+# Cairo (version 1.17.3) source repository by Adrian Johnson <ajohnson redneon com>.
+
+
+use strict;
+use warnings;
+use Cairo;
+
+use feature 'say';
+
+
+# This test checks PDF with
+# - tagged text
+# - hyperlinks
+# - document outline
+# - metadata
+# - thumbnails
+# - page labels
+
+
+use constant
+ {
+ FILENAME => 'pdf-tagged-text.pl.pdf',
+
+ PAGE_WIDTH => 595,
+ PAGE_HEIGHT => 842,
+
+ HEADING1_SIZE => 16,
+ HEADING2_SIZE => 14,
+ HEADING3_SIZE => 12,
+ TEXT_SIZE => 12,
+ HEADING_HEIGHT => 50,
+ MARGIN => 50,
+
+ CAIRO_TAG_DEST => 'cairo.dest',
+ CAIRO_TAG_LINK => 'Link',
+
+ CAIRO_PDF_OUTLINE_ROOT => 0,
+ };
+
+
+my @contents =
+ (
+ [ 0, "Chapter 1", 1 ],
+ [ 1, "Section 1.1", 4 ],
+ [ 2, "Section 1.1.1", 3 ],
+ [ 1, "Section 1.2", 2 ],
+ [ 2, "Section 1.2.1", 4 ],
+ [ 2, "Section 1.2.2", 4 ],
+ [ 1, "Section 1.3", 2 ],
+ [ 0, "Chapter 2", 1 ],
+ [ 1, "Section 2.1", 4 ],
+ [ 2, "Section 2.1.1", 3 ],
+ [ 1, "Section 2.2", 2 ],
+ [ 2, "Section 2.2.1", 4 ],
+ [ 2, "Section 2.2.2", 4 ],
+ [ 1, "Section 2.3", 2 ],
+ [ 0, "Chapter 3", 1 ],
+ [ 1, "Section 3.1", 4 ],
+ [ 2, "Section 3.1.1", 3 ],
+ [ 1, "Section 3.2", 2 ],
+ [ 2, "Section 3.2.1", 4 ],
+ [ 2, "Section 3.2.2", 4 ],
+ [ 1, "Section 3.3", 2 ],
+ );
+
+my @level_data =
+ (
+ [HEADING1_SIZE, 'H1', ['bold', 'open'],],
+ [HEADING2_SIZE, 'H2', [],],
+ [HEADING3_SIZE, 'H3', ['italic'],],
+ );
+
+my @ipsum_lorem = split(' ', "Lorem ipsum dolor sit amet, consectetur adipiscing"
+ . " elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
+ . " Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi"
+ . " ut aliquip ex ea commodo consequat. Duis aute irure dolor in"
+ . " reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla"
+ . " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa"
+ . " qui officia deserunt mollit anim id est laborum.");
+
+my @roman_numerals = ( "i", "ii", "iii", "iv", "v", );
+
+
+my @paragraph_text;
+my $paragraph_height = 0;
+my $line_height = 0;
+my $y_pos = 0;
+my @outline_parents;
+my $page_num = 0;
+
+
+sub layout_paragraph
+ {
+ my ($cr) = @_;
+
+ $cr->select_font_face('Serif', 'normal', 'normal');
+ $cr->set_font_size(TEXT_SIZE);
+
+ my $font_extents = $cr->font_extents();
+ $line_height = $$font_extents{height};
+
+ my $curr = $ipsum_lorem[0];
+ foreach (@ipsum_lorem[1..$#ipsum_lorem])
+ {
+ my $next = join(' ', $curr, $_);
+ my $text_extents = $cr->text_extents($next);
+ if ($$text_extents{width} + 2*MARGIN > PAGE_WIDTH)
+ {
+ push @paragraph_text, $curr;
+ $next = $_;
+ }
+ $curr = $next;
+ }
+ if ($curr ne '')
+ {
+ push @paragraph_text, $curr;
+ }
+
+ $paragraph_height = $line_height * (scalar @paragraph_text + 1);
+ }
+
+
+sub draw_paragraph
+ {
+ my ($cr) = @_;
+
+ $cr->select_font_face('Serif', 'normal', 'normal');
+ $cr->set_font_size(TEXT_SIZE);
+
+ $cr->tag_begin('P', '');
+ foreach (@paragraph_text)
+ {
+ $cr->move_to(MARGIN, $y_pos);
+ $cr->show_text($_);
+ $y_pos += $line_height;
+ }
+ $cr->tag_end('P');
+
+ $y_pos += $line_height;
+ }
+
+
+sub draw_page_num
+ {
+ my ($cr, $prefix, $num) = @_;
+
+ my $buf = ''
+ . (defined $prefix) ? $prefix : ''
+ . ($num) ? $num : '';
+
+ $cr->save();
+
+ $cr->select_font_face('Sans', 'normal', 'normal');
+ $cr->set_font_size(12);
+
+ $cr->move_to(PAGE_WIDTH/2, PAGE_HEIGHT - MARGIN);
+ $cr->show_text($buf);
+
+ $cr->restore();
+
+ $cr->get_target()->set_page_label($buf);
+ }
+
+
+sub draw_contents
+ {
+ my ($cr, $section) = @_;
+
+ if ($y_pos + HEADING_HEIGHT + MARGIN > PAGE_HEIGHT)
+ {
+ $cr->show_page();
+ draw_page_num($cr, $roman_numerals[$page_num++], 0);
+ $y_pos = MARGIN;
+ }
+
+ $cr->move_to(MARGIN, $y_pos);
+
+ $cr->select_font_face('Sans', 'normal', 'normal');
+ $cr->set_font_size($level_data[$$section[0]]->[0]);
+
+ $cr->save();
+ $cr->set_source_rgb(0, 0, 1);
+
+ $cr->tag_begin('TOCI', '');
+ $cr->tag_begin('Reference', '');
+ $cr->tag_begin(CAIRO_TAG_LINK, "dest='".$$section[1]."'");
+ $cr->show_text($$section[1]);
+ $cr->tag_end(CAIRO_TAG_LINK);
+ $cr->tag_end('Reference');
+ $cr->tag_end('TOCI');
+
+ $cr->restore();
+
+ $y_pos += HEADING_HEIGHT;
+ }
+
+
+sub draw_section
+ {
+ my ($cr, $section) = @_;
+
+ my $parent;
+
+ if ($$section[0] == 0)
+ {
+ $cr->show_page();
+ draw_page_num($cr, undef, $page_num++);
+ $y_pos = MARGIN;
+
+ $parent = CAIRO_PDF_OUTLINE_ROOT;
+ }
+ else
+ {
+ if ($y_pos + HEADING_HEIGHT + $paragraph_height + MARGIN > PAGE_HEIGHT)
+ {
+ $cr->show_page();
+ draw_page_num($cr, undef, $page_num++);
+ $y_pos = MARGIN;
+ }
+
+ $parent = $outline_parents[$$section[0]-1];
+ }
+
+ $cr->tag_begin('Sect', '');
+
+ $cr->select_font_face('Sans', 'normal', 'bold');
+ $cr->set_font_size($level_data[$$section[0]]->[0]);
+
+ $cr->move_to(MARGIN, $y_pos);
+
+ $cr->tag_begin($level_data[$$section[0]]->[1], '');
+ $cr->tag_begin(CAIRO_TAG_DEST, "name='".$$section[1]."'");
+ $cr->show_text($$section[1]);
+ $cr->tag_end(CAIRO_TAG_DEST);
+ $cr->tag_end($level_data[$$section[0]]->[1]);
+
+ $y_pos += HEADING_HEIGHT;
+ $outline_parents[$$section[0]] = $cr->get_target()->add_outline($parent, $$section[1],
"dest='".$$section[1]."'", $level_data[$$section[0]]->[2]);
+
+ for (my $i=0; $i<$$section[2]; $i++)
+ {
+ if ($y_pos + $paragraph_height + MARGIN > PAGE_HEIGHT)
+ {
+ $cr->show_page();
+ draw_page_num($cr, undef, $page_num++);
+ $y_pos = MARGIN;
+ }
+ draw_paragraph($cr);
+ }
+
+ $cr->tag_end('Sect');
+ }
+
+
+sub draw_cover
+ {
+ my ($cr) = @_;
+
+ $cr->select_font_face("Sans", 'normal', 'bold');
+ $cr->set_font_size(16);
+
+ $cr->move_to(PAGE_WIDTH/3, PAGE_HEIGHT/2);
+
+ $cr->tag_begin("Span", '');
+ $cr->show_text("PDF Features Test");
+ $cr->tag_end("Span");
+
+ draw_page_num($cr, "cover", 0);
+ }
+
+
+sub create_document
+ {
+ my ($surface, $cr) = @_;
+
+ layout_paragraph($cr);
+
+ $surface->set_thumbnail_size(PAGE_WIDTH/10, PAGE_HEIGHT/10);
+
+ $surface->set_metadata('title', "PDF Features Test");
+ $surface->set_metadata('author', "cairo test suite");
+ $surface->set_metadata('subject', "cairo test");
+ $surface->set_metadata('keywords', "tags, links, outline, page labels, metadata, thumbnails");
+ $surface->set_metadata('creator', "pdf-features");
+ $surface->set_metadata('create-date', "2016-01-01T12:34:56+10:30");
+ $surface->set_metadata('mod-date', "2016-06-21T05:43:21Z");
+
+ $cr->tag_begin("Document", '');
+
+ draw_cover($cr);
+ $surface->add_outline(CAIRO_PDF_OUTLINE_ROOT, 'Cover', 'page=1', ['bold']);
+ $cr->show_page();
+
+ $page_num = 0;
+ draw_page_num($cr, $roman_numerals[$page_num++], 0);
+ $y_pos = MARGIN;
+
+ $surface->add_outline(CAIRO_PDF_OUTLINE_ROOT, "Contents", "dest='TOC'", ['bold']);
+
+ $cr->tag_begin(CAIRO_TAG_DEST, "name='TOC' internal");
+ $cr->tag_begin("TOC", '');
+
+ foreach (@contents)
+ {
+ draw_contents($cr, $_);
+ }
+
+ $cr->tag_end("TOC");
+ $cr->tag_end(CAIRO_TAG_DEST);
+
+ $page_num = 1;
+ foreach (@contents)
+ {
+ draw_section($cr, $_);
+ }
+
+ $cr->tag_end("Document");
+ }
+
+
+my $surface = Cairo::PdfSurface->create(FILENAME, PAGE_WIDTH, PAGE_HEIGHT);
+
+my $cr = Cairo::Context->create($surface);
+create_document($surface, $cr);
+
+my $status = $cr->status();
+$cr = undef;
+$surface->finish();
+my $status2 = $surface->status();
+if ($status ne 'success')
+ {
+ $status = $status2;
+ }
+
+$surface = undef;
+if ($status ne 'success')
+ {
+ say "Failed to create pdf surface: $status";
+ die;
+ }
+
+0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]