Crate rckive_genpdf
source ·Expand description
User-friendly PDF generator written in pure Rust.
rckive_genpdf
is a high-level PDF generator built ontop of printpdf
and rusttype
. It
takes care of the page layout and text alignment and renders a document tree into a PDF
document. All of its dependencies are written in Rust, so you don’t need any pre-installed
libraries or tools.
Quickstart
To generate a PDF document, create an instance of the Document
struct and add
Element
implementations to it. Then call the Document::render_to_file
method to
render the document and to write it to a file.
// Load a font from the file system
let font_family = rckive_genpdf::fonts::from_files("./fonts", "LiberationSans", None)
.expect("Failed to load font family");
// Create a document and set the default font family
let mut doc = rckive_genpdf::Document::new(font_family);
// Change the default settings
doc.set_title("Demo document");
// Customize the pages
let mut decorator = rckive_genpdf::SimplePageDecorator::new();
decorator.set_margins(10);
doc.set_page_decorator(decorator);
// Add one or more elements
doc.push(rckive_genpdf::elements::Paragraph::new("This is a demo document."));
// Render the document and write it to a file
doc.render_to_file("output.pdf").expect("Failed to write PDF file");
For a complete example with all supported elements, see the examples/demo.rs
file that
generates this PDF document.
Overview
A Document
consists of a LinearLayout
that renders the added elements, a
FontCache
instance that keeps track of the loaded fonts and a collection of default
values for the text style and the page layout.
When creating a Document
instance, you always have to set the default font family that
will be used for the document. You can load additional fonts with the
Document::load_font_family
method.
The style of a shape or text can be set using the Style
struct. The style is inherited
within the document tree. You can set the style of an element by wrapping it in a
StyledElement
(see the Element::styled
method) or – for text elements – with a
StyledString
.
For an overview of the available elements, see the elements
module. You can also
create custom elements by implementing the Element
trait.
The actual PDF document is generated from the elements that have been added to the document
once you call the Document::render
or Document::render_to_file
methods. For
details on the rendering process, see the next section.
In rckive_genpdf
, all lengths are measured in millimeters. The only exceptions are font sizes that
are measured in points. The Mm
newtype struct is used for all lengths, and the
Position
and Size
types are used to describe points and rectangles in the PDF
document.
Rendering Process
The rendering process is started by calling the Document::render
or
Document::render_to_file
methods. You can only render a document once. Before the
rendering starts, the PDF document is created and all loaded fonts are embedded into the
document.
The elements are then rendered by calling the Element::render
method of the root element,
a LinearLayout
. This element will then call the render
methods of the elements stored
in the layout, and so on.
The Element::render
method receives the following arguments:
- context is the context for the rendering process, see
Context
. Currently, it only stores theFontCache
instance that keeps track of the loaded fonts and can be used to map aStyle
instance to font data. - area is a view on the area of the current page that can be used by the element.
- style is the
Style
instance for this element. Is is a combination of the default style of theDocument
and the style set byStyledElement
instances that are parents of the current element.
The render
method tries to render the entire element in the provided area. The returned
RenderResult
stores the size of the area that has actually been used to render the
element. If the element did not fit into the provided area, the has_more
field of the
RenderResult
is set to true
. This causes the Document
to add a new page to the PDF
document and then call the render
method again with an area of the new page. This is
repeated until all elements have been rendered completely, that means until all elements return
a RenderResult
with has_more == false
.
Elements may print to the provided area using the methods of the Area
struct, or by
calling the render
method of other elements, or both.
Every new page is prepared by calling the document’s PageDecorator
(if set). This
decorator can add a margin to the page, print a header, a footer, or perform other tasks.
The render process is cancelled if an Element
returns an error, or if no content has been
rendered to a newly created page. This indicates that an element does not fit on a clear page
and can’t even be rendered partially, so the rendering process is cancelled.
As the Element::render
method is called repeatedly until the complete element has been
rendered, the element has to keep track of the content that has already been rendered. As
there is only one rendering process per document, elements may discard data that has been
rendered and that is no longer needed.
Low-Level Interface
The render
module contains a low-level interface for creating PDF files. It keeps track
of page sizes and layers and has utility methods for easier text and shape rendering. But it
does not provide support for measuring the size of rendered text or for laying out elements.
If possible, you should always try to use rckive_genpdf
’s high-level interface and implement the
Element
trait if you want to customize a document instead of using the low-level
interface directly.
Known Issues
- Currently,
rckive_genpdf
adds all loaded fonts to the PDF document, even if they are not used.printpdf
then adds all available glyphs for these fonts to the document, even if they are not used in the document. This increases the file size by 100–200 KiB per font (500–1000 KiB per font family). Until this is fixed, you can pass the generated file throughps2pdf
to significantly reduce its size. Alternatively, you can use a built-in font if you don’t need any characters that are not supported by the Windows-1252 encoding.
Modules
rckive_genpdf
.