"""Shared PDF footer canvas: bottom-right `current / total` page counter.""" from __future__ import annotations from reportlab.lib import colors from reportlab.pdfgen import canvas class NumberedCanvas(canvas.Canvas): """Canvas that renders `N / total` footer on every page.""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._saved_page_states: list[dict] = [] def showPage(self) -> None: self._saved_page_states.append(dict(self.__dict__)) self._startPage() def save(self) -> None: total = len(self._saved_page_states) for state in self._saved_page_states: self.__dict__.update(state) self._draw_page_footer(total) super().showPage() super().save() def _draw_page_footer(self, total_pages: int) -> None: self.saveState() self.setFillColor(colors.HexColor("#BDBDBD")) self.setFont("Helvetica", 8) label = f"{self._pageNumber} / {total_pages}" x = self._pagesize[0] - 1.5 * 28.3465 # ~1.5 cm from right y = 0.9 * 28.3465 # ~0.9 cm from bottom self.drawRightString(x, y, label) self.restoreState()