pub struct PdfDocumentReference { /* private fields */ }
Expand description

Marker struct for a document. Used to make the API a bit nicer. It simply calls PdfDocument functions.

Implementations§

source§

impl PdfDocumentReference

source

pub fn with_title<S>(self, new_title: S) -> Self
where S: Into<String>,

Changes the title on both the document info dictionary as well as the metadata

source

pub fn with_author<S>(self, author: S) -> Self
where S: Into<String>,

Changes the author metadata property on both the document info dictionary as well as the metadata

source

pub fn with_creator<S>(self, creator: S) -> Self
where S: Into<String>,

Changes the creator metadata property on both the document info dictionary as well as the metadata

source

pub fn with_producer<S>(self, producer: S) -> Self
where S: Into<String>,

Changes the producer/publisher metadata property on both the document info dictionary as well as the metadata

source

pub fn with_keywords<S>(self, keywords: Vec<S>) -> Self
where S: Into<String>,

Changes the keywords metadata property on both the document info dictionary as well as the metadata

source

pub fn with_subject<S>(self, subject: S) -> Self
where S: Into<String>,

Changes the subject metadata property on both the document info dictionary as well as the metadata

source

pub fn with_identifier<S>(self, identifier: S) -> Self
where S: Into<String>,

Changes the subject metadata property on both the document info dictionary as well as the metadata

source

pub fn with_trapping(self, trapping: bool) -> Self

Set the trapping of the document

source

pub fn with_document_id(self, id: String) -> Self

Sets the document ID (for comparing two PDF documents for equality)

source

pub fn with_document_version(self, version: u32) -> Self

Set the version of the document

source

pub fn with_conformance(self, conformance: PdfConformance) -> Self

Changes the conformance of this document. It is recommended to call check_for_errors() after changing it.

Examples found in repository?
examples/no_icc.rs (lines 17-21)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
fn main() {
    // This code creates the most minimal PDF file with 1.2 KB
    // Currently, fonts need to use an embedded font, so if you need to write something, the file size
    // will still be bloated (because of the embedded font)
    // Also, OCG content is still enabled, even if you disable it here.
    let (mut doc, _page1, _layer1) =
        PdfDocument::new("printpdf no_icc test", Mm(297.0), Mm(210.0), "Layer 1");
    doc = doc.with_conformance(PdfConformance::Custom(CustomPdfConformance {
        requires_icc_profile: false,
        requires_xmp_metadata: false,
        ..Default::default()
    }));

    doc.save(&mut BufWriter::new(
        File::create("test_no_icc.pdf").unwrap(),
    ))
    .unwrap();
}
source

pub fn with_creation_date(self, creation_date: OffsetDateTime) -> Self

Sets the creation date on the document.

Per default, the creation date is set to the current time.

source

pub fn with_metadata_date(self, metadata_date: OffsetDateTime) -> Self

Sets the metadata date on the document.

By default, the metadata date is set to the current time.

source

pub fn with_mod_date(self, mod_date: OffsetDateTime) -> Self

Sets the modification date on the document. Intended to be used when reading documents that already have a modification date.

source

pub fn add_page<S>( &self, x_mm: Mm, y_mm: Mm, inital_layer_name: S ) -> (PdfPageIndex, PdfLayerIndex)
where S: Into<String>,

Create a new pdf page and returns the index of the page

