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.