~mglolenstine


#65 Page numbering 2 years ago

Comment by ~mglolenstine on ~ireas/genpdf-rs

I did it this way. I opened a new area layer and padded the previous one by 10 so that I had 10 mm of space for the footer. Then I rendered the footer element at the bottom of the new layer (padding it to the bottom) and shortened the original area if the footer was too long.

#[derive(Default, Clone, Debug)]
pub struct CustomPageDecorator {
    page: usize,
}

impl CustomPageDecorator {
    pub fn generate_footer(&self, top_padding: genpdf::Mm) -> Box<dyn Element> {
        Box::new(
            Paragraph::new(format!("Page {}", self.page))
                .aligned(genpdf::Alignment::Right)
                .styled(genpdf::style::Style::new().with_font_size(8))
                .padded(genpdf::Margins::trbl(top_padding, 0, 0, 0)),
        )
    }
}

And then called it like so

impl PageDecorator for CustomPageDecorator {
    fn decorate_page<'a>(
        &mut self,
        context: &genpdf::Context,
        mut area: genpdf::render::Area<'a>,
        style: genpdf::style::Style,
    ) -> Result<genpdf::render::Area<'a>, genpdf::error::Error> {
        self.page += 1;
        let mut footer_area = area.next_layer();

        //? Header
        let mut element = Paragraph::new("Header");
        area.add_margins(10);
        let result = element.render(context, area.clone(), style)?;
        area.add_offset(Position::new(0, result.size.height + genpdf::Mm::from(5)));

        //? Footer
        footer_area.add_margins(Margins::trbl(0, 10, 0, 10));
        let height = footer_area.size().height;
        let mut element = self.generate_footer(height - genpdf::Mm::from(11));
        let result = element.render(context, footer_area.clone(), style)?;
        let footer_size = result.size.height - height + genpdf::Mm::from(15);
        area.set_height(area.size().height - footer_size);

        Ok(area)
    }
}

So far it works great, could probably be improved.