Examples found in repository?
examples/bookmark.rs (line 11)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
fn main() {
    let (doc, page1, _) = PdfDocument::new("printpdf page test", Mm(210.0), Mm(297.0), "Layer 1");
    doc.add_bookmark("This is a bookmark", page1);

    let (page2, _) = doc.add_page(Mm(297.0), Mm(210.0), "Page 2, Layer 1");
    let _ = doc.get_page(page2).add_layer("Layer 3");
    doc.add_bookmark("This is another bookmark", page2);

    // If this is successful, you should see a PDF with two blank A4 pages and 2 bookmarks
    doc.save(&mut BufWriter::new(
        File::create("test_bookmark.pdf").unwrap(),
    ))
    .unwrap();
}
More examples
Hide additional examples
examples/page.rs (line 15)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
fn main() {
    // To prevent empty documents, you must specify at least one page with one layer
    // You can later on add more pages with the add_page() function
    // You also have to specify the title of the PDF and the document creator
    let (doc, _, _) = PdfDocument::new("printpdf page test", Mm(210.0), Mm(297.0), "Layer 1");

    // You can add more pages and layers to the PDF.
    // Just make sure you don't lose the references, otherwise, you can't add things to the layer anymore
    let (page2, _) = doc.add_page(Mm(297.0), Mm(210.0), "Page 2, Layer 1");
    let _ = doc.get_page(page2).add_layer("Layer 3");

    // If this is successful, you should see a PDF with two blank A4 pages
    doc.save(&mut BufWriter::new(File::create("test_pages.pdf").unwrap()))
        .unwrap();
}
source

pub fn add_bookmark<S>(&self, name: S, page: PdfPageIndex)
where S: Into<String>,

Create a new pdf page and returns the index of the page. If the page already has a bookmark, overwrites it.

Examples found in repository?
examples/bookmark.rs (line 9)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
fn main() {
    let (doc, page1, _) = PdfDocument::new("printpdf page test", Mm(210.0), Mm(297.0), "Layer 1");
    doc.add_bookmark("This is a bookmark", page1);

    let (page2, _) = doc.add_page(Mm(297.0), Mm(210.0), "Page 2, Layer 1");
    let _ = doc.get_page(page2).add_layer("Layer 3");
    doc.add_bookmark("This is another bookmark", page2);

    // If this is successful, you should see a PDF with two blank A4 pages and 2 bookmarks
    doc.save(&mut BufWriter::new(
        File::create("test_bookmark.pdf").unwrap(),
    ))
    .unwrap();
}
source

pub fn add_external_font<R>( &self, font_stream: R ) -> Result<IndirectFontRef, Error>
where R: Read,

Add a font from a font stream

