///|
/// Build the cpdftype element stream for a table of contents.
///
/// `page_width` and `margin` are the already-resolved first-page dimensions
/// from cpdftoc's caller. Actual page typesetting and insertion remain a
/// separate step.
pub fn PdfDocument::toc_type_elements(
self : PdfDocument,
fontpack : PdfFontPack,
font_size : Double,
title : BytesView,
dotleader : Bool,
process_struct_tree : Bool,
labels : ArrayView[@label.PdfPageLabel],
bookmarks : ArrayView[@bookmark.PdfBookmark],
page_width : Double,
margin : Double,
) -> Array[PdfTypeElement] raise @core.PdfError {
let title_elements = pdf_toc_title_elements(
fontpack, font_size, title, process_struct_tree,
)
let body : Array[PdfTypeElement] = []
pdf_toc_append_elements(body, title_elements)
for bookmark in bookmarks {
pdf_toc_append_elements(
body,
self.pdf_toc_bookmark_elements(
fontpack, font_size, labels, page_width, margin, dotleader, process_struct_tree,
bookmark,
),
)
}
let output : Array[PdfTypeElement] = [
pdf_toc_first_font(body),
PdfTypeBeginDocument,
]
pdf_toc_append_elements(output, body)
output
}
///|
/// Compatibility wrapper for `PdfDocument::toc_type_elements`.
pub fn pdf_toc_type_elements(
document : PdfDocument,
fontpack : PdfFontPack,
font_size : Double,
title : BytesView,
dotleader : Bool,
process_struct_tree : Bool,
labels : ArrayView[@label.PdfPageLabel],
bookmarks : ArrayView[@bookmark.PdfBookmark],
page_width : Double,
margin : Double,
) -> Array[PdfTypeElement] raise @core.PdfError {
document.toc_type_elements(
fontpack, font_size, title, dotleader, process_struct_tree, labels, bookmarks,
page_width, margin,
)
}
///|
/// Typeset a TOC element stream into pages using cpdftoc's first-page geometry.
///
/// The first page's `/MediaBox` defines the paper size and base margin, while an
/// inherited `/CropBox`, when present, narrows the content width, offsets the
/// margins, and is copied onto the generated TOC pages. This helper does not
/// insert the pages into the source document.
pub fn PdfDocument::toc_typeset_pages(
self : PdfDocument,
fontpack : PdfFontPack,
font_size : Double,
title : BytesView,
dotleader : Bool,
process_struct_tree : Bool,
labels : ArrayView[@label.PdfPageLabel],
bookmarks : ArrayView[@bookmark.PdfBookmark],
) -> PdfTypeTypesetResult raise @core.PdfError {
let source_pages = self.pages_of_pagetree()
guard source_pages.length() > 0 else {
raise SoftError("toc_typeset_pages: no pages")
}
let first_page = source_pages[0]
let media = self.parse_rectangle(first_page.mediabox)
let media_width = media.max_x - media.min_x
let media_height = media.max_y - media.min_y
let paper = @geometry.paper_size_make(PdfPoint, media_width, media_height)
let margin = double_min(media_width, media_height) * 0.1
let cropbox = match
self.lookup_direct(pdf_page_cropbox_key(), first_page.rest) {
Some(raw_cropbox) => Some(self.parse_rectangle(raw_cropbox))
None => None
}
let page_width = match cropbox {
Some(crop) => crop.max_x - crop.min_x
None => media_width
}
let (left_margin, right_margin, bottom_margin, top_margin) = match cropbox {
Some(crop) =>
(
crop.min_x + margin,
media.max_x - crop.max_x + margin,
crop.min_y + margin,
media.max_y - crop.max_y + margin,
)
None => (margin, margin, margin, margin)
}
let elements = self.toc_type_elements(
fontpack, font_size, title, dotleader, process_struct_tree, labels, bookmarks,
page_width, margin,
)
let result = self.pdf_type_typeset(
process_struct_tree, left_margin, right_margin, top_margin, bottom_margin, paper,
elements,
)
let cropbox_object = match cropbox {
Some(crop) => Some(pdf_toc_rectangle_object(crop))
None => None
}
{ ..result, pages: pdf_toc_cropbox_pages(result.pages, cropbox_object), }
}
///|
/// Compatibility wrapper for `PdfDocument::toc_typeset_pages`.
pub fn pdf_toc_typeset_pages(
document : PdfDocument,
fontpack : PdfFontPack,
font_size : Double,
title : BytesView,
dotleader : Bool,
process_struct_tree : Bool,
labels : ArrayView[@label.PdfPageLabel],
bookmarks : ArrayView[@bookmark.PdfBookmark],
) -> PdfTypeTypesetResult raise @core.PdfError {
document.toc_typeset_pages(
fontpack, font_size, title, dotleader, process_struct_tree, labels, bookmarks,
)
}