genpdf states it is based on printpdf.
I am not able to find any direct method to print straight lines .However I do see them in print pdf.
I am able to generate pdf using genpdf.I have need to print a straight line.How do I achieve that?
I believe you need to create a new type that implements genpdf::Element
and then you can use the Area
passed to render
to draw a line.
I am new to rust .Could you help me with implementation and usage .
I believe I can use the below code however I am not sure how to pass draw line params.
I tried this but it fails: doc.push(elements::FramedElement::new("text").framed());
impl<E: Element> Element for FramedElement<E> {
fn render(
&mut self,
context: &Context,
area: render::Area<'_>,
style: Style,
) -> Result<RenderResult, Error> {
let result = self.element.render(context, area.clone(), style)?;
area.draw_line(
vec![Position::default(), Position::new(0, result.size.height)],
style,
);
area.draw_line(
vec![
Position::new(area.size().width, 0),
Position::new(area.size().width, result.size.height),
],
style,
);
if self.is_first {
area.draw_line(
vec![Position::default(), Position::new(area.size().width, 0)],
style,
);
}
if !result.has_more {
area.draw_line(
vec![
Position::new(0, result.size.height),
Position::new(area.size().width, result.size.height),
],
style,
);
}
self.is_first = false;
Ok(result)
}
}
I modified the demo with an example line draw element
use genpdf::{
elements,
fonts::{self},
style, Alignment, Element, Position, RenderResult, Size,
};
fn main() {
let mut doc = genpdf::Document::new(
fonts::from_files("fonts/liberation", "LiberationSans", None).unwrap(),
);
doc.set_title("Test");
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 Demo Document")
.aligned(Alignment::Center)
.styled(style::Style::new().bold().with_font_size(20)),
);
doc.push(elements::Break::new(1.5));
doc.push(elements::Paragraph::new(
"This document demonstrates how the genpdf crate generates PDF documents. I removed a bunch of code from the demo and now it looks silly",
));
doc.push(Line);
doc.render_to_file("output.pdf").unwrap();
}
struct Line;
impl Element for Line {
fn render(
&mut self,
_: &genpdf::Context,
area: genpdf::render::Area<'_>,
style: style::Style,
) -> Result<genpdf::RenderResult, genpdf::error::Error> {
area.draw_line(
vec![
Position {
x: 0.into(),
y: 0.into(),
},
Position {
x: area.size().width,
y: 0.into(),
},
],
style.with_color(style::Color::Rgb(0, 0, 255)),
);
Ok(RenderResult {
size: Size {
width: area.size().width,
height: 1.into(),
},
has_more: false,
})
}
}
I downloaded the example font from here because I didn't feel like figuring out how to make it read fonts on windows
Here's a screenshot of the result
The drawing capabilities of genpdf
seem pretty limited, so if you're trying to draw something more complicated you might be out of luck at the moment. printpdf
seems to have quite a bit more functionality that isn't exposed in genpdf
at the moment.
Awesome & thank you
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.