pub struct PdfLayerReference {
    pub document: Weak<RefCell<PdfDocument>>,
    pub page: PdfPageIndex,
    pub layer: PdfLayerIndex,
}
Expand description

A “reference” to the current layer, allows for inner mutability but only inside this library

Fields§

§document: Weak<RefCell<PdfDocument>>

A weak reference to the document, for inner mutability

§page: PdfPageIndex

The index of the page this layer is on

§layer: PdfLayerIndex

The index of the layer this layer has (inside the page)

Implementations§

source§

impl PdfLayerReference

source

pub fn add_line(&self, line: Line)

Add a line to the layer. Use closed to indicate whether the line is a closed line Use has_fill to determine if the line should be filled.

Examples found in repository?
examples/shape.rs (line 39)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(400.0), Mm(400.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    // Quadratic shape. The "false" determines if the next (following)
    // point is a bezier handle (for curves)
    // If you want holes, simply reorder the winding of the points to be
    // counterclockwise instead of clockwise.
    let points1 = vec![
        (Point::new(Mm(100.0), Mm(100.0)), false),
        (Point::new(Mm(100.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(100.0)), false),
    ];

    // Is the shape stroked? Is the shape closed? Is the shape filled?
    let line1 = Line {
        points: points1.clone(),
        is_closed: true,
    };

    let outline_color = Color::Rgb(Rgb::new(0.75, 1.0, 0.64, None));
    let dash_pattern = LineDashPattern {
        dash_1: Some(20),
        ..Default::default()
    };

    // Draw first line
    current_layer.set_outline_color(outline_color);
    current_layer.set_outline_thickness(10.0);
    current_layer.add_line(line1);

    // Triangle shape
    // Note: Line is invisible by default, the previous method of
    // constructing a line is recommended!
    let line2 = Polygon {
        rings: vec![vec![
            (Point::new(Mm(150.0), Mm(150.0)), false),
            (Point::new(Mm(150.0), Mm(250.0)), false),
            (Point::new(Mm(350.0), Mm(250.0)), false),
        ]],
        mode: PaintMode::FillStroke,
        winding_order: WindingOrder::NonZero,
    };

    let fill_color_2 = Color::Cmyk(Cmyk::new(0.0, 0.0, 0.0, 0.0, None));
    let outline_color_2 = Color::Greyscale(Greyscale::new(0.45, None));

    // More advanced graphical options
    current_layer.set_overprint_stroke(true);
    current_layer.set_blend_mode(BlendMode::Seperable(SeperableBlendMode::Multiply));
    current_layer.set_line_dash_pattern(dash_pattern);
    current_layer.set_line_cap_style(LineCapStyle::Round);
    current_layer.set_line_join_style(LineJoinStyle::Round);
    current_layer.set_fill_color(fill_color_2);
    current_layer.set_outline_color(outline_color_2);
    current_layer.set_outline_thickness(15.0);

    // draw second line
    current_layer.add_polygon(line2);

    // quad clip - note: FIRST SET THE CLIP, then paint the path
    current_layer.save_graphics_state();
    let line4 = Polygon {
        rings: vec![points1.clone()],
        mode: PaintMode::Clip,
        winding_order: WindingOrder::NonZero,
    };

    current_layer.add_polygon(line4);

    let points5 = vec![
        (Point::new(Mm(150.0), Mm(150.0)), false),
        (Point::new(Mm(150.0), Mm(250.0)), false),
        (Point::new(Mm(350.0), Mm(250.0)), false),
    ];

    let line3 = Line {
        points: points5.clone(),
        is_closed: true,
    };

    let outline_color2 = Color::Rgb(Rgb::new(1.0, 0.75, 0.0, None));
    current_layer.set_line_dash_pattern(LineDashPattern::default());
    current_layer.set_outline_color(outline_color2);
    current_layer.set_outline_thickness(5.0);
    current_layer.add_line(line3);

    current_layer.restore_graphics_state(); // unset clip again for further operations

    // If this is successful, you should see a PDF two shapes, one rectangle
    // and a dotted line
    doc.save(&mut BufWriter::new(
        File::create("test_graphics.pdf").unwrap(),
    ))
    .unwrap();
}
source

pub fn add_polygon(&self, poly: Polygon)

Add a line to the layer. Use closed to indicate whether the line is a closed line Use has_fill to determine if the line should be filled.

Examples found in repository?
examples/circle.rs (line 27)
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();
}
More examples
Hide additional examples
examples/shape.rs (line 68)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(400.0), Mm(400.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    // Quadratic shape. The "false" determines if the next (following)
    // point is a bezier handle (for curves)
    // If you want holes, simply reorder the winding of the points to be
    // counterclockwise instead of clockwise.
    let points1 = vec![
        (Point::new(Mm(100.0), Mm(100.0)), false),
        (Point::new(Mm(100.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(100.0)), false),
    ];

    // Is the shape stroked? Is the shape closed? Is the shape filled?
    let line1 = Line {
        points: points1.clone(),
        is_closed: true,
    };

    let outline_color = Color::Rgb(Rgb::new(0.75, 1.0, 0.64, None));
    let dash_pattern = LineDashPattern {
        dash_1: Some(20),
        ..Default::default()
    };

    // Draw first line
    current_layer.set_outline_color(outline_color);
    current_layer.set_outline_thickness(10.0);
    current_layer.add_line(line1);

    // Triangle shape
    // Note: Line is invisible by default, the previous method of
    // constructing a line is recommended!
    let line2 = Polygon {
        rings: vec![vec![
            (Point::new(Mm(150.0), Mm(150.0)), false),
            (Point::new(Mm(150.0), Mm(250.0)), false),
            (Point::new(Mm(350.0), Mm(250.0)), false),
        ]],
        mode: PaintMode::FillStroke,
        winding_order: WindingOrder::NonZero,
    };

    let fill_color_2 = Color::Cmyk(Cmyk::new(0.0, 0.0, 0.0, 0.0, None));
    let outline_color_2 = Color::Greyscale(Greyscale::new(0.45, None));

    // More advanced graphical options
    current_layer.set_overprint_stroke(true);
    current_layer.set_blend_mode(BlendMode::Seperable(SeperableBlendMode::Multiply));
    current_layer.set_line_dash_pattern(dash_pattern);
    current_layer.set_line_cap_style(LineCapStyle::Round);
    current_layer.set_line_join_style(LineJoinStyle::Round);
    current_layer.set_fill_color(fill_color_2);
    current_layer.set_outline_color(outline_color_2);
    current_layer.set_outline_thickness(15.0);

    // draw second line
    current_layer.add_polygon(line2);

    // quad clip - note: FIRST SET THE CLIP, then paint the path
    current_layer.save_graphics_state();
    let line4 = Polygon {
        rings: vec![points1.clone()],
        mode: PaintMode::Clip,
        winding_order: WindingOrder::NonZero,
    };

    current_layer.add_polygon(line4);

    let points5 = vec![
        (Point::new(Mm(150.0), Mm(150.0)), false),
        (Point::new(Mm(150.0), Mm(250.0)), false),
        (Point::new(Mm(350.0), Mm(250.0)), false),
    ];

    let line3 = Line {
        points: points5.clone(),
        is_closed: true,
    };

    let outline_color2 = Color::Rgb(Rgb::new(1.0, 0.75, 0.0, None));
    current_layer.set_line_dash_pattern(LineDashPattern::default());
    current_layer.set_outline_color(outline_color2);
    current_layer.set_outline_thickness(5.0);
    current_layer.add_line(line3);

    current_layer.restore_graphics_state(); // unset clip again for further operations

    // If this is successful, you should see a PDF two shapes, one rectangle
    // and a dotted line
    doc.save(&mut BufWriter::new(
        File::create("test_graphics.pdf").unwrap(),
    ))
    .unwrap();
}
Examples found in repository?
examples/hyperlink.rs (lines 16-22)
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();
}
source

