http://qs321.pair.com?node_id=1212564

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello all,

I have the sample code below to print a line of plain text and a second of text over a filled rectangle:
use PDF::API2; my $pdf = PDF::API2->new(); my $page = $pdf->page(); my $text = $page->text(); my $font = $pdf->corefont('Helvetica-Roman'); $text->font($font, 16); $text->translate(50, 620); $text->text('Print some text'); $text->rect(50, 560, 400, 18); $text->fillcolor('#000000'); $text->fill(); $text->fillcolor('#ffffff'); $text->translate(62, 565); $text->text('Print text in rect'); $pdf->saveas('test.pdf');
When I view 'test.pdf' on my computer, I have the two lines of text correctly displayed as expected.

But when I try to view test.pdf on my android phone using a pdf viewer that I installed from Google Play (Adobe Acrobat Reader version 18.1 with 100 million downloads), only the plain text line is displayed but not the text over rect box.

Is there anything wrong with my code?

I'm at my wits' end.

Replies are listed 'Best First'.
Re: PDF API2 rect fill not displayed in android pdf viewer
by vr (Curate) on Apr 09, 2018 at 13:00 UTC

    There's no "Helvetica-Roman" in core, your code dies on me in both question and solution. The latter, while moves in right direction, produces white text below the black rectangle, are you sure it's what you want?

    Because, each invocation of either "text" or "gfx" methods of page object appends a chunk of content to content array, and you still add text to 0-th content array element, regardless of this being in the end of your program.

    To original problem: the PDF spec says, that inside "text objects" (fragments of content stream bracketed between BT and ET keywords) you can only use either text-related or general graphics state related operators. I.e., drawing graphics is not allowed while inside a "text object". Some viewers/interpreters may be more forgiving, but such PDF is still broken.

    Just, add text to content object, returned by "text" method of a page. And add graphics to content object returned by "gfx" method of a page. Then the correct BT-ET frames will be handled for you automatically.

    use strict; use warnings; use PDF::API2; my $pdf = PDF::API2-> new; my $page = $pdf-> page; my $font = $pdf-> corefont( 'Helvetica' ); my $content = $page-> text; $content-> font( $font, 16 ); $content-> fillcolor( '#000000' ); $content-> translate( 50, 620 ); $content-> text( 'Print some text' ); $content = $page-> gfx; $content-> rect( 50, 560, 400, 18 ); $content-> fillcolor( '#000000' ); $content-> fill; $content = $page-> text; $content-> font( $font, 16 ); $content-> fillcolor( '#ffffff' ); $content-> translate( 62, 565 ); $content-> text( 'Print text in rect' ); $pdf-> saveas( 'test.pdf' );
      Many thanks for your correction and your example code! Using $content makes so much sense.

      You make my day :)))
Re: PDF API2 rect fill not displayed in android pdf viewer
by Anonymous Monk on Apr 09, 2018 at 12:33 UTC
    ***SOLVED***

    My original code used the text method to draw the rectangle. It so happened that most browsers and some pdf viewers do not see this as a problem and render the line of text and the text over the rectangle (as desired). But apparently other pdf viewers are less forgiving of this.
    use PDF::API2; my $pdf = PDF::API2->new(); my $page = $pdf->page(); my $text = $page->text(); my $font = $pdf->corefont('Helvetica-Roman'); $text->font($font, 16); $text->translate(50, 620); $text->text('Print some text'); # define rect with gfx my $rect = $page->gfx; $rect->rect(50, 560, 400, 18); $rect->fillcolor('#000000'); $rect->fill(); # Go back to text $text->fillcolor('#ffffff'); $text->translate(62, 565); $text->text('Print text in rect'); $pdf->saveas('test.pdf');