Struct printpdf::PdfLayerReference
source · 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
impl PdfLayerReference
sourcepub fn add_line(&self, line: Line)
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?
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();
}
sourcepub fn add_polygon(&self, poly: Polygon)
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?
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
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();
}
sourcepub fn add_link_annotation<T>(&self, annotation: T) -> LinkAnnotationRefwhere
T: Into<LinkAnnotation>,
pub fn add_link_annotation<T>(&self, annotation: T) -> LinkAnnotationRefwhere
T: Into<LinkAnnotation>,
Examples found in repository?
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();
}
sourcepub fn begin_text_section(&self)
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?
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();
}
sourcepub fn end_text_section(&self)
pub fn end_text_section(&self)
Ends a new text section
Only valid if begin_text_section
has been called
Examples found in repository?
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();
}
sourcepub fn set_fill_color(&self, fill_color: Color)
pub fn set_fill_color(&self, fill_color: Color)
Set the current fill color for the layer
Examples found in repository?
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
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();
}
sourcepub fn set_font(&self, font: &IndirectFontRef, font_size: f32)
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?
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();
}
sourcepub fn set_outline_color(&self, color: Color)
pub fn set_outline_color(&self, color: Color)
Set the current line / outline color for the layer
Examples found in repository?
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
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();
}
sourcepub fn set_overprint_fill(&self, overprint: bool)
pub fn set_overprint_fill(&self, overprint: bool)
Set the overprint mode of the stroke color to true (overprint) or false (no overprint)
sourcepub fn set_overprint_stroke(&self, overprint: bool)
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?
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();
}
sourcepub fn set_blend_mode(&self, blend_mode: BlendMode)
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?
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();
}
sourcepub fn set_outline_thickness(&self, outline_thickness: f32)
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?
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();
}
sourcepub fn set_line_join_style(&self, line_join: LineJoinStyle)
pub fn set_line_join_style(&self, line_join: LineJoinStyle)
Set the current line join style for outlines
Examples found in repository?
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();
}
sourcepub fn set_line_cap_style(&self, line_cap: LineCapStyle)
pub fn set_line_cap_style(&self, line_cap: LineCapStyle)
Set the current line join style for outlines
Examples found in repository?
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();
}
sourcepub fn set_line_dash_pattern(&self, dash_pattern: LineDashPattern)
pub fn set_line_dash_pattern(&self, dash_pattern: LineDashPattern)
Set the current line join style for outlines
Examples found in repository?
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();
}
sourcepub fn set_ctm(&self, ctm: CurTransMat)
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
sourcepub fn set_text_matrix(&self, tm: TextMatrix)
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?
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();
}
sourcepub fn set_text_cursor(&self, x: Mm, y: Mm)
pub fn set_text_cursor(&self, x: Mm, y: Mm)
Sets the position where the text should appear
Examples found in repository?
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();
}
sourcepub fn add_line_break(&self)
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?
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();
}
sourcepub fn set_line_height(&self, height: f32)
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?
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();
}
sourcepub fn set_character_spacing(&self, spacing: f32)
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?
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();
}
sourcepub fn set_word_spacing(&self, spacing: f32)
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?
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();
}
sourcepub fn set_text_scaling(&self, scaling: f32)
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
sourcepub fn set_line_offset(&self, offset: f32)
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?
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();
}
sourcepub fn set_text_rendering_mode(&self, mode: TextRenderingMode)
pub fn set_text_rendering_mode(&self, mode: TextRenderingMode)
Examples found in repository?
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();
}
sourcepub fn write_codepoints<I>(&self, codepoints: I)where
I: IntoIterator<Item = u16>,
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
sourcepub fn write_positioned_codepoints<I>(&self, codepoints: I)
pub fn write_positioned_codepoints<I>(&self, codepoints: I)
Add text to the file at the current position by specifying font codepoints with additional kerning offset
sourcepub fn write_text<S>(&self, text: S, font: &IndirectFontRef)
pub fn write_text<S>(&self, text: S, font: &IndirectFontRef)
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?
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();
}
sourcepub fn save_graphics_state(&self)
pub fn save_graphics_state(&self)
Saves the current graphic state
Examples found in repository?
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();
}
sourcepub fn restore_graphics_state(&self)
pub fn restore_graphics_state(&self)
Restores the previous graphic state
Examples found in repository?
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();
}
sourcepub fn use_text<S>(
&self,
text: S,
font_size: f32,
x: Mm,
y: Mm,
font: &IndirectFontRef
)
pub fn use_text<S>( &self, text: S, font_size: f32, x: Mm, y: Mm, font: &IndirectFontRef )
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?
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
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();
}
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();
}
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();
}
sourcepub fn add_operation<T>(&self, op: T)
pub fn add_operation<T>(&self, op: T)
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.
sourcepub fn add_rect(&self, rect: Rect)
pub fn add_rect(&self, rect: Rect)
Add a rectangle to the layer.
Examples found in repository?
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
impl Clone for PdfLayerReference
source§fn clone(&self) -> PdfLayerReference
fn clone(&self) -> PdfLayerReference
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read more