Examples found in repository?
examples/rect.rs (line 25)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf rect test", Mm(210.0), Mm(297.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    let rect = Rect::new(Mm(30.), Mm(250.), Mm(200.), Mm(290.));

    current_layer.add_rect(rect);

    let rect = Rect::new(Mm(50.), Mm(180.), Mm(120.), Mm(290.))
        .with_mode(PaintMode::Clip)
        .with_winding(WindingOrder::EvenOdd);

    current_layer.add_rect(rect);

    let mut font_reader =
        std::io::Cursor::new(include_bytes!("../assets/fonts/RobotoMedium.ttf").as_ref());
    let font = doc.add_external_font(&mut font_reader).unwrap();

    current_layer.use_text("hello world", 100.0, Mm(10.0), Mm(200.0), &font);
    doc.save(&mut BufWriter::new(File::create("test_rect.pdf").unwrap()))
        .unwrap();
}
More examples
Hide additional examples
examples/font.rs (line 17)
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("PDF_Document_title", Mm(500.0), Mm(300.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    let text = "Lorem ipsum";
    let text2 = "dolor sit amet";

    let mut font_reader =
        std::io::Cursor::new(include_bytes!("../assets/fonts/RobotoMedium.ttf").as_ref());

    let font = doc.add_external_font(&mut font_reader).unwrap();

    // `use_text` is a wrapper around making a simple string
    current_layer.use_text(text, 48.0, Mm(10.0), Mm(200.0), &font);

    // text fill color = blue
    let blue = Rgb::new(13.0 / 256.0, 71.0 / 256.0, 161.0 / 256.0, None);
    let orange = Rgb::new(244.0 / 256.0, 67.0 / 256.0, 54.0 / 256.0, None);
    current_layer.set_fill_color(Color::Rgb(blue));
    current_layer.set_outline_color(Color::Rgb(orange));

    // For more complex layout of text, you can use functions
    // defined on the PdfLayerReference
    // Make sure to wrap your commands
    // in a `begin_text_section()` and `end_text_section()` wrapper
    current_layer.begin_text_section();

    // setup the general fonts.
    // see the docs for these functions for details
    current_layer.set_font(&font, 33.0);
    current_layer.set_text_cursor(Mm(10.0), Mm(100.0));
    current_layer.set_line_height(33.0);
    current_layer.set_word_spacing(3000.0);
    current_layer.set_character_spacing(10.0);

    // write two lines (one line break)
    current_layer.write_text(text, &font);
    current_layer.add_line_break();
    current_layer.write_text(text2, &font);
    current_layer.add_line_break();

    current_layer.set_text_rendering_mode(TextRenderingMode::FillStroke);
    current_layer.set_character_spacing(0.0);
    current_layer.set_text_matrix(TextMatrix::Rotate(10.0));

    // write one line, but write text2 in superscript
    current_layer.write_text(text, &font);
    current_layer.set_line_offset(10.0);
    current_layer.set_text_rendering_mode(TextRenderingMode::Stroke);
    current_layer.set_font(&font, 18.0);
    current_layer.write_text(text2, &font);

    current_layer.end_text_section();

    // Use text from a built-in font (no external resource needed)
    let text = "Lorem ipsum";
    let font = doc.add_builtin_font(BuiltinFont::TimesBoldItalic).unwrap();
    current_layer.use_text(text, 48.0, Mm(10.0), Mm(200.0), &font);

    doc.save(&mut BufWriter::new(File::create("test_fonts.pdf").unwrap()))
        .unwrap();
}
source

pub fn add_external_font_with_subsetting<R>( &self, font_stream: R, allow_subsetting: bool ) -> Result<IndirectFontRef, Error>
where R: Read,

Add a font from a font stream and set the whether or not to allow subsetting the font

source

pub fn add_external_font_data<F>( &self, bytes: Vec<u8>, data: F ) -> Result<IndirectFontRef, Error>
where F: FontData + 'static,

Add a font from a custom font backend

source

pub fn add_external_font_data_with_subsetting<F>( &self, bytes: Vec<u8>, data: F, allow_subsetting: bool ) -> Result<IndirectFontRef, Error>
where F: FontData + 'static,

Add a font from a custom font backend and set the whether or not to allow subsetting the font

source

pub fn add_builtin_font( &self, builtin_font: BuiltinFont ) -> Result<IndirectFontRef, Error>

Add a built-in font to the document

Built-in fonts can only be used to print characters that are supported by the Windows-1252 encoding. All other characters will be ignored.

Examples found in repository?
examples/hyperlink.rs (line 13)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(595.276), Mm(841.89), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    let text = "Lorem ipsum";
    let font = doc.add_builtin_font(BuiltinFont::TimesBoldItalic).unwrap();
    current_layer.use_text(text, 48.0, Mm(10.0), Mm(200.0), &font);

    current_layer.add_link_annotation(LinkAnnotation::new(
        printpdf::Rect::new(Mm(10.0), Mm(200.0), Mm(100.0), Mm(212.0)),
        Some(printpdf::BorderArray::default()),
        Some(printpdf::ColorArray::default()),
        printpdf::Actions::uri("https://www.google.com/".to_string()),
        Some(printpdf::HighlightingMode::Invert),
    ));

    doc.save(&mut BufWriter::new(
        File::create("test_hyperlink.pdf").unwrap(),
    ))
    .unwrap();
}
More examples
Hide additional examples
examples/annotations.rs (line 41)
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(210.0), Mm(297.0), "Layer 1");
    let page = doc.get_page(page1);
    let current_layer = page.get_layer(layer1);

    let action = Dictionary::from_iter(vec![
      ("Type", "Action".into()),
      ("S", Object::Name(b"URI".to_vec())),
      ("URI", Object::String(b"https://github.com/fschutt/printpdf".to_vec(), Literal)),
    ]);

    let annotation = Dictionary::from_iter(vec![
        ("Type", "Annot".into()),
        ("Subtype", Object::Name(b"Link".to_vec())),
        ("Rect", vec![20.into(), 580.into(), 300.into(), 560.into()].into()),
        ("C", vec![].into()),
        ("Contents", Object::String("Hello World".into(), Literal)),
        ("A", action.into()),
    ]);

    let annotations = Dictionary::from_iter(vec![
        ("Annots", Object::Array(vec![annotation.into()]))
    ]);

    page.extend_with(annotations);

    let text = "There's an invisible annotation with a link covering this text.";
    let font = doc.add_builtin_font(BuiltinFont::Helvetica).unwrap();
    current_layer.use_text(text, 10.0, Mm(10.0), Mm(200.0), &font);

    doc.save(&mut BufWriter::new(File::create("test_annotations.pdf").unwrap()))
        .unwrap();
}
examples/font.rs (line 63)
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("PDF_Document_title", Mm(500.0), Mm(300.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    let text = "Lorem ipsum";
    let text2 = "dolor sit amet";

    let mut font_reader =
        std::io::Cursor::new(include_bytes!("../assets/fonts/RobotoMedium.ttf").as_ref());

    let font = doc.add_external_font(&mut font_reader).unwrap();

    // `use_text` is a wrapper around making a simple string
    current_layer.use_text(text, 48.0, Mm(10.0), Mm(200.0), &font);

    // text fill color = blue
    let blue = Rgb::new(13.0 / 256.0, 71.0 / 256.0, 161.0 / 256.0, None);
    let orange = Rgb::new(244.0 / 256.0, 67.0 / 256.0, 54.0 / 256.0, None);
    current_layer.set_fill_color(Color::Rgb(blue));
    current_layer.set_outline_color(Color::Rgb(orange));

    // For more complex layout of text, you can use functions
    // defined on the PdfLayerReference
    // Make sure to wrap your commands
    // in a `begin_text_section()` and `end_text_section()` wrapper
    current_layer.begin_text_section();

    // setup the general fonts.
    // see the docs for these functions for details
    current_layer.set_font(&font, 33.0);
    current_layer.set_text_cursor(Mm(10.0), Mm(100.0));
    current_layer.set_line_height(33.0);
    current_layer.set_word_spacing(3000.0);
    current_layer.set_character_spacing(10.0);

    // write two lines (one line break)
    current_layer.write_text(text, &font);
    current_layer.add_line_break();
    current_layer.write_text(text2, &font);
    current_layer.add_line_break();

    current_layer.set_text_rendering_mode(TextRenderingMode::FillStroke);
    current_layer.set_character_spacing(0.0);
    current_layer.set_text_matrix(TextMatrix::Rotate(10.0));

    // write one line, but write text2 in superscript
    current_layer.write_text(text, &font);
    current_layer.set_line_offset(10.0);
    current_layer.set_text_rendering_mode(TextRenderingMode::Stroke);
    current_layer.set_font(&font, 18.0);
    current_layer.write_text(text2, &font);

    current_layer.end_text_section();

    // Use text from a built-in font (no external resource needed)
    let text = "Lorem ipsum";
    let font = doc.add_builtin_font(BuiltinFont::TimesBoldItalic).unwrap();
    current_layer.use_text(text, 48.0, Mm(10.0), Mm(200.0), &font);

    doc.save(&mut BufWriter::new(File::create("test_fonts.pdf").unwrap()))
        .unwrap();
}
source

pub fn get_page(&self, page: PdfPageIndex) -> PdfPageReference

Returns the page (for inserting content)

Examples found in repository?
examples/bookmark.rs (line 12)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
fn main() {
    let (doc, page1, _) = PdfDocument::new("printpdf page test", Mm(210.0), Mm(297.0), "Layer 1");
    doc.add_bookmark("This is a bookmark", page1);

    let (page2, _) = doc.add_page(Mm(297.0), Mm(210.0), "Page 2, Layer 1");
    let _ = doc.get_page(page2).add_layer("Layer 3");
    doc.add_bookmark("This is another bookmark", page2);

    // If this is successful, you should see a PDF with two blank A4 pages and 2 bookmarks
    doc.save(&mut BufWriter::new(
        File::create("test_bookmark.pdf").unwrap(),
    ))
    .unwrap();
}
More examples
Hide additional examples
examples/page.rs (line 16)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
fn main() {
    // To prevent empty documents, you must specify at least one page with one layer
    // You can later on add more pages with the add_page() function
    // You also have to specify the title of the PDF and the document creator
    let (doc, _, _) = PdfDocument::new("printpdf page test", Mm(210.0), Mm(297.0), "Layer 1");

    // You can add more pages and layers to the PDF.
    // Just make sure you don't lose the references, otherwise, you can't add things to the layer anymore
    let (page2, _) = doc.add_page(Mm(297.0), Mm(210.0), "Page 2, Layer 1");
    let _ = doc.get_page(page2).add_layer("Layer 3");

    // If this is successful, you should see a PDF with two blank A4 pages
    doc.save(&mut BufWriter::new(File::create("test_pages.pdf").unwrap()))
        .unwrap();
}
examples/rect.rs (line 11)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf rect test", Mm(210.0), Mm(297.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    let rect = Rect::new(Mm(30.), Mm(250.), Mm(200.), Mm(290.));

    current_layer.add_rect(rect);

    let rect = Rect::new(Mm(50.), Mm(180.), Mm(120.), Mm(290.))
        .with_mode(PaintMode::Clip)
        .with_winding(WindingOrder::EvenOdd);

    current_layer.add_rect(rect);

    let mut font_reader =
        std::io::Cursor::new(include_bytes!("../assets/fonts/RobotoMedium.ttf").as_ref());
    let font = doc.add_external_font(&mut font_reader).unwrap();

    current_layer.use_text("hello world", 100.0, Mm(10.0), Mm(200.0), &font);
    doc.save(&mut BufWriter::new(File::create("test_rect.pdf").unwrap()))
        .unwrap();
}
examples/hyperlink.rs (line 10)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(595.276), Mm(841.89), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    let text = "Lorem ipsum";
    let font = doc.add_builtin_font(BuiltinFont::TimesBoldItalic).unwrap();
    current_layer.use_text(text, 48.0, Mm(10.0), Mm(200.0), &font);

    current_layer.add_link_annotation(LinkAnnotation::new(
        printpdf::Rect::new(Mm(10.0), Mm(200.0), Mm(100.0), Mm(212.0)),
        Some(printpdf::BorderArray::default()),
        Some(printpdf::ColorArray::default()),
        printpdf::Actions::uri("https://www.google.com/".to_string()),
        Some(printpdf::HighlightingMode::Invert),
    ));

    doc.save(&mut BufWriter::new(
        File::create("test_hyperlink.pdf").unwrap(),
    ))
    .unwrap();
}
examples/svg.rs (line 11)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(210.0), Mm(297.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);
    let svg = Svg::parse(SVG).unwrap();

    let rotation_center_x = Px((svg.width.0 as f32 / 2.0) as usize);
    let rotation_center_y = Px((svg.height.0 as f32 / 2.0) as usize);

    let reference = svg.into_xobject(&current_layer);

    for i in 0..10 {
        reference.clone().add_to_layer(
            &current_layer,
            SvgTransform {
                rotate: Some(SvgRotation {
                    angle_ccw_degrees: i as f32 * 36.0,
                    rotation_center_x: rotation_center_x.into_pt(300.0),
                    rotation_center_y: rotation_center_y.into_pt(300.0),
                }),
                translate_x: Some(Mm(i as f32 * 20.0 % 50.0).into()),
                translate_y: Some(Mm(i as f32 * 30.0).into()),
                ..Default::default()
            },
        );
    }

    let pdf_bytes = doc.save_to_bytes().unwrap();
    std::fs::write("test_svg.pdf", &pdf_bytes).unwrap();
}
examples/circle.rs (line 11)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf circle test", Mm(210.0), Mm(297.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    let radius_1 = Pt(40.0);
    let radius_2 = Pt(30.0);
    let offset_x = Pt(10.0);
    let offset_y = Pt(50.0);

    let line = Polygon {
        rings: vec![
            calculate_points_for_circle(radius_1, offset_x, offset_y),
            calculate_points_for_circle(radius_2, offset_x, offset_y), // hole
        ],
        mode: PaintMode::FillStroke,
        winding_order: WindingOrder::EvenOdd,
    };

    current_layer.add_polygon(line);

    let scale_x_rect = Pt(40.0);
    let scale_y_rect = Pt(10.0);
    let offset_x_rect = Pt(20.0);
    let offset_y_rect = Pt(5.0);

    let line = Polygon {
        rings: vec![calculate_points_for_rect(
            scale_x_rect,
            scale_y_rect,
            offset_x_rect,
            offset_y_rect,
        )],
        mode: PaintMode::FillStroke,
        winding_order: WindingOrder::NonZero,
    };

    current_layer.add_polygon(line);

    doc.save(&mut BufWriter::new(
        File::create("test_circle.pdf").unwrap(),
    ))
    .unwrap();
}
source

