///|
fn pdf_impose_validate_transform_inputs(
x : Int,
y : Int,
count : Int,
) -> Unit raise PdfError {
if x <= 0 || y <= 0 {
raise BadNumberArgument("impose: x and y must be positive")
}
if count < 0 {
raise BadNumberArgument("impose: page count must be non-negative")
}
}
///|
fn pdf_impose_order(
row : Int,
col : Int,
x : Int,
y : Int,
rtl : Bool,
btt : Bool,
) -> (Int, Int) {
(if btt { y - row - 1 } else { row }, if rtl { x - col - 1 } else { col })
}
///|
fn pdf_impose_adjusted_row(
original_row : Int,
y : Int,
final_full_rows : Int,
remaining : Int,
center : Bool,
) -> Int {
if center && remaining <= final_full_rows {
let final_empty_rows = y - final_full_rows
original_row + (y - 1 - 1 - final_empty_rows / 2)
} else {
original_row
}
}
///|
fn pdf_impose_adjusted_col(
original_col : Int,
x : Int,
final_full_cols : Int,
remaining : Int,
center : Bool,
) -> Int {
if center && remaining <= final_full_cols {
let final_empty_cols = x - final_full_cols
original_col + (x - 1 - 1 - final_empty_cols / 2)
} else {
original_col
}
}
///|
fn pdf_impose_translate(
x : Int,
rtl : Bool,
btt : Bool,
cent_extra_x : Double,
cent_extra_y : Double,
fit_extra_hspace : Double,
fit_extra_vspace : Double,
row : Int,
col : Int,
px : Double,
py : Double,
) -> TransformMatrix {
let cex = if rtl { -cent_extra_x } else { cent_extra_x }
let cey = if btt { -cent_extra_y } else { cent_extra_y }
let space_col = if rtl { x - col - 1 } else { col }
let total_fit_extra_hspace = fit_extra_hspace * (space_col.to_double() + 1.0)
let total_fit_extra_vspace = fit_extra_vspace * (row.to_double() + 1.0)
transform_translate(
px + cex + total_fit_extra_hspace,
py + cey + total_fit_extra_vspace,
)
}
///|
fn PdfDocument::pdf_impose_make_margin(
self : PdfDocument,
output_mediabox : PdfObject,
margin : Double,
matrix : TransformMatrix,
) -> TransformMatrix raise PdfError {
if margin == 0.0 {
matrix
} else {
let box = self.parse_rectangle(output_mediabox)
let width = box.max_x - box.min_x
let height = box.max_y - box.min_y
if margin > width / 2.0 || margin > height / 2.0 {
raise BadNumberArgument("impose: margin would fill whole page")
}
let hfactor = (width - margin - margin) / width
let vfactor = (height - margin - margin) / height
let factor = if hfactor < vfactor { hfactor } else { vfactor }
let scale = transform_scale(point2(0.0, 0.0), factor, factor)
let shift = transform_translate(
(width - width * factor) / 2.0,
(height - height * factor) / 2.0,
)
transform_matrix_compose(shift, transform_matrix_compose(scale, matrix))
}
}
///|
fn PdfDocument::pdf_impose_transform_for_slot(
self : PdfDocument,
fit : Bool,
x : Int,
rtl : Bool,
btt : Bool,
margin : Double,
output_mediabox : PdfObject,
fit_extra_hspace : Double,
fit_extra_vspace : Double,
cent_extra_x : Double,
cent_extra_y : Double,
row : Int,
col : Int,
px : Double,
py : Double,
) -> TransformMatrix raise PdfError {
let matrix = pdf_impose_translate(
x, rtl, btt, cent_extra_x, cent_extra_y, fit_extra_hspace, fit_extra_vspace,
row, col, px, py,
)
if fit {
self.pdf_impose_make_margin(output_mediabox, margin, matrix)
} else {
matrix
}
}
///|
#warnings("-unused_field")
priv struct PdfImposeLayout {
pages_per_sheet : Int
x_slots : Int
y_slots : Int
output_mediabox : PdfObject
fit_extra_hspace : Double
fit_extra_vspace : Double
}
///|
fn pdf_impose_output_box(width : Double, height : Double) -> PdfObject {
PdfArray([PdfReal(0.0), PdfReal(0.0), PdfReal(width), PdfReal(height)])
}
///|
fn PdfDocument::pdf_impose_fit_layout(
self : PdfDocument,
x : Double,
y : Double,
page_width : Double,
page_height : Double,
) -> PdfImposeLayout raise PdfError {
ignore(self)
let across = @math.floor(x / page_width + 0.001).to_int()
let down = @math.floor(y / page_height + 0.001).to_int()
if across < 1 || down < 1 {
raise BadNumberArgument("impose: not even a single page would fit")
}
{
pages_per_sheet: across * down,
x_slots: across,
y_slots: down,
output_mediabox: pdf_impose_output_box(x, y),
fit_extra_hspace: (x - across.to_double() * page_width) /
(across.to_double() + 1.0),
fit_extra_vspace: (y - down.to_double() * page_height) /
(down.to_double() + 1.0),
}
}
///|
fn PdfDocument::pdf_impose_xy_layout(
self : PdfDocument,
x : Double,
y : Double,
margin : Double,
page_count : Int,
page_width : Double,
page_height : Double,
) -> PdfImposeLayout raise PdfError {
ignore(self)
let ix = x.to_int()
let iy = y.to_int()
if ix == 0 && iy == 0 {
raise BadNumberArgument("impose-xy: both dimensions cannot be zero")
}
let (pages_per_sheet, x_slots, y_slots) = if ix == 0 {
(page_count, page_count, 1)
} else if iy == 0 {
(page_count, 1, page_count)
} else {
(ix * iy, ix, iy)
}
let margin2 = margin * 2.0
let output_mediabox = if x == 0.0 {
pdf_impose_output_box(
page_width * page_count.to_double() + margin2,
page_height + margin2,
)
} else if y == 0.0 {
pdf_impose_output_box(
page_width + margin2,
page_height * page_count.to_double() + margin2,
)
} else {
pdf_impose_output_box(page_width * x + margin2, page_height * y + margin2)
}
{
pages_per_sheet,
x_slots,
y_slots,
output_mediabox,
fit_extra_hspace: 0.0,
fit_extra_vspace: 0.0,
}
}
///|
#warnings("-unused_value")
fn PdfDocument::pdf_impose_layout(
self : PdfDocument,
fit : Bool,
x : Double,
y : Double,
margin : Double,
page_count : Int,
mediabox : PdfObject,
) -> PdfImposeLayout raise PdfError {
let bounds = self.parse_rectangle(mediabox)
let page_width = bounds.max_x - bounds.min_x
let page_height = bounds.max_y - bounds.min_y
if fit {
self.pdf_impose_fit_layout(x, y, page_width, page_height)
} else {
self.pdf_impose_xy_layout(x, y, margin, page_count, page_width, page_height)
}
}
///|
fn pdf_impose_split_pages(
pages : ArrayView[PdfPage],
chunk_size : Int,
) -> Array[Array[PdfPage]] {
let chunks : Array[Array[PdfPage]] = []
let mut index = 0
while index < pages.length() {
let chunk : Array[PdfPage] = []
let stop = if index + chunk_size < pages.length() {
index + chunk_size
} else {
pages.length()
}
for page_index in index.. Array[(Int, Int)] {
let changes : Array[(Int, Int)] = []
for page_number in 1..<=page_count {
changes.push(
(page_number, (page_number + pages_per_sheet - 1) / pages_per_sheet),
)
}
changes
}
///|
fn PdfDocument::pdf_impose_preprocess(
self : PdfDocument,
fit : Bool,
spacing : Double,
line_width : Double,
fast : Bool,
) -> PdfDocument raise PdfError {
let end_page = self.endpage()
let all_pages = pdf_impose_all_pages(end_page)
self
.copy_page_box(
all_pages,
pdf_page_cropbox_key(),
pdf_page_mediabox_key(),
mediabox_if_missing=true,
)
.remove_cropping(all_pages)
.upright_pages(all_pages, fast~)
.pdf_impose_add_border(line_width, fast)
.pdf_impose_make_space(fit, spacing, fast)
}
///|
/// Impose pages into cpdf-style sheets.
///
/// In non-fit mode, `x` and `y` are grid dimensions; one of them may be zero to
/// stack all pages in the other direction. In fit mode, `x` and `y` are the
/// output page width and height, and the grid is calculated from the current
/// page size.
pub fn PdfDocument::impose(
self : PdfDocument,
x : Double,
y : Double,
fit? : Bool = false,
columns? : Bool = false,
rtl? : Bool = false,
btt? : Bool = false,
center? : Bool = false,
margin? : Double = 0.0,
spacing? : Double = 0.0,
line_width? : Double = 0.0,
fast? : Bool = false,
process_struct_tree? : Bool = false,
) -> PdfDocument raise PdfError {
let source = if process_struct_tree {
self.mark_all_as_artifact()
} else {
self
}
let original_page_count = source.endpage()
if original_page_count == 0 {
raise BadNumberArgument("impose: pages must not be empty")
}
let prepared = source.pdf_impose_preprocess(fit, spacing, line_width, fast)
let prepared_pages = prepared.pages_of_pagetree()
let layout = prepared.pdf_impose_layout(
fit,
x,
y,
margin,
original_page_count,
prepared_pages[0].mediabox,
)
let imposed_pages : Array[PdfPage] = []
for page_set in pdf_impose_split_pages(prepared_pages, layout.pages_per_sheet) {
imposed_pages.push(
prepared.pdf_impose_pages_core(
prepared.renumber_pages(page_set),
fit,
layout.x_slots,
layout.y_slots,
columns,
rtl,
btt,
center,
margin,
layout.output_mediabox,
fast,
layout.fit_extra_hspace,
layout.fit_extra_vspace,
),
)
}
let imposed = prepared.change_pages(
imposed_pages,
change_references=true,
changes=pdf_impose_page_reference_changes(
original_page_count,
layout.pages_per_sheet,
),
)
if fit {
imposed
} else {
let output_count = imposed.endpage()
imposed.shift_pages(
pdf_impose_all_pages(output_count),
pdf_impose_repeated_offsets(output_count, (margin, margin)),
fast~,
)
}
}
///|
/// Compatibility wrapper for `PdfDocument::impose`.
pub fn pdf_impose(
document : PdfDocument,
x : Double,
y : Double,
fit? : Bool = false,
columns? : Bool = false,
rtl? : Bool = false,
btt? : Bool = false,
center? : Bool = false,
margin? : Double = 0.0,
spacing? : Double = 0.0,
line_width? : Double = 0.0,
fast? : Bool = false,
process_struct_tree? : Bool = false,
) -> PdfDocument raise PdfError {
document.impose(
x,
y,
fit~,
columns~,
rtl~,
btt~,
center~,
margin~,
spacing~,
line_width~,
fast~,
process_struct_tree~,
)
}
///|
/// Legacy cpdf two-up stack operation.
///
/// This first imposes source pages in a 2x1 non-fit grid, then rotates the
/// imposed sheets by -90 degrees and uprights them into ordinary page geometry.
pub fn PdfDocument::twoup_stack(
self : PdfDocument,
fast? : Bool = false,
process_struct_tree? : Bool = false,
) -> PdfDocument raise PdfError {
let imposed = self.impose(2.0, 1.0, fast~, process_struct_tree~)
let all_pages = pdf_impose_all_pages(imposed.endpage())
imposed.rotate_pages(-90, all_pages).upright_pages(all_pages, fast~)
}
///|
/// Compatibility wrapper for `PdfDocument::twoup_stack`.
pub fn pdf_twoup_stack(
document : PdfDocument,
fast? : Bool = false,
process_struct_tree? : Bool = false,
) -> PdfDocument raise PdfError {
document.twoup_stack(fast~, process_struct_tree~)
}
///|
/// Legacy cpdf two-up operation.
///
/// This scales source pages down, imposes them 2x1, rotates/uprights the
/// imposed sheets, then scales each sheet back to the first page's original
/// size.
pub fn PdfDocument::twoup(
self : PdfDocument,
fast? : Bool = false,
process_struct_tree? : Bool = false,
) -> PdfDocument raise PdfError {
let pages = self.pages_of_pagetree()
if pages.length() == 0 {
raise BadNumberArgument("twoup: pages must not be empty")
}
let bounds = self.parse_rectangle(pages[0].mediabox)
let width = bounds.max_x - bounds.min_x
let height = bounds.max_y - bounds.min_y
let scale = if width > height {
let page_ratio = height / width
let sheet_ratio = width / 2.0 / height
if page_ratio < sheet_ratio {
page_ratio
} else {
sheet_ratio
}
} else {
let page_ratio = width / height
let sheet_ratio = height / 2.0 / width
if page_ratio < sheet_ratio {
page_ratio
} else {
sheet_ratio
}
}
let source_count = self.endpage()
let source_pages = pdf_impose_all_pages(source_count)
let scaled = self.scale_pages(
source_pages,
pdf_impose_repeated_scales(source_count, (scale, scale)),
fast~,
)
let imposed = scaled.impose(
2.0,
1.0,
center=true,
fast~,
process_struct_tree~,
)
let output_count = imposed.endpage()
let output_pages = pdf_impose_all_pages(output_count)
let upright = imposed
.rotate_pages(-90, output_pages)
.upright_pages(output_pages, fast~)
upright.scale_to_fit_pages(
output_pages,
pdf_impose_repeated_scales(output_count, (width, height)),
position=PdfPositionDiagonal,
fast~,
)
}
///|
/// Compatibility wrapper for `PdfDocument::twoup`.
pub fn pdf_twoup(
document : PdfDocument,
fast? : Bool = false,
process_struct_tree? : Bool = false,
) -> PdfDocument raise PdfError {
document.twoup(fast~, process_struct_tree~)
}
///|
fn pdf_impose_concat_ops(
first : ArrayView[PdfContentOp],
second : ArrayView[PdfContentOp],
) -> Array[PdfContentOp] {
let output : Array[PdfContentOp] = []
for op in first {
output.push(op)
}
for op in second {
output.push(op)
}
output
}
///|
fn pdf_impose_push_objects(
output : Array[PdfObject],
objects : ArrayView[PdfObject],
) -> Unit {
for object in objects {
output.push(object)
}
}
///|
fn pdf_impose_all_pages(end_page : Int) -> Array[Int] {
let pages : Array[Int] = []
for page_number in 1..<=end_page {
pages.push(page_number)
}
pages
}
///|
fn pdf_impose_repeated_offsets(
count : Int,
offset : (Double, Double),
) -> Array[(Double, Double)] {
let offsets : Array[(Double, Double)] = []
for _ in 0.. Array[(Double, Double)] {
let scales : Array[(Double, Double)] = []
for _ in 0.. Array[(Double, Double, Double, Double)] {
let boxes : Array[(Double, Double, Double, Double)] = []
for _ in 0.. PdfDocument raise PdfError {
let end_page = self.endpage()
let all_pages = pdf_impose_all_pages(end_page)
let boxed = self.hard_box(all_pages, pdf_page_mediabox_key(), fast~)
if spacing == 0.0 || end_page == 0 {
boxed
} else {
let margin = spacing / 2.0
let pages = boxed.pages_of_pagetree()
let first_bounds = boxed.parse_rectangle(pages[0].mediabox)
let width = first_bounds.max_x - first_bounds.min_x
let height = first_bounds.max_y - first_bounds.min_y
let offsets = pdf_impose_repeated_offsets(end_page, (margin, margin))
if fit {
boxed
.scale_contents(
all_pages,
PdfPositionBottomLeft(0.0, 0.0),
(width - spacing) / width,
fast~,
)
.shift_pages(all_pages, offsets, fast~)
} else {
boxed
.shift_pages(all_pages, offsets, fast~)
.set_mediaboxes(
all_pages,
pdf_impose_repeated_boxes(
end_page,
(0.0, 0.0, width + spacing, height + spacing),
),
)
}
}
}
///|
let pdf_impose_cpdf_stamp_name : PdfName = pdf_page_name("/CPDFSTAMP")
///|
fn pdf_impose_border_ops(
x : Double,
y : Double,
width : Double,
height : Double,
line_width : Double,
) -> Array[PdfContentOp] {
[
pdf_content_begin_artifact(),
Op_q,
Op_BMC(pdf_impose_cpdf_stamp_name),
Op_rg(0.0, 0.0, 0.0),
Op_RG(0.0, 0.0, 0.0),
Op_w(line_width),
Op_re(x, y, width, height),
Op_s,
Op_EMC,
Op_Q,
pdf_content_end_artifact(),
]
}
///|
#warnings("-unused_value")
fn PdfDocument::pdf_impose_add_border(
self : PdfDocument,
line_width : Double,
fast : Bool,
) -> PdfDocument raise PdfError {
let end_page = self.endpage()
if line_width == 0.0 || end_page == 0 {
self
} else {
let pages = self.pages_of_pagetree()
let first_bounds = self.parse_rectangle(pages[0].mediabox)
let inset = line_width / 2.0
self.append_page_content_ops(
pdf_impose_all_pages(end_page),
pdf_impose_border_ops(
first_bounds.min_x + inset,
first_bounds.min_y + inset,
first_bounds.max_x - line_width,
first_bounds.max_y - line_width,
line_width,
),
fast~,
)
}
}
///|
let pdf_impose_matrix_key_name : PdfName = pdf_page_name("/Matrix")
///|
fn pdf_impose_pattern_name_used(
used_names : ArrayView[PdfName],
name : PdfName,
) -> Bool {
for used_name in used_names {
if used_name == name {
break true
}
} nobreak {
false
}
}
///|
fn pdf_impose_pattern_add_used(
used_names : Array[PdfName],
name : PdfName,
) -> Unit {
if !pdf_impose_pattern_name_used(used_names, name) {
used_names.push(name)
}
}
///|
fn PdfDocument::pdf_impose_patterns_used_with_scn(
self : PdfDocument,
content : ArrayView[PdfObject],
resources : PdfObject,
) -> Array[PdfName] raise PdfError {
let used_names : Array[PdfName] = []
match self.lookup_direct(pdf_page_pattern_resource_name, resources) {
Some(_) => {
let ops = self.parse_content_ops_with_resources(resources, content)
for op in ops {
match op {
Op_scnName(name, []) | Op_SCNName(name, []) =>
pdf_impose_pattern_add_used(used_names, name)
_ => ()
}
}
}
None => ()
}
used_names
}
///|
fn pdf_impose_xobject_done(done : ArrayView[Int], number : Int) -> Bool {
for item in done {
if item == number {
break true
}
} nobreak {
false
}
}
///|
fn PdfDocument::pdf_impose_change_pattern_object(
self : PdfDocument,
matrix : TransformMatrix,
pattern : PdfObject,
) -> PdfObject raise PdfError {
let old_pattern = self.direct(pattern)
let existing = self.parse_matrix(pdf_impose_matrix_key_name, old_pattern)
let new_matrix = transform_matrix_compose(matrix, existing)
PdfIndirect(
self.add_object(
old_pattern.add_dict_entry(
pdf_impose_matrix_key_name,
pdf_object_of_matrix(new_matrix),
),
),
)
}
///|
fn PdfDocument::pdf_impose_change_pattern_matrices_resources(
self : PdfDocument,
matrix : TransformMatrix,
resources : PdfObject,
names_used_with_scn : ArrayView[PdfName],
xobjects_done : Array[Int],
) -> PdfObject raise PdfError {
match self.lookup_direct(pdf_page_xobject_key(), resources) {
Some(PdfDictionary(entries)) =>
for entry in entries {
match entry.1 {
PdfIndirect(number) =>
self.pdf_impose_change_pattern_matrices_xobject(
matrix,
entry.1,
number,
xobjects_done,
)
_ => raise DictionaryExpected
}
}
_ => ()
}
match self.lookup_direct(pdf_page_pattern_resource_name, resources) {
Some(PdfDictionary(patterns)) => {
let entries : Array[(PdfName, PdfObject)] = []
for entry in patterns {
let (name, pattern) = entry
if pdf_impose_pattern_name_used(names_used_with_scn, name) {
entries.push(
(name, self.pdf_impose_change_pattern_object(matrix, pattern)),
)
} else {
entries.push(entry)
}
}
resources.add_dict_entry(
pdf_page_pattern_resource_name,
PdfDictionary(entries),
)
}
_ => resources
}
}
///|
fn PdfDocument::pdf_impose_change_pattern_matrices_xobject(
self : PdfDocument,
matrix : TransformMatrix,
xobject : PdfObject,
xobject_number : Int,
xobjects_done : Array[Int],
) -> Unit raise PdfError {
if pdf_impose_xobject_done(xobjects_done, xobject_number) {
()
} else {
xobjects_done.push(xobject_number)
let direct_xobject = self.direct(xobject)
match self.lookup_direct(pdf_page_subtype_key(), direct_xobject) {
Some(PdfNameObject(name)) if name == pdf_page_type_form() => {
let resources = match
self.lookup_direct(pdf_page_resources_key(), direct_xobject) {
Some(value) => value
None => PdfDictionary([])
}
let used = self.pdf_impose_patterns_used_with_scn(
[direct_xobject],
resources,
)
match self.lookup_direct(pdf_page_resources_key(), direct_xobject) {
Some(_) => {
let updated_resources = self.pdf_impose_change_pattern_matrices_resources(
matrix, resources, used, xobjects_done,
)
self.add_object_given_number(
xobject_number,
direct_xobject.add_dict_entry(
pdf_page_resources_key(),
updated_resources,
),
)
}
None => ()
}
}
_ => ()
}
}
}
///|
fn PdfDocument::pdf_impose_change_pattern_matrices_page(
self : PdfDocument,
matrix : TransformMatrix,
page : PdfPage,
) -> PdfPage raise PdfError {
let used = self.pdf_impose_patterns_used_with_scn(
page.content,
page.resources,
)
let xobjects_done : Array[Int] = []
{
..page,
resources: self.pdf_impose_change_pattern_matrices_resources(
matrix,
page.resources,
used,
xobjects_done,
),
}
}
///|
/// Rewrite pattern matrices used by a page after applying a page transform.
pub fn PdfDocument::change_pattern_matrices_page(
self : PdfDocument,
matrix : TransformMatrix,
page : PdfPage,
) -> PdfPage raise PdfError {
self.pdf_impose_change_pattern_matrices_page(matrix, page)
}
///|
/// Compatibility wrapper matching cpdfpage's `change_pattern_matrices_page`.
pub fn pdf_change_pattern_matrices_page(
document : PdfDocument,
matrix : TransformMatrix,
page : PdfPage,
) -> PdfPage raise PdfError {
document.change_pattern_matrices_page(matrix, page)
}
///|
#warnings("-unused_value")
fn PdfDocument::pdf_impose_transform_content(
self : PdfDocument,
resources : PdfObject,
matrix : TransformMatrix,
content : ArrayView[PdfObject],
fast : Bool,
) -> Array[PdfObject] raise PdfError {
if fast {
let output : Array[PdfObject] = [
pdf_content_stream_of_ops([Op_q, Op_cm(matrix)]),
]
pdf_impose_push_objects(output, content)
output.push(pdf_content_stream_of_ops([Op_Q]))
output
} else {
let old_ops = self.parse_content_ops_with_resources(resources, content)
let protected_ops = pdf_impose_concat_ops(
pdf_page_protect(old_ops),
old_ops,
)
[
pdf_content_stream_of_ops(
pdf_impose_concat_ops(
[Op_q, Op_cm(matrix)],
pdf_impose_concat_ops(protected_ops, [Op_Q]),
),
),
]
}
}
///|
fn PdfDocument::pdf_impose_combine_page_resources(
self : PdfDocument,
pages : ArrayView[PdfPage],
) -> PdfObject {
let mut resources = pages[0].resources
for index in 1.. PdfObject {
let mut rest = pages[0].rest
for index in 1.. PdfPage raise PdfError {
if pages.length() == 0 {
raise BadNumberArgument("impose: pages must not be empty")
}
let first_page = pages[0]
let transforms = self.pdf_impose_transforms(
fit,
x,
y,
columns,
rtl,
btt,
center,
margin,
first_page.mediabox,
output_mediabox,
fit_extra_hspace,
fit_extra_vspace,
pages.length(),
)
for index in 0.. Array[TransformMatrix] raise PdfError {
pdf_impose_validate_transform_inputs(x, y, count)
let page_box = self.parse_rectangle(mediabox)
let width = page_box.max_x - page_box.min_x
let height = page_box.max_y - page_box.min_y
let final_full_cols = count % x
let final_full_rows = count % y
let output : Array[TransformMatrix] = []
let mut remaining = count
let mut cent_extra_x = 0.0
let mut cent_extra_y = 0.0
if columns {
for col in 0.. 0 {
output.push(
self.pdf_impose_transform_for_slot(
fit,
x,
rtl,
btt,
margin,
output_mediabox,
fit_extra_hspace,
fit_extra_vspace,
cent_extra_x,
cent_extra_y,
adjusted_row,
ordered_col,
width * ordered_col.to_double(),
height * ordered_row.to_double(),
),
)
}
remaining -= 1
}
}
} else {
for row_offset in 0.. 0 {
output.push(
self.pdf_impose_transform_for_slot(
fit,
x,
rtl,
btt,
margin,
output_mediabox,
fit_extra_hspace,
fit_extra_vspace,
cent_extra_x,
cent_extra_y,
ordered_row,
adjusted_col,
width * ordered_col.to_double(),
height * ordered_row.to_double(),
),
)
}
remaining -= 1
}
}
}
output
}