Help language development. Donate to The Perl Foundation

PDF::Content cpan:WARRINGD last updated on 2021-10-12


[Raku PDF Project] / PDF::Content

Actions Status


This Raku module is a library of roles and classes for basic PDF content creation and rendering, including text, images, basic colors, core fonts, marked content and general graphics.

It is centered around implementing a graphics state machine and provding support for the operators and graphics variables as listed in the PDF::API6 Graphics Documentation.

Key roles and classes:


implements a PDF graphics state machine for composition, or rendering:

use lib 't';
use PDF::Content;
use PDF::Content::Canvas;
use PDFTiny;
my PDF::Content::Canvas $canvas =;
my PDF::Content $gfx .= new: :$canvas;
$gfx.use-font: $gfx.core-font('Courier'); # define /F1 font
$gfx.Font = 'F1', 16;
$gfx.TextMove(10, 20);
$gfx.ShowText('Hello World');
say $gfx.Str;
# BT
#  /F1 16 Tf
#  10 20 Td
#  (Hello World) Tj
# ET


handles the loading of some common image formats

It currently supports: PNG, GIF and JPEG.

use PDF::Content::XObject;
my PDF::Content::XObject $image .= open: "t/images/lightbulb.gif";
say "image has size {$image.width} X {$image.height}";
say $;
# data:image/gif;base64,R0lGODlhEwATAMQA...


provides simple support for core fonts

use PDF::Content::Font::CoreFont;
my PDF::Content::Font::CoreFont $font .= load-font( :family<Times-Roman>, :weight<bold> );
say $font.encode("¶Hi");
say $font.stringwidth("RVX"); # 2166
say $font.stringwidth("RVX", :kern); # 2111


a utility class for creating boxed text content for output by print() or say():

use lib 't';
use PDFTiny;
my $page =;
use PDF::Content;
use PDF::Content::Font::CoreFont;
use PDF::Content::Text::Block;
my PDF::Content::Font::CoreFont $font .= load-font( :family<helvetica>, :weight<bold> );
my $text = "Hello.  Ting, ting-ting. Attention! … ATTENTION! ";
my PDF::Content::Text::Box $text-box .= new( :$text, :$font, :font-size(16) );
my PDF::Content $gfx = $page.gfx;
say $gfx.Str;


Simple Color construction functions:

use lib 't';
use PDFTiny;
my $page =;
use PDF::Content;
use PDF::Content::Color :color, :ColorName;
my PDF::Content $gfx = $page.gfx;
$gfx.FillColor = color Blue; # named color
$gfx.StrokeColor = color '#fa9'; # RGB mask, 3 digit
$gfx.StrokeColor = color '#ffaa99'; # RGB mask, 6 digit
$gfx.StrokeColor = color [1, .8, .1, .2]; # CMYK color values (0..1)
$gfx.StrokeColor = color [1, .5, .1];     # RGB color values (0..1)
$gfx.StrokeColor = color [255, 127, 25];  # RGB color values (0..255)
$gfx.StrokeColor = color .7; # Shade of gray
use Color;
my Color $red .= new(0xff, 0x0a, 0x0a);
$gfx.StrokeColor = color $red; # Color objects


This class assists in the detection or construction of marked content in page or xobject form content streams:

use lib 't';
use PDFTiny;
use PDF::Content::XObject;
use PDF::Content::Tag :ParagraphTags, :IllustrationTags;

my PDFTiny $pdf .= new;

my $page = $pdf.add-page;
my $header-font = $page.core-font: :family<Helvetica>, :weight<bold>;
my $body-font = $page.core-font: :family<Helvetica>;

$ -> $gfx {
    my PDF::Content::Tag $tag;

    $tag = $gfx.mark: Header1, {
        .say('Header text',
             :position[50, 120]);

    say $; # 'H1'
    say $tag.mcid;     # marked content id of 0

    $tag = $gfx.mark: Paragraph, {
        .say('Paragraph that contains a figure', :position[50, 100], :font($body-font), :font-size(12));

        # nested tag. Note: marks cannot be nested, but tags can
        .tag: Figure, {
            my PDF::Content::XObject $img .= open: "t/images/lightbulb.gif";
            .do: $img, :position[50,70];


    say $;         # 'P'
    say $tag.mcid;             # marked content id of 1
    say $[0].name.Str; # 'Figure'

say $page.gfx.tags.gist; # '<H1 MCID="0"/><P MCID="1"><Figure/></P>';

See Also