pub fn get_font(&self, font: &IndirectFontRef) -> Option<DirectFontRef>

Returns a direct reference (object ID) to the font from an indirect reference (postscript name)

source

pub unsafe fn get_inner(self) -> Document

Drops the PDFDocument, returning the inner lopdf::Document.

§Safety

Document may be only half-written, use only in extreme cases

source

pub fn check_for_errors(&self) -> Result<(), Error>

Checks for invalid settings in the document

source

pub fn repair_errors(&self, _conformance: PdfConformance) -> Result<(), Error>

Tries to match the document to the given conformance. Errors only on an unrecoverable error.

source

pub fn save_to_bytes(self) -> Result<Vec<u8>, Error>

Save PDF document to bytes

Examples found in repository?
examples/svg.rs (line 35)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(210.0), Mm(297.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);
    let svg = Svg::parse(SVG).unwrap();

    let rotation_center_x = Px((svg.width.0 as f32 / 2.0) as usize);
    let rotation_center_y = Px((svg.height.0 as f32 / 2.0) as usize);

    let reference = svg.into_xobject(&current_layer);

    for i in 0..10 {
        reference.clone().add_to_layer(
            &current_layer,
            SvgTransform {
                rotate: Some(SvgRotation {
                    angle_ccw_degrees: i as f32 * 36.0,
                    rotation_center_x: rotation_center_x.into_pt(300.0),
                    rotation_center_y: rotation_center_y.into_pt(300.0),
                }),
                translate_x: Some(Mm(i as f32 * 20.0 % 50.0).into()),
                translate_y: Some(Mm(i as f32 * 30.0).into()),
                ..Default::default()
            },
        );
    }

    let pdf_bytes = doc.save_to_bytes().unwrap();
    std::fs::write("test_svg.pdf", &pdf_bytes).unwrap();
}
source

