///|
fn PdfDocument::pdf_page_stretch_matrix(
self : PdfDocument,
page : @page.PdfPage,
target_width : Double,
target_height : Double,
) -> @geometry.TransformMatrix raise @core.PdfError {
let bounds = self.pdf_page_scale_bounds(page)
let source_width = bounds.max_x - bounds.min_x
let source_height = bounds.max_y - bounds.min_y
if source_width <= 0.0 || source_height <= 0.0 {
raise BadNumberArgument("stretch_pages: zero-sized pages are invalid")
}
@geometry.transform_scale(
@geometry.point2(0.0, 0.0),
target_width / source_width,
target_height / source_height,
)
}
///|
/// Stretch selected pages to target sizes without preserving aspect ratio.
///
/// This ports cpdfpage's `stretch`: the current `/CropBox` when present,
/// otherwise `/MediaBox`, determines the source width and height. Page boxes,
/// content streams, annotations, pattern matrices, and destination coordinates
/// are transformed by the computed x/y scale.
pub fn PdfDocument::stretch_pages(
self : PdfDocument,
page_numbers : ArrayView[Int],
sizes : ArrayView[(Double, Double)],
fast? : Bool = false,
) -> PdfDocument raise @core.PdfError {
pdf_page_box_validate_page_numbers(
page_numbers,
self.endpage(),
"stretch_pages",
)
if page_numbers.length() != sizes.length() {
raise BadPageSpecification(
"stretch_pages: size count must match page count",
)
}
let pages = self.pages_of_pagetree()
let page_indexes = pdf_page_scale_pair_index_map(page_numbers)
let rewritten : Array[@page.PdfPage] = Array(capacity=pages.length())
let matrices : Array[(Int, @geometry.TransformMatrix)] = Array(
capacity=page_numbers.length(),
)
for index in 0.. {
let size = sizes[size_index]
let matrix = self.pdf_page_stretch_matrix(pages[index], size.0, size.1)
rewritten.push(
self.pdf_page_scale_page_data(pages[index], matrix, fast),
)
matrices.push((page_number, matrix))
}
None => rewritten.push(pages[index])
}
}
self.change_pages(rewritten, change_references=true, matrices~)
}
///|
/// Compatibility wrapper for `PdfDocument::stretch_pages`.
pub fn pdf_stretch_pages(
document : PdfDocument,
page_numbers : ArrayView[Int],
sizes : ArrayView[(Double, Double)],
fast? : Bool = false,
) -> PdfDocument raise @core.PdfError {
document.stretch_pages(page_numbers, sizes, fast~)
}
///|
/// Stretch selected pages using cpdf's absolute page-indexed size list.
pub fn PdfDocument::stretch(
self : PdfDocument,
page_numbers : ArrayView[Int],
sizes : ArrayView[(Double, Double)],
fast? : Bool = false,
) -> PdfDocument raise @core.PdfError {
let pages = self.pages_of_pagetree()
pdf_page_box_validate_page_numbers(page_numbers, pages.length(), "stretch")
pdf_page_scale_validate_page_indexed_pairs(
"stretch",
"size",
pages.length(),
sizes,
)
self.stretch_pages(
page_numbers,
pdf_page_scale_select_page_indexed_pairs(page_numbers, sizes),
fast~,
)
}
///|
/// Compatibility wrapper matching cpdfpage's `stretch` value argument order.
pub fn pdf_stretch(
sizes : ArrayView[(Double, Double)],
document : PdfDocument,
page_numbers : ArrayView[Int],
fast? : Bool = false,
) -> PdfDocument raise @core.PdfError {
document.stretch(page_numbers, sizes, fast~)
}