save method
Composes the tree and writes a PDF 1.7 file (synchronous).
Implementation
Uint8List save() {
final ThemeData theme = this.theme ?? const ThemeData();
final Context seed = Context(
document: this,
pageFormat: PdfPageFormat.a4,
theme: theme,
textDirection: TextDirection.ltr,
);
// Pass 1: collect text + headings (TOC still empty).
seed.pagesCount = _measure(seed);
_freezeHeadings(seed);
if (font != null && seed.usedCodePoints.isNotEmpty) {
seed.subset = FontSubsetter(font!).subset(seed.usedCodePoints);
}
if (fontBold != null && seed.usedCodePoints.isNotEmpty) {
seed.boldSubset = FontSubsetter(fontBold!).subset(seed.usedCodePoints);
}
// Pass 2: TOC has entries; recount pages and restamp heading numbers.
seed.pagesCount = _measure(seed);
_freezeHeadings(seed);
seed.pagesCount = _measure(seed);
// Second pass placed headings with the TOC present. Keep those positions.
_freezeHeadings(seed);
final _PageSink paint = _PageSink(paint: true);
seed.pageNumber = 1;
seed.headings.clear();
seed.anchors.clear();
for (final Page page in _pages) {
page._compose(seed, paint);
}
final PdfDocument pdf = PdfDocument(title: title, author: author);
for (final PdfPage built in paint.pages) {
pdf.addPage(built);
}
for (final PwHeading heading in seed.headings) {
if (heading.level <= 2 && pdf.pages.isNotEmpty) {
pdf.addOutline(
PdfOutlineItem(
title: heading.title,
pageIndex: (heading.pageNumber - 1).clamp(0, pdf.pages.length - 1),
destY: heading.destY,
),
);
}
}
final List<PdfEmbeddedFace> faces = <PdfEmbeddedFace>[
if (seed.subset != null && font != null)
PdfEmbeddedFace(
subset: seed.subset!,
source: font!,
resourceName: 'F1',
),
if (seed.boldSubset != null && fontBold != null)
PdfEmbeddedFace(
subset: seed.boldSubset!,
source: fontBold!,
resourceName: 'F3',
),
];
return faces.isEmpty
? pdf.save(subset: seed.subset, font: font)
: pdf.save(faces: faces);
}