pub fn save<W: Write>(self, target: &mut BufWriter<W>) -> Result<(), Error>

Save PDF Document, writing the contents to the target

Examples found in repository?
examples/bookmark.rs (lines 16-18)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
fn main() {
    let (doc, page1, _) = PdfDocument::new("printpdf page test", Mm(210.0), Mm(297.0), "Layer 1");
    doc.add_bookmark("This is a bookmark", page1);

    let (page2, _) = doc.add_page(Mm(297.0), Mm(210.0), "Page 2, Layer 1");
    let _ = doc.get_page(page2).add_layer("Layer 3");
    doc.add_bookmark("This is another bookmark", page2);

    // If this is successful, you should see a PDF with two blank A4 pages and 2 bookmarks
    doc.save(&mut BufWriter::new(
        File::create("test_bookmark.pdf").unwrap(),
    ))
    .unwrap();
}
More examples
Hide additional examples
examples/no_icc.rs (lines 23-25)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
fn main() {
    // This code creates the most minimal PDF file with 1.2 KB
    // Currently, fonts need to use an embedded font, so if you need to write something, the file size
    // will still be bloated (because of the embedded font)
    // Also, OCG content is still enabled, even if you disable it here.
    let (mut doc, _page1, _layer1) =
        PdfDocument::new("printpdf no_icc test", Mm(297.0), Mm(210.0), "Layer 1");
    doc = doc.with_conformance(PdfConformance::Custom(CustomPdfConformance {
        requires_icc_profile: false,
        requires_xmp_metadata: false,
        ..Default::default()
    }));

    doc.save(&mut BufWriter::new(
        File::create("test_no_icc.pdf").unwrap(),
    ))
    .unwrap();
}
examples/page.rs (line 19)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
fn main() {
    // To prevent empty documents, you must specify at least one page with one layer
    // You can later on add more pages with the add_page() function
    // You also have to specify the title of the PDF and the document creator
    let (doc, _, _) = PdfDocument::new("printpdf page test", Mm(210.0), Mm(297.0), "Layer 1");

    // You can add more pages and layers to the PDF.
    // Just make sure you don't lose the references, otherwise, you can't add things to the layer anymore
    let (page2, _) = doc.add_page(Mm(297.0), Mm(210.0), "Page 2, Layer 1");
    let _ = doc.get_page(page2).add_layer("Layer 3");

    // If this is successful, you should see a PDF with two blank A4 pages
    doc.save(&mut BufWriter::new(File::create("test_pages.pdf").unwrap()))
        .unwrap();
}
examples/rect.rs (line 28)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf rect test", Mm(210.0), Mm(297.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    let rect = Rect::new(Mm(30.), Mm(250.), Mm(200.), Mm(290.));

    current_layer.add_rect(rect);

    let rect = Rect::new(Mm(50.), Mm(180.), Mm(120.), Mm(290.))
        .with_mode(PaintMode::Clip)
        .with_winding(WindingOrder::EvenOdd);

    current_layer.add_rect(rect);

    let mut font_reader =
        std::io::Cursor::new(include_bytes!("../assets/fonts/RobotoMedium.ttf").as_ref());
    let font = doc.add_external_font(&mut font_reader).unwrap();

    current_layer.use_text("hello world", 100.0, Mm(10.0), Mm(200.0), &font);
    doc.save(&mut BufWriter::new(File::create("test_rect.pdf").unwrap()))
        .unwrap();
}
examples/hyperlink.rs (lines 24-26)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(595.276), Mm(841.89), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    let text = "Lorem ipsum";
    let font = doc.add_builtin_font(BuiltinFont::TimesBoldItalic).unwrap();
    current_layer.use_text(text, 48.0, Mm(10.0), Mm(200.0), &font);

    current_layer.add_link_annotation(LinkAnnotation::new(
        printpdf::Rect::new(Mm(10.0), Mm(200.0), Mm(100.0), Mm(212.0)),
        Some(printpdf::BorderArray::default()),
        Some(printpdf::ColorArray::default()),
        printpdf::Actions::uri("https://www.google.com/".to_string()),
        Some(printpdf::HighlightingMode::Invert),
    ));

    doc.save(&mut BufWriter::new(
        File::create("test_hyperlink.pdf").unwrap(),
    ))
    .unwrap();
}
examples/circle.rs (lines 47-49)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf circle test", Mm(210.0), Mm(297.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    let radius_1 = Pt(40.0);
    let radius_2 = Pt(30.0);
    let offset_x = Pt(10.0);
    let offset_y = Pt(50.0);

    let line = Polygon {
        rings: vec![
            calculate_points_for_circle(radius_1, offset_x, offset_y),
            calculate_points_for_circle(radius_2, offset_x, offset_y), // hole
        ],
        mode: PaintMode::FillStroke,
        winding_order: WindingOrder::EvenOdd,
    };

    current_layer.add_polygon(line);

    let scale_x_rect = Pt(40.0);
    let scale_y_rect = Pt(10.0);
    let offset_x_rect = Pt(20.0);
    let offset_y_rect = Pt(5.0);

    let line = Polygon {
        rings: vec![calculate_points_for_rect(
            scale_x_rect,
            scale_y_rect,
            offset_x_rect,
            offset_y_rect,
        )],
        mode: PaintMode::FillStroke,
        winding_order: WindingOrder::NonZero,
    };

    current_layer.add_polygon(line);

    doc.save(&mut BufWriter::new(
        File::create("test_circle.pdf").unwrap(),
    ))
    .unwrap();
}

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> Finish for T

source§

fn finish(self)

Does nothing but move self, equivalent to drop.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> Pointable for T

§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.