///|
fn PdfDocument::pdf_annotation_contents_text(
self : PdfDocument,
encoding : @metadata.PdfMetadataEncoding,
annotation : @syntax.PdfObject,
) -> @core.PdfBytes raise @core.PdfError {
match self.lookup_direct(pdf_annotation_contents_key(), annotation) {
Some(PdfString(contents)) => pdf_metadata_encode_output(encoding, contents)
_ => []
}
}
///|
fn pdf_annotation_write_listing_view(
output : Array[Byte],
position : Int,
data : BytesView,
) -> Int {
let mut current = position
for byte in data {
output[current] = byte
current += 1
}
current
}
///|
fn pdf_annotation_write_listing_ascii(
output : Array[Byte],
position : Int,
text : String,
) -> Int {
pdf_annotation_write_listing_view(output, position, @ascii.encode(text))
}
///|
fn pdf_annotation_write_listing_line(
output : Array[Byte],
position : Int,
page_number : Int,
contents : BytesView,
) -> Int {
let mut current = pdf_annotation_write_listing_ascii(
output, position, "Page ",
)
current = pdf_annotation_write_listing_ascii(
output,
current,
page_number.to_string(),
)
current = pdf_annotation_write_listing_ascii(output, current, ": ")
current = pdf_annotation_write_listing_view(output, current, contents)
output[current] = 10
current + 1
}
///|
fn pdf_annotation_listing_line_length(
page_number : Int,
contents : BytesView,
) -> Int {
b"Page ".length() +
@ascii.encode(page_number.to_string()).length() +
b": ".length() +
contents.length() +
1
}
///|
/// Return old-style annotation contents as `(page_number, contents)` pairs.
///
/// Every annotation entry contributes one pair. Annotations without `/Contents`
/// contribute an empty byte string, matching cpdf's old list behavior.
pub fn PdfDocument::get_annotations(
self : PdfDocument,
encoding? : @metadata.PdfMetadataEncoding = PdfMetadataUTF8,
) -> Array[(Int, @core.PdfBytes)] raise @core.PdfError {
let pages = self.pages_of_pagetree()
let output : Array[(Int, @core.PdfBytes)] = Array(capacity=pages.length())
for index, page in pages {
match self.lookup_direct(pdf_annotation_annots_key(), page.rest) {
Some(PdfArray(annotations)) =>
for annotation in annotations {
output.push(
(index + 1, self.pdf_annotation_contents_text(encoding, annotation)),
)
}
_ => ()
}
}
output
}
///|
/// Compatibility wrapper for `PdfDocument::get_annotations`.
pub fn pdf_get_annotations(
encoding : @metadata.PdfMetadataEncoding,
document : PdfDocument,
) -> Array[(Int, @core.PdfBytes)] raise @core.PdfError {
document.get_annotations(encoding~)
}
///|
/// Render cpdf's old-style annotation listing for selected pages.
///
/// Unlike `get_annotations`, this suppresses empty `/Contents` entries and
/// returns the bytes cpdf would print instead of writing to stdout.
pub fn PdfDocument::list_annotations(
self : PdfDocument,
page_numbers : ArrayView[Int],
encoding? : @metadata.PdfMetadataEncoding = PdfMetadataUTF8,
) -> @core.PdfBytes raise @core.PdfError {
let pages = self.pages_of_pagetree()
pdf_page_box_validate_page_numbers(
page_numbers,
pages.length(),
"list_annotations",
)
let selected_pages = @core.pdf_number_set(page_numbers)
let rows : Array[(Int, @core.PdfBytes)] = Array(
capacity=page_numbers.length(),
)
let mut output_length = 0
for index, page in pages {
let page_number = index + 1
if selected_pages.contains(page_number) {
match self.lookup_direct(pdf_annotation_annots_key(), page.rest) {
Some(PdfArray(annotations)) =>
for annotation in annotations {
let contents = self.pdf_annotation_contents_text(
encoding, annotation,
)
if contents.length() > 0 {
output_length += pdf_annotation_listing_line_length(
page_number, contents,
)
rows.push((page_number, contents))
}
}
_ => ()
}
}
}
let output = Array::make(output_length, b'\x00')
let mut position = 0
for row in rows {
position = pdf_annotation_write_listing_line(output, position, row.0, row.1)
}
Bytes::from_array(output)
}
///|
/// Compatibility wrapper for `PdfDocument::list_annotations`.
pub fn pdf_list_annotations(
page_numbers : ArrayView[Int],
encoding : @metadata.PdfMetadataEncoding,
document : PdfDocument,
) -> @core.PdfBytes raise @core.PdfError {
document.list_annotations(page_numbers, encoding~)
}