pub fn begin_text_section(&self)

Begins a new text section You have to make sure to call end_text_section afterwards

Examples found in repository?
examples/font.rs (line 32)
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 end_text_section(&self)

Ends a new text section Only valid if begin_text_section has been called

Examples found in repository?
examples/font.rs (line 59)
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 set_fill_color(&self, fill_color: Color)

Set the current fill color for the layer

Examples found in repository?
examples/font.rs (line 25)
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();
}
More examples
Hide additional examples
examples/shape.rs (line 63)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(400.0), Mm(400.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    // Quadratic shape. The "false" determines if the next (following)
    // point is a bezier handle (for curves)
    // If you want holes, simply reorder the winding of the points to be
    // counterclockwise instead of clockwise.
    let points1 = vec![
        (Point::new(Mm(100.0), Mm(100.0)), false),
        (Point::new(Mm(100.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(100.0)), false),
    ];

    // Is the shape stroked? Is the shape closed? Is the shape filled?
    let line1 = Line {
        points: points1.clone(),
        is_closed: true,
    };

    let outline_color = Color::Rgb(Rgb::new(0.75, 1.0, 0.64, None));
    let dash_pattern = LineDashPattern {
        dash_1: Some(20),
        ..Default::default()
    };

    // Draw first line
    current_layer.set_outline_color(outline_color);
    current_layer.set_outline_thickness(10.0);
    current_layer.add_line(line1);

    // Triangle shape
    // Note: Line is invisible by default, the previous method of
    // constructing a line is recommended!
    let line2 = Polygon {
        rings: vec![vec![
            (Point::new(Mm(150.0), Mm(150.0)), false),
            (Point::new(Mm(150.0), Mm(250.0)), false),
            (Point::new(Mm(350.0), Mm(250.0)), false),
        ]],
        mode: PaintMode::FillStroke,
        winding_order: WindingOrder::NonZero,
    };

    let fill_color_2 = Color::Cmyk(Cmyk::new(0.0, 0.0, 0.0, 0.0, None));
    let outline_color_2 = Color::Greyscale(Greyscale::new(0.45, None));

    // More advanced graphical options
    current_layer.set_overprint_stroke(true);
    current_layer.set_blend_mode(BlendMode::Seperable(SeperableBlendMode::Multiply));
    current_layer.set_line_dash_pattern(dash_pattern);
    current_layer.set_line_cap_style(LineCapStyle::Round);
    current_layer.set_line_join_style(LineJoinStyle::Round);
    current_layer.set_fill_color(fill_color_2);
    current_layer.set_outline_color(outline_color_2);
    current_layer.set_outline_thickness(15.0);

    // draw second line
    current_layer.add_polygon(line2);

    // quad clip - note: FIRST SET THE CLIP, then paint the path
    current_layer.save_graphics_state();
    let line4 = Polygon {
        rings: vec![points1.clone()],
        mode: PaintMode::Clip,
        winding_order: WindingOrder::NonZero,
    };

    current_layer.add_polygon(line4);

    let points5 = vec![
        (Point::new(Mm(150.0), Mm(150.0)), false),
        (Point::new(Mm(150.0), Mm(250.0)), false),
        (Point::new(Mm(350.0), Mm(250.0)), false),
    ];

    let line3 = Line {
        points: points5.clone(),
        is_closed: true,
    };

    let outline_color2 = Color::Rgb(Rgb::new(1.0, 0.75, 0.0, None));
    current_layer.set_line_dash_pattern(LineDashPattern::default());
    current_layer.set_outline_color(outline_color2);
    current_layer.set_outline_thickness(5.0);
    current_layer.add_line(line3);

    current_layer.restore_graphics_state(); // unset clip again for further operations

    // If this is successful, you should see a PDF two shapes, one rectangle
    // and a dotted line
    doc.save(&mut BufWriter::new(
        File::create("test_graphics.pdf").unwrap(),
    ))
    .unwrap();
}
source

pub fn set_font(&self, font: &IndirectFontRef, font_size: f32)

Set the current font, only valid in a begin_text_section to end_text_section block

Examples found in repository?
examples/font.rs (line 36)
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 set_outline_color(&self, color: Color)

Set the current line / outline color for the layer

Examples found in repository?
examples/font.rs (line 26)
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();
}
More examples
Hide additional examples
examples/shape.rs (line 37)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(400.0), Mm(400.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    // Quadratic shape. The "false" determines if the next (following)
    // point is a bezier handle (for curves)
    // If you want holes, simply reorder the winding of the points to be
    // counterclockwise instead of clockwise.
    let points1 = vec![
        (Point::new(Mm(100.0), Mm(100.0)), false),
        (Point::new(Mm(100.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(100.0)), false),
    ];

    // Is the shape stroked? Is the shape closed? Is the shape filled?
    let line1 = Line {
        points: points1.clone(),
        is_closed: true,
    };

    let outline_color = Color::Rgb(Rgb::new(0.75, 1.0, 0.64, None));
    let dash_pattern = LineDashPattern {
        dash_1: Some(20),
        ..Default::default()
    };

    // Draw first line
    current_layer.set_outline_color(outline_color);
    current_layer.set_outline_thickness(10.0);
    current_layer.add_line(line1);

    // Triangle shape
    // Note: Line is invisible by default, the previous method of
    // constructing a line is recommended!
    let line2 = Polygon {
        rings: vec![vec![
            (Point::new(Mm(150.0), Mm(150.0)), false),
            (Point::new(Mm(150.0), Mm(250.0)), false),
            (Point::new(Mm(350.0), Mm(250.0)), false),
        ]],
        mode: PaintMode::FillStroke,
        winding_order: WindingOrder::NonZero,
    };

    let fill_color_2 = Color::Cmyk(Cmyk::new(0.0, 0.0, 0.0, 0.0, None));
    let outline_color_2 = Color::Greyscale(Greyscale::new(0.45, None));

    // More advanced graphical options
    current_layer.set_overprint_stroke(true);
    current_layer.set_blend_mode(BlendMode::Seperable(SeperableBlendMode::Multiply));
    current_layer.set_line_dash_pattern(dash_pattern);
    current_layer.set_line_cap_style(LineCapStyle::Round);
    current_layer.set_line_join_style(LineJoinStyle::Round);
    current_layer.set_fill_color(fill_color_2);
    current_layer.set_outline_color(outline_color_2);
    current_layer.set_outline_thickness(15.0);

    // draw second line
    current_layer.add_polygon(line2);

    // quad clip - note: FIRST SET THE CLIP, then paint the path
    current_layer.save_graphics_state();
    let line4 = Polygon {
        rings: vec![points1.clone()],
        mode: PaintMode::Clip,
        winding_order: WindingOrder::NonZero,
    };

    current_layer.add_polygon(line4);

    let points5 = vec![
        (Point::new(Mm(150.0), Mm(150.0)), false),
        (Point::new(Mm(150.0), Mm(250.0)), false),
        (Point::new(Mm(350.0), Mm(250.0)), false),
    ];

    let line3 = Line {
        points: points5.clone(),
        is_closed: true,
    };

    let outline_color2 = Color::Rgb(Rgb::new(1.0, 0.75, 0.0, None));
    current_layer.set_line_dash_pattern(LineDashPattern::default());
    current_layer.set_outline_color(outline_color2);
    current_layer.set_outline_thickness(5.0);
    current_layer.add_line(line3);

    current_layer.restore_graphics_state(); // unset clip again for further operations

    // If this is successful, you should see a PDF two shapes, one rectangle
    // and a dotted line
    doc.save(&mut BufWriter::new(
        File::create("test_graphics.pdf").unwrap(),
    ))
    .unwrap();
}
source

pub fn set_overprint_fill(&self, overprint: bool)

Set the overprint mode of the stroke color to true (overprint) or false (no overprint)

source

pub fn set_overprint_stroke(&self, overprint: bool)

Set the overprint mode of the fill color to true (overprint) or false (no overprint) This changes the graphics state of the current page, don’t do it too often or you’ll bloat the file size

Examples found in repository?
examples/shape.rs (line 58)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(400.0), Mm(400.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    // Quadratic shape. The "false" determines if the next (following)
    // point is a bezier handle (for curves)
    // If you want holes, simply reorder the winding of the points to be
    // counterclockwise instead of clockwise.
    let points1 = vec![
        (Point::new(Mm(100.0), Mm(100.0)), false),
        (Point::new(Mm(100.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(100.0)), false),
    ];

    // Is the shape stroked? Is the shape closed? Is the shape filled?
    let line1 = Line {
        points: points1.clone(),
        is_closed: true,
    };

    let outline_color = Color::Rgb(Rgb::new(0.75, 1.0, 0.64, None));
    let dash_pattern = LineDashPattern {
        dash_1: Some(20),
        ..Default::default()
    };

    // Draw first line
    current_layer.set_outline_color(outline_color);
    current_layer.set_outline_thickness(10.0);
    current_layer.add_line(line1);

    // Triangle shape
    // Note: Line is invisible by default, the previous method of
    // constructing a line is recommended!
    let line2 = Polygon {
        rings: vec![vec![
            (Point::new(Mm(150.0), Mm(150.0)), false),
            (Point::new(Mm(150.0), Mm(250.0)), false),
            (Point::new(Mm(350.0), Mm(250.0)), false),
        ]],
        mode: PaintMode::FillStroke,
        winding_order: WindingOrder::NonZero,
    };

    let fill_color_2 = Color::Cmyk(Cmyk::new(0.0, 0.0, 0.0, 0.0, None));
    let outline_color_2 = Color::Greyscale(Greyscale::new(0.45, None));

    // More advanced graphical options
    current_layer.set_overprint_stroke(true);
    current_layer.set_blend_mode(BlendMode::Seperable(SeperableBlendMode::Multiply));
    current_layer.set_line_dash_pattern(dash_pattern);
    current_layer.set_line_cap_style(LineCapStyle::Round);
    current_layer.set_line_join_style(LineJoinStyle::Round);
    current_layer.set_fill_color(fill_color_2);
    current_layer.set_outline_color(outline_color_2);
    current_layer.set_outline_thickness(15.0);

    // draw second line
    current_layer.add_polygon(line2);

    // quad clip - note: FIRST SET THE CLIP, then paint the path
    current_layer.save_graphics_state();
    let line4 = Polygon {
        rings: vec![points1.clone()],
        mode: PaintMode::Clip,
        winding_order: WindingOrder::NonZero,
    };

    current_layer.add_polygon(line4);

    let points5 = vec![
        (Point::new(Mm(150.0), Mm(150.0)), false),
        (Point::new(Mm(150.0), Mm(250.0)), false),
        (Point::new(Mm(350.0), Mm(250.0)), false),
    ];

    let line3 = Line {
        points: points5.clone(),
        is_closed: true,
    };

    let outline_color2 = Color::Rgb(Rgb::new(1.0, 0.75, 0.0, None));
    current_layer.set_line_dash_pattern(LineDashPattern::default());
    current_layer.set_outline_color(outline_color2);
    current_layer.set_outline_thickness(5.0);
    current_layer.add_line(line3);

    current_layer.restore_graphics_state(); // unset clip again for further operations

    // If this is successful, you should see a PDF two shapes, one rectangle
    // and a dotted line
    doc.save(&mut BufWriter::new(
        File::create("test_graphics.pdf").unwrap(),
    ))
    .unwrap();
}
source

pub fn set_blend_mode(&self, blend_mode: BlendMode)

Set the overprint mode of the fill color to true (overprint) or false (no overprint) This changes the graphics state of the current page, don’t do it too often or you’ll bloat the file size

Examples found in repository?
examples/shape.rs (line 59)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(400.0), Mm(400.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    // Quadratic shape. The "false" determines if the next (following)
    // point is a bezier handle (for curves)
    // If you want holes, simply reorder the winding of the points to be
    // counterclockwise instead of clockwise.
    let points1 = vec![
        (Point::new(Mm(100.0), Mm(100.0)), false),
        (Point::new(Mm(100.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(100.0)), false),
    ];

    // Is the shape stroked? Is the shape closed? Is the shape filled?
    let line1 = Line {
        points: points1.clone(),
        is_closed: true,
    };

    let outline_color = Color::Rgb(Rgb::new(0.75, 1.0, 0.64, None));
    let dash_pattern = LineDashPattern {
        dash_1: Some(20),
        ..Default::default()
    };

    // Draw first line
    current_layer.set_outline_color(outline_color);
    current_layer.set_outline_thickness(10.0);
    current_layer.add_line(line1);

    // Triangle shape
    // Note: Line is invisible by default, the previous method of
    // constructing a line is recommended!
    let line2 = Polygon {
        rings: vec![vec![
            (Point::new(Mm(150.0), Mm(150.0)), false),
            (Point::new(Mm(150.0), Mm(250.0)), false),
            (Point::new(Mm(350.0), Mm(250.0)), false),
        ]],
        mode: PaintMode::FillStroke,
        winding_order: WindingOrder::NonZero,
    };

    let fill_color_2 = Color::Cmyk(Cmyk::new(0.0, 0.0, 0.0, 0.0, None));
    let outline_color_2 = Color::Greyscale(Greyscale::new(0.45, None));

    // More advanced graphical options
    current_layer.set_overprint_stroke(true);
    current_layer.set_blend_mode(BlendMode::Seperable(SeperableBlendMode::Multiply));
    current_layer.set_line_dash_pattern(dash_pattern);
    current_layer.set_line_cap_style(LineCapStyle::Round);
    current_layer.set_line_join_style(LineJoinStyle::Round);
    current_layer.set_fill_color(fill_color_2);
    current_layer.set_outline_color(outline_color_2);
    current_layer.set_outline_thickness(15.0);

    // draw second line
    current_layer.add_polygon(line2);

    // quad clip - note: FIRST SET THE CLIP, then paint the path
    current_layer.save_graphics_state();
    let line4 = Polygon {
        rings: vec![points1.clone()],
        mode: PaintMode::Clip,
        winding_order: WindingOrder::NonZero,
    };

    current_layer.add_polygon(line4);

    let points5 = vec![
        (Point::new(Mm(150.0), Mm(150.0)), false),
        (Point::new(Mm(150.0), Mm(250.0)), false),
        (Point::new(Mm(350.0), Mm(250.0)), false),
    ];

    let line3 = Line {
        points: points5.clone(),
        is_closed: true,
    };

    let outline_color2 = Color::Rgb(Rgb::new(1.0, 0.75, 0.0, None));
    current_layer.set_line_dash_pattern(LineDashPattern::default());
    current_layer.set_outline_color(outline_color2);
    current_layer.set_outline_thickness(5.0);
    current_layer.add_line(line3);

    current_layer.restore_graphics_state(); // unset clip again for further operations

    // If this is successful, you should see a PDF two shapes, one rectangle
    // and a dotted line
    doc.save(&mut BufWriter::new(
        File::create("test_graphics.pdf").unwrap(),
    ))
    .unwrap();
}
source

pub fn set_outline_thickness(&self, outline_thickness: f32)

Set the current line thickness, in points

NOTE: 0.0 is a special value, it does not make the line disappear, but rather makes it appear 1px wide across all devices

Examples found in repository?
examples/shape.rs (line 38)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(400.0), Mm(400.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    // Quadratic shape. The "false" determines if the next (following)
    // point is a bezier handle (for curves)
    // If you want holes, simply reorder the winding of the points to be
    // counterclockwise instead of clockwise.
    let points1 = vec![
        (Point::new(Mm(100.0), Mm(100.0)), false),
        (Point::new(Mm(100.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(100.0)), false),
    ];

    // Is the shape stroked? Is the shape closed? Is the shape filled?
    let line1 = Line {
        points: points1.clone(),
        is_closed: true,
    };

    let outline_color = Color::Rgb(Rgb::new(0.75, 1.0, 0.64, None));
    let dash_pattern = LineDashPattern {
        dash_1: Some(20),
        ..Default::default()
    };

    // Draw first line
    current_layer.set_outline_color(outline_color);
    current_layer.set_outline_thickness(10.0);
    current_layer.add_line(line1);

    // Triangle shape
    // Note: Line is invisible by default, the previous method of
    // constructing a line is recommended!
    let line2 = Polygon {
        rings: vec![vec![
            (Point::new(Mm(150.0), Mm(150.0)), false),
            (Point::new(Mm(150.0), Mm(250.0)), false),
            (Point::new(Mm(350.0), Mm(250.0)), false),
        ]],
        mode: PaintMode::FillStroke,
        winding_order: WindingOrder::NonZero,
    };

    let fill_color_2 = Color::Cmyk(Cmyk::new(0.0, 0.0, 0.0, 0.0, None));
    let outline_color_2 = Color::Greyscale(Greyscale::new(0.45, None));

    // More advanced graphical options
    current_layer.set_overprint_stroke(true);
    current_layer.set_blend_mode(BlendMode::Seperable(SeperableBlendMode::Multiply));
    current_layer.set_line_dash_pattern(dash_pattern);
    current_layer.set_line_cap_style(LineCapStyle::Round);
    current_layer.set_line_join_style(LineJoinStyle::Round);
    current_layer.set_fill_color(fill_color_2);
    current_layer.set_outline_color(outline_color_2);
    current_layer.set_outline_thickness(15.0);

    // draw second line
    current_layer.add_polygon(line2);

    // quad clip - note: FIRST SET THE CLIP, then paint the path
    current_layer.save_graphics_state();
    let line4 = Polygon {
        rings: vec![points1.clone()],
        mode: PaintMode::Clip,
        winding_order: WindingOrder::NonZero,
    };

    current_layer.add_polygon(line4);

    let points5 = vec![
        (Point::new(Mm(150.0), Mm(150.0)), false),
        (Point::new(Mm(150.0), Mm(250.0)), false),
        (Point::new(Mm(350.0), Mm(250.0)), false),
    ];

    let line3 = Line {
        points: points5.clone(),
        is_closed: true,
    };

    let outline_color2 = Color::Rgb(Rgb::new(1.0, 0.75, 0.0, None));
    current_layer.set_line_dash_pattern(LineDashPattern::default());
    current_layer.set_outline_color(outline_color2);
    current_layer.set_outline_thickness(5.0);
    current_layer.add_line(line3);

    current_layer.restore_graphics_state(); // unset clip again for further operations

    // If this is successful, you should see a PDF two shapes, one rectangle
    // and a dotted line
    doc.save(&mut BufWriter::new(
        File::create("test_graphics.pdf").unwrap(),
    ))
    .unwrap();
}
source

pub fn set_line_join_style(&self, line_join: LineJoinStyle)

Set the current line join style for outlines

Examples found in repository?
examples/shape.rs (line 62)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(400.0), Mm(400.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    // Quadratic shape. The "false" determines if the next (following)
    // point is a bezier handle (for curves)
    // If you want holes, simply reorder the winding of the points to be
    // counterclockwise instead of clockwise.
    let points1 = vec![
        (Point::new(Mm(100.0), Mm(100.0)), false),
        (Point::new(Mm(100.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(100.0)), false),
    ];

    // Is the shape stroked? Is the shape closed? Is the shape filled?
    let line1 = Line {
        points: points1.clone(),
        is_closed: true,
    };

    let outline_color = Color::Rgb(Rgb::new(0.75, 1.0, 0.64, None));
    let dash_pattern = LineDashPattern {
        dash_1: Some(20),
        ..Default::default()
    };

    // Draw first line
    current_layer.set_outline_color(outline_color);
    current_layer.set_outline_thickness(10.0);
    current_layer.add_line(line1);

    // Triangle shape
    // Note: Line is invisible by default, the previous method of
    // constructing a line is recommended!
    let line2 = Polygon {
        rings: vec![vec![
            (Point::new(Mm(150.0), Mm(150.0)), false),
            (Point::new(Mm(150.0), Mm(250.0)), false),
            (Point::new(Mm(350.0), Mm(250.0)), false),
        ]],
        mode: PaintMode::FillStroke,
        winding_order: WindingOrder::NonZero,
    };

    let fill_color_2 = Color::Cmyk(Cmyk::new(0.0, 0.0, 0.0, 0.0, None));
    let outline_color_2 = Color::Greyscale(Greyscale::new(0.45, None));

    // More advanced graphical options
    current_layer.set_overprint_stroke(true);
    current_layer.set_blend_mode(BlendMode::Seperable(SeperableBlendMode::Multiply));
    current_layer.set_line_dash_pattern(dash_pattern);
    current_layer.set_line_cap_style(LineCapStyle::Round);
    current_layer.set_line_join_style(LineJoinStyle::Round);
    current_layer.set_fill_color(fill_color_2);
    current_layer.set_outline_color(outline_color_2);
    current_layer.set_outline_thickness(15.0);

    // draw second line
    current_layer.add_polygon(line2);

    // quad clip - note: FIRST SET THE CLIP, then paint the path
    current_layer.save_graphics_state();
    let line4 = Polygon {
        rings: vec![points1.clone()],
        mode: PaintMode::Clip,
        winding_order: WindingOrder::NonZero,
    };

    current_layer.add_polygon(line4);

    let points5 = vec![
        (Point::new(Mm(150.0), Mm(150.0)), false),
        (Point::new(Mm(150.0), Mm(250.0)), false),
        (Point::new(Mm(350.0), Mm(250.0)), false),
    ];

    let line3 = Line {
        points: points5.clone(),
        is_closed: true,
    };

    let outline_color2 = Color::Rgb(Rgb::new(1.0, 0.75, 0.0, None));
    current_layer.set_line_dash_pattern(LineDashPattern::default());
    current_layer.set_outline_color(outline_color2);
    current_layer.set_outline_thickness(5.0);
    current_layer.add_line(line3);

    current_layer.restore_graphics_state(); // unset clip again for further operations

    // If this is successful, you should see a PDF two shapes, one rectangle
    // and a dotted line
    doc.save(&mut BufWriter::new(
        File::create("test_graphics.pdf").unwrap(),
    ))
    .unwrap();
}
source

pub fn set_line_cap_style(&self, line_cap: LineCapStyle)

Set the current line join style for outlines

Examples found in repository?
examples/shape.rs (line 61)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(400.0), Mm(400.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    // Quadratic shape. The "false" determines if the next (following)
    // point is a bezier handle (for curves)
    // If you want holes, simply reorder the winding of the points to be
    // counterclockwise instead of clockwise.
    let points1 = vec![
        (Point::new(Mm(100.0), Mm(100.0)), false),
        (Point::new(Mm(100.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(100.0)), false),
    ];

    // Is the shape stroked? Is the shape closed? Is the shape filled?
    let line1 = Line {
        points: points1.clone(),
        is_closed: true,
    };

    let outline_color = Color::Rgb(Rgb::new(0.75, 1.0, 0.64, None));
    let dash_pattern = LineDashPattern {
        dash_1: Some(20),
        ..Default::default()
    };

    // Draw first line
    current_layer.set_outline_color(outline_color);
    current_layer.set_outline_thickness(10.0);
    current_layer.add_line(line1);

    // Triangle shape
    // Note: Line is invisible by default, the previous method of
    // constructing a line is recommended!
    let line2 = Polygon {
        rings: vec![vec![
            (Point::new(Mm(150.0), Mm(150.0)), false),
            (Point::new(Mm(150.0), Mm(250.0)), false),
            (Point::new(Mm(350.0), Mm(250.0)), false),
        ]],
        mode: PaintMode::FillStroke,
        winding_order: WindingOrder::NonZero,
    };

    let fill_color_2 = Color::Cmyk(Cmyk::new(0.0, 0.0, 0.0, 0.0, None));
    let outline_color_2 = Color::Greyscale(Greyscale::new(0.45, None));

    // More advanced graphical options
    current_layer.set_overprint_stroke(true);
    current_layer.set_blend_mode(BlendMode::Seperable(SeperableBlendMode::Multiply));
    current_layer.set_line_dash_pattern(dash_pattern);
    current_layer.set_line_cap_style(LineCapStyle::Round);
    current_layer.set_line_join_style(LineJoinStyle::Round);
    current_layer.set_fill_color(fill_color_2);
    current_layer.set_outline_color(outline_color_2);
    current_layer.set_outline_thickness(15.0);

    // draw second line
    current_layer.add_polygon(line2);

    // quad clip - note: FIRST SET THE CLIP, then paint the path
    current_layer.save_graphics_state();
    let line4 = Polygon {
        rings: vec![points1.clone()],
        mode: PaintMode::Clip,
        winding_order: WindingOrder::NonZero,
    };

    current_layer.add_polygon(line4);

    let points5 = vec![
        (Point::new(Mm(150.0), Mm(150.0)), false),
        (Point::new(Mm(150.0), Mm(250.0)), false),
        (Point::new(Mm(350.0), Mm(250.0)), false),
    ];

    let line3 = Line {
        points: points5.clone(),
        is_closed: true,
    };

    let outline_color2 = Color::Rgb(Rgb::new(1.0, 0.75, 0.0, None));
    current_layer.set_line_dash_pattern(LineDashPattern::default());
    current_layer.set_outline_color(outline_color2);
    current_layer.set_outline_thickness(5.0);
    current_layer.add_line(line3);

    current_layer.restore_graphics_state(); // unset clip again for further operations

    // If this is successful, you should see a PDF two shapes, one rectangle
    // and a dotted line
    doc.save(&mut BufWriter::new(
        File::create("test_graphics.pdf").unwrap(),
    ))
    .unwrap();
}
source

pub fn set_line_dash_pattern(&self, dash_pattern: LineDashPattern)

Set the current line join style for outlines

Examples found in repository?
examples/shape.rs (line 60)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(400.0), Mm(400.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    // Quadratic shape. The "false" determines if the next (following)
    // point is a bezier handle (for curves)
    // If you want holes, simply reorder the winding of the points to be
    // counterclockwise instead of clockwise.
    let points1 = vec![
        (Point::new(Mm(100.0), Mm(100.0)), false),
        (Point::new(Mm(100.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(100.0)), false),
    ];

    // Is the shape stroked? Is the shape closed? Is the shape filled?
    let line1 = Line {
        points: points1.clone(),
        is_closed: true,
    };

    let outline_color = Color::Rgb(Rgb::new(0.75, 1.0, 0.64, None));
    let dash_pattern = LineDashPattern {
        dash_1: Some(20),
        ..Default::default()
    };

    // Draw first line
    current_layer.set_outline_color(outline_color);
    current_layer.set_outline_thickness(10.0);
    current_layer.add_line(line1);

    // Triangle shape
    // Note: Line is invisible by default, the previous method of
    // constructing a line is recommended!
    let line2 = Polygon {
        rings: vec![vec![
            (Point::new(Mm(150.0), Mm(150.0)), false),
            (Point::new(Mm(150.0), Mm(250.0)), false),
            (Point::new(Mm(350.0), Mm(250.0)), false),
        ]],
        mode: PaintMode::FillStroke,
        winding_order: WindingOrder::NonZero,
    };

    let fill_color_2 = Color::Cmyk(Cmyk::new(0.0, 0.0, 0.0, 0.0, None));
    let outline_color_2 = Color::Greyscale(Greyscale::new(0.45, None));

    // More advanced graphical options
    current_layer.set_overprint_stroke(true);
    current_layer.set_blend_mode(BlendMode::Seperable(SeperableBlendMode::Multiply));
    current_layer.set_line_dash_pattern(dash_pattern);
    current_layer.set_line_cap_style(LineCapStyle::Round);
    current_layer.set_line_join_style(LineJoinStyle::Round);
    current_layer.set_fill_color(fill_color_2);
    current_layer.set_outline_color(outline_color_2);
    current_layer.set_outline_thickness(15.0);

    // draw second line
    current_layer.add_polygon(line2);

    // quad clip - note: FIRST SET THE CLIP, then paint the path
    current_layer.save_graphics_state();
    let line4 = Polygon {
        rings: vec![points1.clone()],
        mode: PaintMode::Clip,
        winding_order: WindingOrder::NonZero,
    };

    current_layer.add_polygon(line4);

    let points5 = vec![
        (Point::new(Mm(150.0), Mm(150.0)), false),
        (Point::new(Mm(150.0), Mm(250.0)), false),
        (Point::new(Mm(350.0), Mm(250.0)), false),
    ];

    let line3 = Line {
        points: points5.clone(),
        is_closed: true,
    };

    let outline_color2 = Color::Rgb(Rgb::new(1.0, 0.75, 0.0, None));
    current_layer.set_line_dash_pattern(LineDashPattern::default());
    current_layer.set_outline_color(outline_color2);
    current_layer.set_outline_thickness(5.0);
    current_layer.add_line(line3);

    current_layer.restore_graphics_state(); // unset clip again for further operations

    // If this is successful, you should see a PDF two shapes, one rectangle
    // and a dotted line
    doc.save(&mut BufWriter::new(
        File::create("test_graphics.pdf").unwrap(),
    ))
    .unwrap();
}
source

pub fn set_ctm(&self, ctm: CurTransMat)

Sets (adds to) the current transformation matrix Use save_graphics_state() and restore_graphics_state() to “scope” the transformation matrix to a specific function

source

pub fn set_text_matrix(&self, tm: TextMatrix)

Sets (replaces) the current text matrix This does not have to be scoped, since the matrix is replaced instead of concatenated to the current matrix. However, you should only call this function with in a block scoped by begin_text_section() and end_text_section()

Examples found in repository?
examples/font.rs (line 50)
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 set_text_cursor(&self, x: Mm, y: Mm)

Sets the position where the text should appear

Examples found in repository?
examples/font.rs (line 37)
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_line_break(&self)

If called inside a text block scoped by begin_text_section and end_text_section, moves the cursor to a new line. PDF does not have any concept of “alignment” except left-aligned text Note: Use set_line_height earlier to set the line height first

Examples found in repository?
examples/font.rs (line 44)
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 set_line_height(&self, height: f32)

Sets the text line height inside a text block (must be called within begin_text_block and end_text_block)

Examples found in repository?
examples/font.rs (line 38)
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 set_character_spacing(&self, spacing: f32)

Sets the character spacing inside a text block Values are given in points. A value of 3 (pt) will increase the spacing inside a word by 3pt.

Examples found in repository?
examples/font.rs (line 40)
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 set_word_spacing(&self, spacing: f32)

Sets the word spacing inside a text block. Same as set_character_spacing, just for words. Note: This currently does not work for external fonts. External fonts are encoded with Unicode, and PDF does not recognize unicode fonts. It only recognizes builtin fonts done with PDFDoc encoding. However, the function itself is valid and will work with builtin fonts.

Examples found in repository?
examples/font.rs (line 39)
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 set_text_scaling(&self, scaling: f32)

Sets the horizontal scaling (like a “condensed” font) Default value is 100 (regular scaling). Setting it to 50 will reduce the width of the written text by half, but stretch the text

source

pub fn set_line_offset(&self, offset: f32)

Offsets the current text positon (used for superscript and subscript). To reset the superscript / subscript, call this function with 0 as the offset. For superscript, use a positive number, for subscript, use a negative number. This does not change the size of the font

Examples found in repository?
examples/font.rs (line 54)
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 set_text_rendering_mode(&self, mode: TextRenderingMode)

Examples found in repository?
examples/font.rs (line 48)
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 write_codepoints<I>(&self, codepoints: I)
where I: IntoIterator<Item = u16>,

Add text to the file at the current position by specifying font codepoints for an ExternalFont

source

pub fn write_positioned_codepoints<I>(&self, codepoints: I)
where I: IntoIterator<Item = (i64, u16)>,

Add text to the file at the current position by specifying font codepoints with additional kerning offset

source

pub fn write_text<S>(&self, text: S, font: &IndirectFontRef)
where S: Into<String>,

Add text to the file at the current position

If the given font is a built-in font and the given text contains characters that are not supported by the Windows-1252 encoding, these characters will be ignored.

Examples found in repository?
examples/font.rs (line 43)
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 save_graphics_state(&self)

Saves the current graphic state

Examples found in repository?
examples/shape.rs (line 71)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(400.0), Mm(400.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    // Quadratic shape. The "false" determines if the next (following)
    // point is a bezier handle (for curves)
    // If you want holes, simply reorder the winding of the points to be
    // counterclockwise instead of clockwise.
    let points1 = vec![
        (Point::new(Mm(100.0), Mm(100.0)), false),
        (Point::new(Mm(100.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(100.0)), false),
    ];

    // Is the shape stroked? Is the shape closed? Is the shape filled?
    let line1 = Line {
        points: points1.clone(),
        is_closed: true,
    };

    let outline_color = Color::Rgb(Rgb::new(0.75, 1.0, 0.64, None));
    let dash_pattern = LineDashPattern {
        dash_1: Some(20),
        ..Default::default()
    };

    // Draw first line
    current_layer.set_outline_color(outline_color);
    current_layer.set_outline_thickness(10.0);
    current_layer.add_line(line1);

    // Triangle shape
    // Note: Line is invisible by default, the previous method of
    // constructing a line is recommended!
    let line2 = Polygon {
        rings: vec![vec![
            (Point::new(Mm(150.0), Mm(150.0)), false),
            (Point::new(Mm(150.0), Mm(250.0)), false),
            (Point::new(Mm(350.0), Mm(250.0)), false),
        ]],
        mode: PaintMode::FillStroke,
        winding_order: WindingOrder::NonZero,
    };

    let fill_color_2 = Color::Cmyk(Cmyk::new(0.0, 0.0, 0.0, 0.0, None));
    let outline_color_2 = Color::Greyscale(Greyscale::new(0.45, None));

    // More advanced graphical options
    current_layer.set_overprint_stroke(true);
    current_layer.set_blend_mode(BlendMode::Seperable(SeperableBlendMode::Multiply));
    current_layer.set_line_dash_pattern(dash_pattern);
    current_layer.set_line_cap_style(LineCapStyle::Round);
    current_layer.set_line_join_style(LineJoinStyle::Round);
    current_layer.set_fill_color(fill_color_2);
    current_layer.set_outline_color(outline_color_2);
    current_layer.set_outline_thickness(15.0);

    // draw second line
    current_layer.add_polygon(line2);

    // quad clip - note: FIRST SET THE CLIP, then paint the path
    current_layer.save_graphics_state();
    let line4 = Polygon {
        rings: vec![points1.clone()],
        mode: PaintMode::Clip,
        winding_order: WindingOrder::NonZero,
    };

    current_layer.add_polygon(line4);

    let points5 = vec![
        (Point::new(Mm(150.0), Mm(150.0)), false),
        (Point::new(Mm(150.0), Mm(250.0)), false),
        (Point::new(Mm(350.0), Mm(250.0)), false),
    ];

    let line3 = Line {
        points: points5.clone(),
        is_closed: true,
    };

    let outline_color2 = Color::Rgb(Rgb::new(1.0, 0.75, 0.0, None));
    current_layer.set_line_dash_pattern(LineDashPattern::default());
    current_layer.set_outline_color(outline_color2);
    current_layer.set_outline_thickness(5.0);
    current_layer.add_line(line3);

    current_layer.restore_graphics_state(); // unset clip again for further operations

    // If this is successful, you should see a PDF two shapes, one rectangle
    // and a dotted line
    doc.save(&mut BufWriter::new(
        File::create("test_graphics.pdf").unwrap(),
    ))
    .unwrap();
}
source

pub fn restore_graphics_state(&self)

Restores the previous graphic state

Examples found in repository?
examples/shape.rs (line 97)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn main() {
    let (doc, page1, layer1) =
        PdfDocument::new("printpdf graphics test", Mm(400.0), Mm(400.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);

    // Quadratic shape. The "false" determines if the next (following)
    // point is a bezier handle (for curves)
    // If you want holes, simply reorder the winding of the points to be
    // counterclockwise instead of clockwise.
    let points1 = vec![
        (Point::new(Mm(100.0), Mm(100.0)), false),
        (Point::new(Mm(100.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(200.0)), false),
        (Point::new(Mm(300.0), Mm(100.0)), false),
    ];

    // Is the shape stroked? Is the shape closed? Is the shape filled?
    let line1 = Line {
        points: points1.clone(),
        is_closed: true,
    };

    let outline_color = Color::Rgb(Rgb::new(0.75, 1.0, 0.64, None));
    let dash_pattern = LineDashPattern {
        dash_1: Some(20),
        ..Default::default()
    };

    // Draw first line
    current_layer.set_outline_color(outline_color);
    current_layer.set_outline_thickness(10.0);
    current_layer.add_line(line1);

    // Triangle shape
    // Note: Line is invisible by default, the previous method of
    // constructing a line is recommended!
    let line2 = Polygon {
        rings: vec![vec![
            (Point::new(Mm(150.0), Mm(150.0)), false),
            (Point::new(Mm(150.0), Mm(250.0)), false),
            (Point::new(Mm(350.0), Mm(250.0)), false),
        ]],
        mode: PaintMode::FillStroke,
        winding_order: WindingOrder::NonZero,
    };

    let fill_color_2 = Color::Cmyk(Cmyk::new(0.0, 0.0, 0.0, 0.0, None));
    let outline_color_2 = Color::Greyscale(Greyscale::new(0.45, None));

    // More advanced graphical options
    current_layer.set_overprint_stroke(true);
    current_layer.set_blend_mode(BlendMode::Seperable(SeperableBlendMode::Multiply));
    current_layer.set_line_dash_pattern(dash_pattern);
    current_layer.set_line_cap_style(LineCapStyle::Round);
    current_layer.set_line_join_style(LineJoinStyle::Round);
    current_layer.set_fill_color(fill_color_2);
    current_layer.set_outline_color(outline_color_2);
    current_layer.set_outline_thickness(15.0);

    // draw second line
    current_layer.add_polygon(line2);

    // quad clip - note: FIRST SET THE CLIP, then paint the path
    current_layer.save_graphics_state();
    let line4 = Polygon {
        rings: vec![points1.clone()],
        mode: PaintMode::Clip,
        winding_order: WindingOrder::NonZero,
    };

    current_layer.add_polygon(line4);

    let points5 = vec![
        (Point::new(Mm(150.0), Mm(150.0)), false),
        (Point::new(Mm(150.0), Mm(250.0)), false),
        (Point::new(Mm(350.0), Mm(250.0)), false),
    ];

    let line3 = Line {
        points: points5.clone(),
        is_closed: true,
    };

    let outline_color2 = Color::Rgb(Rgb::new(1.0, 0.75, 0.0, None));
    current_layer.set_line_dash_pattern(LineDashPattern::default());
    current_layer.set_outline_color(outline_color2);
    current_layer.set_outline_thickness(5.0);
    current_layer.add_line(line3);

    current_layer.restore_graphics_state(); // unset clip again for further operations

    // If this is successful, you should see a PDF two shapes, one rectangle
    // and a dotted line
    doc.save(&mut BufWriter::new(
        File::create("test_graphics.pdf").unwrap(),
    ))
    .unwrap();
}
source

pub fn use_text<S>( &self, text: S, font_size: f32, x: Mm, y: Mm, font: &IndirectFontRef )
where S: Into<String>,

Add text to the file, x and y are measure in millimeter from the bottom left corner

If the given font is a built-in font and the given text contains characters that are not supported by the Windows-1252 encoding, these characters will be ignored.

Examples found in repository?
examples/rect.rs (line 27)
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/hyperlink.rs (line 14)
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/annotations.rs (line 42)
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 20)
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_operation<T>(&self, op: T)
where T: Into<Operation>,

Add an operation

This is the low level function used by other function in this struct. Notice that Operation is part of the lopdf crate, which is re-exported by this crate.

source

pub fn add_rect(&self, rect: Rect)

Add a rectangle to the layer.

Examples found in repository?
examples/rect.rs (line 15)
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();
}

Trait Implementations§

source§

impl Clone for PdfLayerReference

source§

fn clone(&self) -> PdfLayerReference

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for PdfLayerReference

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

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> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. 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.