///|
/// Calculate the cpdf add-rectangle lower-left origin after placement.
pub fn pdf_addtext_rectangle_origin(
bounds : @geometry.PdfRectangle,
position : @geometry.PdfPosition,
width : Double,
height : Double,
) -> (Double, Double) {
let placed = @geometry.pdf_calculate_position(false, width, bounds, position)
let y = match position {
PdfPositionTop(_) | PdfPositionTopLeft(_, _) | PdfPositionTopRight(_, _) =>
placed.y - height
PdfPositionCentre | PdfPositionPosCentre(_, _) => placed.y - height / 2.0
_ => placed.y
}
(placed.x, y)
}
///|
fn PdfDocument::pdf_addtext_rectangle_bounds(
self : PdfDocument,
page : @page.PdfPage,
relative_to_box : @core.PdfName,
) -> @geometry.PdfRectangle raise @core.PdfError {
if relative_to_box == pdf_page_mediabox_key() {
self.parse_rectangle(page.mediabox)
} else {
match self.lookup_direct(relative_to_box, page.rest) {
Some(box_object) => self.parse_rectangle(box_object)
None => self.parse_rectangle(page.mediabox)
}
}
}
///|
fn PdfDocument::pdf_addtext_rectangle_dimensions(
self : PdfDocument,
page : @page.PdfPage,
coord : String,
) -> (Double, Double) raise @core.PdfError {
match self.parse_units_string(page, coord) {
[width, height] => (width, height)
_ => raise SoftError("bad coordinate specification")
}
}
///|
fn PdfDocument::pdf_addtext_rectangle_page(
self : PdfDocument,
page : @page.PdfPage,
coord : String,
colour : @colour.PdfContentColour,
position : @geometry.PdfPosition,
relative_to_box : @core.PdfName,
outline : Bool,
line_width : Double,
opacity : Double,
underneath : Bool,
fast : Bool,
) -> @page.PdfPage raise @core.PdfError {
let (resources, extgstate_name) = self.pdf_addtext_opacity_resources(
page.resources,
opacity,
)
let bounds = self.pdf_addtext_rectangle_bounds(page, relative_to_box)
let (width, height) = self.pdf_addtext_rectangle_dimensions(page, coord)
let (x, y) = pdf_addtext_rectangle_origin(bounds, position, width, height)
let ops = pdf_addtext_rectangle_ops(
x, y, width, height, colour, outline, line_width, extgstate_name,
)
let page = { ..page, resources, }
if underneath {
self.prepend_operators(page, ops, fast~)
} else {
self.postpend_operators(page, ops, fast~)
}
}
///|
/// Add a cpdf-style rectangle stamp to selected one-based pages.
///
/// The rectangle dimensions are parsed with cpdf coordinate syntax, placed
/// relative to `relative_to_box`, wrapped as `/CPDFSTAMP` artifact content, and
/// appended unless `underneath` is set.
pub fn PdfDocument::addtext_rectangle(
self : PdfDocument,
page_numbers : ArrayView[Int],
coord : String,
colour : @colour.PdfContentColour,
position : @geometry.PdfPosition,
relative_to_box? : @core.PdfName = pdf_page_mediabox_key(),
outline? : Bool = false,
line_width? : Double = 1.0,
opacity? : Double = 1.0,
underneath? : Bool = false,
fast? : Bool = false,
) -> PdfDocument raise @core.PdfError {
let pages = self.pages_of_pagetree()
pdf_addtext_validate_page_numbers(
page_numbers,
pages.length(),
"addtext_rectangle",
)
let selected_pages = @core.pdf_number_set(page_numbers)
let rewritten : Array[@page.PdfPage] = Array(capacity=pages.length())
for index in 0.. PdfDocument raise @core.PdfError {
document.addtext_rectangle(
page_numbers,
coord,
colour,
position,
relative_to_box~,
outline~,
line_width~,
opacity~,
underneath~,
fast~,
)
}
///|
/// Source-spelled compatibility wrapper matching cpdfaddtext's `addrectangle`.
pub fn pdf_addrectangle(
fast : Bool,
coord : String,
colour : @colour.PdfContentColour,
outline : Bool,
line_width : Double,
opacity : Double,
position : @geometry.PdfPosition,
relative_to_box : String,
underneath : Bool,
page_numbers : ArrayView[Int],
document : PdfDocument,
) -> PdfDocument raise @core.PdfError {
document.addtext_rectangle(
page_numbers,
coord,
colour,
position,
relative_to_box=pdf_page_box_name_of_string(relative_to_box),
outline~,
line_width~,
opacity~,
underneath~,
fast~,
)
}