Genpdf print straight line with colour

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?

1 Like

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.