///|
fn pdf_page_scale_to_fit_rotate_should_rotate(
bounds : @geometry.PdfRectangle,
target_width : Double,
target_height : Double,
) -> Bool {
// cpdf uses max_x - min_y for this historical orientation test.
let page_width = bounds.max_x - bounds.min_y
let page_height = bounds.max_y - bounds.min_y
(page_width < page_height && target_width > target_height) ||
(page_width > page_height && target_width < target_height)
}
///|
fn PdfDocument::pdf_page_scale_to_fit_rotate_page(
self : PdfDocument,
page : @page.PdfPage,
target_width : Double,
target_height : Double,
rotation : Int,
) -> @page.PdfPage raise @core.PdfError {
if pdf_page_scale_to_fit_rotate_should_rotate(
self.pdf_page_scale_bounds(page),
target_width,
target_height,
) {
{
..page,
rotate: @page.pdf_page_rotation_of_int(
@page.pdf_page_int_of_rotation(page.rotate) + rotation,
),
}
} else {
page
}
}
///|
/// Conditionally rotate selected pages to better fit target sizes, then upright
/// the same pages.
///
/// This ports cpdf's `scale_to_fit_rotate`: if a page and its target size have
/// opposite orientation, the page dictionary rotation is adjusted by `rotation`;
/// `upright_pages` is then applied to the selected range.
pub fn PdfDocument::scale_to_fit_rotate_pages(
self : PdfDocument,
page_numbers : ArrayView[Int],
sizes : ArrayView[(Double, Double)],
rotation : Int,
fast? : Bool = false,
) -> PdfDocument raise @core.PdfError {
pdf_page_box_validate_page_numbers(
page_numbers,
self.endpage(),
"scale_to_fit_rotate_pages",
)
if page_numbers.length() != sizes.length() {
raise BadPageSpecification(
"scale_to_fit_rotate_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())
for index in 0.. {
let size = sizes[size_index]
rewritten.push(
self.pdf_page_scale_to_fit_rotate_page(
pages[index],
size.0,
size.1,
rotation,
),
)
}
None => rewritten.push(pages[index])
}
}
let rotated = self.change_pages(rewritten, change_references=true)
rotated.upright_pages(page_numbers, fast~)
}
///|
/// Compatibility wrapper for `PdfDocument::scale_to_fit_rotate_pages`.
pub fn pdf_scale_to_fit_rotate_pages(
document : PdfDocument,
page_numbers : ArrayView[Int],
sizes : ArrayView[(Double, Double)],
rotation : Int,
fast? : Bool = false,
) -> PdfDocument raise @core.PdfError {
document.scale_to_fit_rotate_pages(page_numbers, sizes, rotation, fast~)
}
///|
/// Conditionally rotate selected pages using cpdf's absolute page-indexed size
/// list, then upright the same pages.
pub fn PdfDocument::scale_to_fit_rotate(
self : PdfDocument,
page_numbers : ArrayView[Int],
sizes : ArrayView[(Double, Double)],
rotation : Int,
fast? : Bool = false,
) -> PdfDocument raise @core.PdfError {
let pages = self.pages_of_pagetree()
pdf_page_box_validate_page_numbers(
page_numbers,
pages.length(),
"scale_to_fit_rotate",
)
pdf_page_scale_validate_page_indexed_pairs(
"scale_to_fit_rotate",
"size",
pages.length(),
sizes,
)
self.scale_to_fit_rotate_pages(
page_numbers,
pdf_page_scale_select_page_indexed_pairs(page_numbers, sizes),
rotation,
fast~,
)
}
///|
/// Compatibility wrapper matching cpdfpage's `scale_to_fit_rotate` order.
pub fn pdf_scale_to_fit_rotate(
sizes : ArrayView[(Double, Double)],
rotation : Int,
document : PdfDocument,
page_numbers : ArrayView[Int],
fast? : Bool = false,
) -> PdfDocument raise @core.PdfError {
document.scale_to_fit_rotate(page_numbers, sizes, rotation, fast~)
}