Experimental and under construction!
This is a styling module designed to work with the Raku PDF Tool-chain, including PDF::Class
and PDF::API6
, etc.
It implements some basic CSS styling of PDF components, including pages, forms, images, or text blocks.
use v6;
use PDF::Class;
use PDF::Style::Element;
use CSS::Properties;
use CSS::Units :pt, :ops;
my PDF::Class $pdf .= new;
my $page = $pdf.add-page;
$page.media-box = 0, 0, 350, 140;
# create and output a styled text-block
my CSS::Properties() $css = "font-family:Helvetica; width:250pt; height:80pt; border:1pt dashed green; padding: 5pt; word-spacing:10pt;";
my $text = q:to"--ENOUGH!!--".lines.join: ' ';
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.
--ENOUGH!!--
$css.bottom = 20pt;
$css.left = 20pt;
my $gfx = $page.gfx;
my PDF::Style::Element $text-elem .= element: :$text, :$css, :$gfx;
# display it on the page
.render( .bottom, .left) given $text-elem;
$pdf.save-as: "examples/styled-text.pdf";
Type | Properties |
---|---|
Borders | border-color, border-style ('dotted', 'dashed', 'solid' only), border-width, padding, margin |
Backgrounds | background-color, background-image (url encoded only), background-position, background-repeat |
Sizing | height, max-height, min-height, width, max-width, min-width |
Text | font-family, font-style, font-size, font-kerning, font-stretch, font-weight, color, letter-spacing, line-height, text-align, text-indent, vertical-align ('top', 'center', 'bottom' only), word-spacing |
Positioning | bottom, top, left, right |
Body | size, (also border and background properties: padding, border, margin, background-color, etc) |
Other | opacity |
Elements positions and sizes on a body are calculated from CSS properties top
, right,
bottom,
left,
widthand
height`.
use PDF::Class;
use PDF::Style::Body;
use PDF::Style::Element;
use CSS::Properties;
use CSS::Units :pt, :ops;
use PDF::Content::XObject;
my PDF::Content::XObject $background-image .= open: "t/images/tiny.png";
my CSS::Properties() $css = "background-color: rgb(180,180,250); background-image: url($background-image); opacity: 0.25; width:420pt; height:595pt";
my PDF::Style::Body $body .= new: :$css;
my PDF::Class $pdf .= new;
# Create a page, sized and decorated from the body element
my $page = $body.decorate: $pdf.add-page;
my $gfx = $page.gfx;
# create and lay up some styled elements
my CSS::Properties() $css = "font-family:Helvetica; width:250pt; height:80pt; top:20pt; left:20pt; border: 1pt solid green; padding: 2pt";
my $text = "Text, styled as $css";
my PDF::Style::Element $text-elem = $body.element( :$text, :$css, :gfx );
given $text-elem {
note "text top-left is {.top}pt {.left}pt from page bottom, left corner";
# output the element on the page.
.render(.left, .bottom);
}
# now position an image below the text block,
# after some styling adjustments
$css.border-color = 'red';
$css.border-style = 'dashed';
$css.top +css= ($text-elem.height('padding') + 5)pt;
$css.height = Nil;
my Str $image = "t/images/snoopy-happy-dance.jpg";
given $body.element(:$image, :$css, :$gfx) {
note "image bottom-right is {.bottom}pt {.left}pt from page bottom, left corner";
.render(.left, .bottom);
}
# position from bottom right
$css .= COERCE: "border:2pt dashed green; bottom:5pt; color:blue; font-family:Helvetica; padding:2pt; right:5pt; text-align:right; width:120pt;";
.render(.left, .bottom)
given $body.element( :text("Text styled as $css"), :$css, :$gfx );
$pdf.save-as: "examples/styling.pdf";
# also save as HTML
"t/example.html".IO.spurt: $body.html;
By default, this module uses fontconfig
to
load the most appropriate system font for the current CSS font properties (font-family
, font-style
, font-weight, and
font-stretch`).
CSS @font-face
font descriptors can be used to define a set of fonts to load based on font properties.
use PDF::Style::Body;
use PDF::Style::Element;
use CSS::Font::Descriptor;
use CSS::Properties;
use CSS::Units :pt, :ops;
use PDF::Class;
use PDF::Font::Loader::FontObj;
my CSS::Font::Descriptor() @font-face = q:to<END>;
font-family: "ugly";
src: url("fonts/FreeMono.ttf");
END
my CSS::Properties() $css = "font-family:ugly; height:30pt; width:110pt; position:absolute; top:10pt; left:10pt; right:10pt; border:1pt solid red;";
my PDF::Style::Body $body .= new: :@font-face, :base-url<t/>;
my PDF::Class $pdf .= new;
my $Page = $body.decorate: $pdf.add-page;
my $elem = $body.element( :text("Mono Text"), :$css);
$elem.render: gfx => $Page.gfx;
$pdf.save-as: "/tmp/at-font-face.pdf";
The :tag
option may be used on the element()
method to link the element
into the PDF Structure tree.
Futhermore, the :styler
option may be used on the PDF::Tags root element to inherit styling for the tags, so that the PDF can be both tagged and styled at the
same time.
use PDF::Tags;
use PDF::Tags::Elem;
use PDF::Style::Body;
use PDF::Style::Element;
use CSS::TagSet::TaggedPDF;
use CSS::Properties;
use PDF::Class;
use PDF::Page;
my PDF::Class $pdf .= new;
my PDF::Style::Body $body .= new;
my PDF::Page $page = $body.decorate: $pdf.add-page;
my CSS::TagSet::TaggedPDF $styler .= new;
my PDF::Tags $tags .= create: :$pdf, :$styler;
my PDF::Tags::Elem $doc = $tags.Document;
my $gfx = $page.gfx;
# add tagged/styled header text
my PDF::Tags::Elem $header = $doc.Header1;
my $elem = $body.element: :text("Tagged/Styled PDF Demo"), :tag($header), :$gfx;
note $elem.css; # display:block; font-size:2em; font-weight:bolder; margin-bottom:0.67em; margin-top:0.67em; unicode-bidi:embed;
.render( 10, 750) with $elem;
# add tagged/styled figure image
my PDF::Tags::Elem $figure = $doc.Figure: :Alt("light bulb");
my Str $image = "t/images/snoopy-happy-dance.jpg";
my CSS::Properties() $css = "padding:2px; border:1px dashed red; opacity:0.5";
my $image-elem = $body.element(:$image, :tag($figure), :$css, :$gfx);
.render(10, 550) with $image-elem;
$pdf.save-as: "t/tag-demo.pdf"
- Tags don't yet integrate with CSS Selectors
Property | Notes | To-do |
---|---|---|
border-style | 'dotted', 'dashed', 'solid' | Other styles. |
text-decoration | NYI | |
text-transform | NYI | |
white-space | normal and pre-wrap | Other modes |
vertical-align | 'top', 'center', 'bottom' only | Other modes |
- content
- direction
- display
- font-variant
- empty-cells
- float
- list-style, list-style-image, list-style-position, list-style-type
- outline, outline-width, outline-style, outline-color
- overflow
- unicode-bidi
- table-layout
- text-decoration
- visibility
Fonts:
- font-synthesis
- @font-face
Body
- @top-left-corner, etc
- page-break-before, page-break-after, page-break-inside
CSS Transforms http://dev.w3.org/csswg/css-transforms/#transform
- transform
- transform-origin