// lib/editor/pdf/pdf_document_source.dart // // A minimal abstraction over a paginated document (a pdfrx PdfDocument in // production) consumed by the layout + render layer. Keeping the layout math // behind this seam lets continuous-single windowing (layout/page_viewport.dart) // and tiling be unit-tested against a fake source — no pdfium, no GPU, no real // PDF (the production pdfrx adapter is a thin device-side wrapper added with the // viewport widget / page_tile renderer, which are device-gated). import 'dart:ui' show Size; import '../layout/page_viewport.dart'; /// Read-only page geometry for a paginated document. abstract class PageDocumentSource { /// Number of pages (>= 0). int get pageCount; /// Intrinsic size of page [index] in PDF points (width/height > 0). Size pageSize(int index); } /// Builds continuous-single stacking metrics by fitting every page to a single /// [columnWidth] (fit-to-width, the continuous-single mode): each page's /// laid-out height is `columnWidth × (pageHeight / pageWidth)`, preserving its /// aspect ratio. [gap] is inserted between pages (content units). /// /// Pages reporting a non-positive width are treated as zero-height (defensive; /// real pages always have a positive width) so a malformed page can't throw. /// /// Returns the metrics needed by [PageStackMetrics.visibleRange]; pair this with /// the device-gated page-mounting widget. PageStackMetrics pageStackMetricsForWidth( PageDocumentSource source, double columnWidth, { double gap = 0.0, }) { assert(columnWidth >= 0); final heights = List.generate(source.pageCount, (i) { final size = source.pageSize(i); if (size.width <= 0) return 0.0; return columnWidth * (size.height / size.width); }); return PageStackMetrics(pageHeights: heights, gap: gap); }