use std::env;
use genpdf::Alignment;
use genpdf::Element as _;
use genpdf::{elements, fonts, style};
const FONT_DIRS: &[&str] = &[
"/usr/share/fonts/liberation",
"/usr/share/fonts/truetype/liberation",
];
const DEFAULT_FONT_NAME: &'static str = "LiberationSans";
const IMAGE_PATH_JPG: &'static str = "examples/images/test_image.jpg";
const IMAGE_PATH_BMP: &'static str = "examples/images/test_image.bmp";
const IMAGE_PATH_PNG: &'static str = "examples/images/test_image.png";
fn main() {
let args: Vec<_> = env::args().skip(1).collect();
if args.len() != 1 {
panic!("Missing argument: output file");
}
let output_file = &args[0];
let font_dir = FONT_DIRS
.iter()
.filter(|path| std::path::Path::new(path).exists())
.next()
.expect("Could not find font directory");
let default_font =
fonts::from_files(font_dir, DEFAULT_FONT_NAME, Some(fonts::Builtin::Helvetica))
.expect("Failed to load the default font family");
let mut doc = genpdf::Document::new(default_font);
doc.set_title("genpdf Demo Document");
doc.set_minimal_conformance();
doc.set_line_spacing(1.25);
let mut decorator = genpdf::SimplePageDecorator::new();
decorator.set_margins(10);
decorator.set_header(|page| {
let mut layout = elements::LinearLayout::vertical();
if page > 1 {
layout.push(
elements::Paragraph::new(format!("Page {}", page)).aligned(Alignment::Center),
);
layout.push(elements::Break::new(1));
}
layout.styled(style::Style::new().with_font_size(10))
});
doc.set_page_decorator(decorator);
doc.push(
elements::Paragraph::new("genpdf Image Tests")
.aligned(Alignment::Center)
.styled(style::Style::new().bold().with_font_size(20)),
);
doc.push(elements::Break::new(1.5));
doc.push(elements::Paragraph::new(
"You may also: override the position, dpi, and/or default line-breaks, etc. See image here =>"
));
doc.push(
elements::Image::from_path(IMAGE_PATH_JPG)
.expect("Unable to load alt image")
.with_position(genpdf::Position::new(170, -10)) .with_clockwise_rotation(90.0),
);
doc.push(elements::Break::new(2));
doc.push(elements::Paragraph::new(
"Table with image format/scaling tests:",
));
let mut img_table = elements::TableLayout::new(vec![2, 2, 2, 2]);
img_table.set_cell_decorator(elements::FrameCellDecorator::new(true, true, false));
img_table
.row()
.element(elements::Text::new("Format").padded(1))
.element(elements::Text::new("1:1").padded(1))
.element(elements::Text::new("Half Size").padded(1))
.element(elements::Text::new("Double Size").padded(1))
.push()
.expect("Invalid row");
for (ftype, path) in vec![
("BMP", IMAGE_PATH_BMP),
("JPG", IMAGE_PATH_JPG),
("PNG", IMAGE_PATH_PNG),
] {
let img = elements::Image::from_path(path).expect("invalid image");
img_table
.row()
.element(elements::Paragraph::new(ftype).padded(1))
.element(img.clone().framed().padded(1))
.element(
img.clone()
.with_scale(genpdf::Scale::new(0.5, 0.5))
.framed()
.padded(1),
)
.element(
img.clone()
.with_scale(genpdf::Scale::new(2, 2))
.framed()
.padded(1),
)
.push()
.expect("Invalid row");
}
doc.push(img_table);
doc.push(elements::Break::new(2));
doc.push(elements::Paragraph::new(
"Table with image rotation/offset calculation tests:",
));
let mut rot_table = elements::TableLayout::new(vec![2, 2, 2, 2, 2, 2, 2]);
rot_table.set_cell_decorator(elements::FrameCellDecorator::new(true, true, false));
rot_table
.row()
.element(elements::Text::new("Rot").padded(1))
.element(elements::Text::new("30°").padded(1))
.element(elements::Text::new("45°").padded(1))
.element(elements::Text::new("90°").padded(1))
.element(elements::Text::new("120°").padded(1))
.element(elements::Text::new("150°").padded(1))
.element(elements::Text::new("180°").padded(1))
.push()
.expect("Invalid row");
let img = elements::Image::from_path(IMAGE_PATH_JPG).expect("invalid image");
rot_table
.row()
.element(elements::Text::new("Positive").padded(1))
.element(img.clone().with_clockwise_rotation(30.0).framed().padded(1))
.element(img.clone().with_clockwise_rotation(45.0).framed().padded(1))
.element(img.clone().with_clockwise_rotation(90.0).framed().padded(1))
.element(
img.clone()
.with_clockwise_rotation(120.0)
.framed()
.padded(1),
)
.element(
img.clone()
.with_clockwise_rotation(150.0)
.framed()
.padded(1),
)
.element(
img.clone()
.with_clockwise_rotation(180.0)
.framed()
.padded(1),
)
.push()
.expect("Invalid row");
rot_table
.row()
.element(elements::Text::new("Negative").padded(1))
.element(
img.clone()
.with_clockwise_rotation(-30.0)
.framed()
.padded(1),
)
.element(
img.clone()
.with_clockwise_rotation(-45.0)
.framed()
.padded(1),
)
.element(
img.clone()
.with_clockwise_rotation(-90.0)
.framed()
.padded(1),
)
.element(
img.clone()
.with_clockwise_rotation(-120.0)
.framed()
.padded(1),
)
.element(
img.clone()
.with_clockwise_rotation(-150.0)
.framed()
.padded(1),
)
.element(
img.clone()
.with_clockwise_rotation(-180.0)
.framed()
.padded(1),
)
.push()
.expect("Invalid row");
doc.push(rot_table);
doc.render_to_file(output_file)
.expect("Failed to write output file");
}