///|
fn pdf_annotation_name(text : String) -> PdfName {
pdf_name_of_bytes(@ascii.encode(text))
}
///|
let pdf_annotation_empty_name : PdfName = pdf_annotation_name("")
///|
let pdf_annotation_subtype_key_name : PdfName = pdf_annotation_name("/Subtype")
///|
fn pdf_annotation_subtype_key() -> PdfName {
pdf_annotation_subtype_key_name
}
///|
let pdf_annotation_contents_key_name : PdfName = pdf_annotation_name(
"/Contents",
)
///|
fn pdf_annotation_contents_key() -> PdfName {
pdf_annotation_contents_key_name
}
///|
let pdf_annotation_rect_key_name : PdfName = pdf_annotation_name("/Rect")
///|
fn pdf_annotation_rect_key() -> PdfName {
pdf_annotation_rect_key_name
}
///|
let pdf_annotation_border_key_name : PdfName = pdf_annotation_name("/Border")
///|
fn pdf_annotation_border_key() -> PdfName {
pdf_annotation_border_key_name
}
///|
let pdf_annotation_bs_key_name : PdfName = pdf_annotation_name("/BS")
///|
fn pdf_annotation_bs_key() -> PdfName {
pdf_annotation_bs_key_name
}
///|
let pdf_annotation_subj_key_name : PdfName = pdf_annotation_name("/Subj")
///|
fn pdf_annotation_subj_key() -> PdfName {
pdf_annotation_subj_key_name
}
///|
let pdf_annotation_colour_key_name : PdfName = pdf_annotation_name("/C")
///|
fn pdf_annotation_colour_key() -> PdfName {
pdf_annotation_colour_key_name
}
///|
let pdf_annotation_parent_key_name : PdfName = pdf_annotation_name("/Parent")
///|
fn pdf_annotation_parent_key() -> PdfName {
pdf_annotation_parent_key_name
}
///|
let pdf_annotation_annots_key_name : PdfName = pdf_annotation_name("/Annots")
///|
fn pdf_annotation_annots_key() -> PdfName {
pdf_annotation_annots_key_name
}
///|
let pdf_annotation_width_key_name : PdfName = pdf_annotation_name("/W")
///|
fn pdf_annotation_width_key() -> PdfName {
pdf_annotation_width_key_name
}
///|
let pdf_annotation_style_key_name : PdfName = pdf_annotation_name("/S")
///|
fn pdf_annotation_style_key() -> PdfName {
pdf_annotation_style_key_name
}
///|
let pdf_annotation_dash_key_name : PdfName = pdf_annotation_name("/D")
///|
fn pdf_annotation_dash_key() -> PdfName {
pdf_annotation_dash_key_name
}
///|
let pdf_annotation_quadpoints_key_name : PdfName = pdf_annotation_name(
"/QuadPoints",
)
///|
fn pdf_annotation_quadpoints_key() -> PdfName {
pdf_annotation_quadpoints_key_name
}
///|
let pdf_annotation_line_key_name : PdfName = pdf_annotation_name("/L")
///|
fn pdf_annotation_line_key() -> PdfName {
pdf_annotation_line_key_name
}
///|
let pdf_annotation_beveled_name : PdfName = pdf_annotation_name("/B")
///|
let pdf_annotation_inset_name : PdfName = pdf_annotation_name("/I")
///|
let pdf_annotation_underline_style_name : PdfName = pdf_annotation_name("/U")
///|
let pdf_annotation_text_name : PdfName = pdf_annotation_name("/Text")
///|
let pdf_annotation_link_name : PdfName = pdf_annotation_name("/Link")
///|
let pdf_annotation_free_text_name : PdfName = pdf_annotation_name("/FreeText")
///|
let pdf_annotation_line_name : PdfName = pdf_annotation_name("/Line")
///|
let pdf_annotation_square_name : PdfName = pdf_annotation_name("/Square")
///|
let pdf_annotation_circle_name : PdfName = pdf_annotation_name("/Circle")
///|
let pdf_annotation_polygon_name : PdfName = pdf_annotation_name("/Polygon")
///|
let pdf_annotation_polyline_name : PdfName = pdf_annotation_name("/PolyLine")
///|
let pdf_annotation_highlight_name : PdfName = pdf_annotation_name("/Highlight")
///|
let pdf_annotation_underline_name : PdfName = pdf_annotation_name("/Underline")
///|
let pdf_annotation_squiggly_name : PdfName = pdf_annotation_name("/Squiggly")
///|
let pdf_annotation_strikeout_name : PdfName = pdf_annotation_name("/StrikeOut")
///|
let pdf_annotation_stamp_name : PdfName = pdf_annotation_name("/Stamp")
///|
let pdf_annotation_caret_name : PdfName = pdf_annotation_name("/Caret")
///|
let pdf_annotation_ink_name : PdfName = pdf_annotation_name("/Ink")
///|
let pdf_annotation_popup_name : PdfName = pdf_annotation_name("/Popup")
///|
let pdf_annotation_file_attachment_name : PdfName = pdf_annotation_name(
"/FileAttachment",
)
///|
let pdf_annotation_sound_name : PdfName = pdf_annotation_name("/Sound")
///|
let pdf_annotation_movie_name : PdfName = pdf_annotation_name("/Movie")
///|
let pdf_annotation_widget_name : PdfName = pdf_annotation_name("/Widget")
///|
let pdf_annotation_screen_name : PdfName = pdf_annotation_name("/Screen")
///|
let pdf_annotation_printer_mark_name : PdfName = pdf_annotation_name(
"/PrinterMark",
)
///|
let pdf_annotation_trap_net_name : PdfName = pdf_annotation_name("/TrapNet")
///|
let pdf_annotation_watermark_name : PdfName = pdf_annotation_name("/Watermark")
///|
let pdf_annotation_three_dee_name : PdfName = pdf_annotation_name("/3D")
///|
let pdf_annotation_unknown_name : PdfName = pdf_annotation_name("/Unknown")
///|
/// Border style used by an annotation border dictionary.
pub(all) enum PdfAnnotationStyle {
AnnotationNoStyle
AnnotationSolid
AnnotationDashed
AnnotationBeveled
AnnotationInset
AnnotationUnderlineStyle
} derive(Debug, Eq, ToJson)
///|
/// Parsed annotation border information.
///
/// `vertical_radius` and `horizontal_radius` come from the legacy `/Border`
/// array form. `style` and `dash_array` represent `/BS` dictionary entries when
/// present.
pub(all) struct PdfAnnotationBorder {
width : Double
vertical_radius : Double
horizontal_radius : Double
style : PdfAnnotationStyle
dash_array : Array[Int]
} derive(Debug, Eq, ToJson)
///|
/// RGB annotation colour from the `/C` entry.
///
/// Components are stored as integer channel values after parsing PDF numbers.
pub(all) struct PdfAnnotationColour {
red : Int
green : Int
blue : Int
} derive(Debug, Eq, ToJson)
///|
/// Supported annotation subtype.
///
/// Popup annotations embed their resolved parent annotation when available.
/// Unknown subtype names are preserved as `AnnotationUnknown`.
pub(all) enum PdfAnnotationSubtype {
AnnotationText
AnnotationLink
AnnotationFreeText
AnnotationLine
AnnotationSquare
AnnotationCircle
AnnotationPolygon
AnnotationPolyLine
AnnotationHighlight
AnnotationUnderline
AnnotationSquiggly
AnnotationStrikeOut
AnnotationStamp
AnnotationCaret
AnnotationInk
AnnotationPopup(PdfAnnotation)
AnnotationFileAttachment
AnnotationSound
AnnotationMovie
AnnotationWidget
AnnotationScreen
AnnotationPrinterMark
AnnotationTrapNet
AnnotationWatermark
AnnotationThreeDee
AnnotationUnknown(PdfName)
} derive(Debug, Eq, ToJson)
///|
/// Parsed PDF annotation dictionary.
///
/// `contents` and `subject` are raw PDF string bytes. `rectangle` is required
/// when reading from a PDF. `rest` preserves dictionary entries not modeled by
/// the typed fields so they can be written back.
pub(all) struct PdfAnnotation {
subtype : PdfAnnotationSubtype
contents : PdfBytes?
subject : PdfBytes?
rectangle : PdfRectangle
border : PdfAnnotationBorder
colour : PdfAnnotationColour?
rest : PdfObject
} derive(Debug, Eq, ToJson)
///|
fn pdf_annotation_default_border() -> PdfAnnotationBorder {
{
width: 1.0,
vertical_radius: 0.0,
horizontal_radius: 0.0,
style: AnnotationNoStyle,
dash_array: [],
}
}
///|
fn pdf_annotation_zero_rectangle() -> PdfRectangle {
{ min_x: 0.0, min_y: 0.0, max_x: 0.0, max_y: 0.0 }
}
///|
/// Build an annotation border, copying the supplied dash array.
pub fn pdf_annotation_make_border(
width : Double,
vertical_radius? : Double = 0.0,
horizontal_radius? : Double = 0.0,
style? : PdfAnnotationStyle = AnnotationNoStyle,
dash_array? : ArrayView[Int] = [],
) -> PdfAnnotationBorder {
{
width,
vertical_radius,
horizontal_radius,
style,
dash_array: [
for dash in dash_array => dash
],
}
}
///|
/// Build an annotation value with CamlPDF-compatible defaults.
///
/// Defaults are no contents, no subject, a zero rectangle, default border, no
/// colour, and no preserved extra dictionary entries.
pub fn pdf_annotation_make(
subtype : PdfAnnotationSubtype,
contents? : PdfBytes? = None,
border? : PdfAnnotationBorder = pdf_annotation_default_border(),
rectangle? : PdfRectangle = pdf_annotation_zero_rectangle(),
colour? : PdfAnnotationColour? = None,
subject? : PdfBytes? = None,
) -> PdfAnnotation {
{ subtype, contents, subject, rectangle, border, colour, rest: PdfNull }
}
///|
fn pdf_annotation_style_of_name(name : PdfName) -> PdfAnnotationStyle {
if name == pdf_annotation_style_key() {
AnnotationSolid
} else if name == pdf_annotation_dash_key() {
AnnotationDashed
} else if name == pdf_annotation_beveled_name {
AnnotationBeveled
} else if name == pdf_annotation_inset_name {
AnnotationInset
} else if name == pdf_annotation_underline_style_name {
AnnotationUnderlineStyle
} else {
AnnotationNoStyle
}
}
///|
fn pdf_annotation_subtype_name(subtype : PdfAnnotationSubtype) -> PdfName {
match subtype {
AnnotationText => pdf_annotation_text_name
AnnotationLink => pdf_annotation_link_name
AnnotationFreeText => pdf_annotation_free_text_name
AnnotationLine => pdf_annotation_line_name
AnnotationSquare => pdf_annotation_square_name
AnnotationCircle => pdf_annotation_circle_name
AnnotationPolygon => pdf_annotation_polygon_name
AnnotationPolyLine => pdf_annotation_polyline_name
AnnotationHighlight => pdf_annotation_highlight_name
AnnotationUnderline => pdf_annotation_underline_name
AnnotationSquiggly => pdf_annotation_squiggly_name
AnnotationStrikeOut => pdf_annotation_strikeout_name
AnnotationStamp => pdf_annotation_stamp_name
AnnotationCaret => pdf_annotation_caret_name
AnnotationInk => pdf_annotation_ink_name
AnnotationPopup(_) => pdf_annotation_popup_name
AnnotationFileAttachment => pdf_annotation_file_attachment_name
AnnotationSound => pdf_annotation_sound_name
AnnotationMovie => pdf_annotation_movie_name
AnnotationWidget => pdf_annotation_widget_name
AnnotationScreen => pdf_annotation_screen_name
AnnotationPrinterMark => pdf_annotation_printer_mark_name
AnnotationTrapNet => pdf_annotation_trap_net_name
AnnotationWatermark => pdf_annotation_watermark_name
AnnotationThreeDee => pdf_annotation_three_dee_name
AnnotationUnknown(_) => pdf_annotation_unknown_name
}
}
///|
fn PdfDocument::pdf_annotation_subtype(
self : PdfDocument,
annotation : PdfObject,
depth : Int,
) -> PdfAnnotationSubtype raise PdfError {
match self.lookup_direct(pdf_annotation_subtype_key(), annotation) {
Some(PdfNameObject(name)) if name == pdf_annotation_text_name =>
AnnotationText
Some(PdfNameObject(name)) if name == pdf_annotation_free_text_name =>
AnnotationFreeText
Some(PdfNameObject(name)) if name == pdf_annotation_popup_name =>
match
self.direct(annotation).lookup_immediate(pdf_annotation_parent_key()) {
Some(PdfIndirect(parent)) if depth < 64 =>
AnnotationPopup(
self.pdf_annotation_read_depth(PdfIndirect(parent), depth + 1),
)
_ => AnnotationUnknown(pdf_annotation_empty_name)
}
Some(PdfNameObject(name)) if name == pdf_annotation_stamp_name =>
AnnotationStamp
Some(PdfNameObject(name)) if name == pdf_annotation_link_name =>
AnnotationLink
Some(PdfNameObject(name)) if name == pdf_annotation_line_name =>
AnnotationLine
Some(PdfNameObject(name)) if name == pdf_annotation_square_name =>
AnnotationSquare
Some(PdfNameObject(name)) if name == pdf_annotation_circle_name =>
AnnotationCircle
Some(PdfNameObject(name)) if name == pdf_annotation_polygon_name =>
AnnotationPolygon
Some(PdfNameObject(name)) if name == pdf_annotation_polyline_name =>
AnnotationPolyLine
Some(PdfNameObject(name)) if name == pdf_annotation_highlight_name =>
AnnotationHighlight
Some(PdfNameObject(name)) if name == pdf_annotation_underline_name =>
AnnotationUnderline
Some(PdfNameObject(name)) if name == pdf_annotation_squiggly_name =>
AnnotationSquiggly
Some(PdfNameObject(name)) if name == pdf_annotation_strikeout_name =>
AnnotationStrikeOut
Some(PdfNameObject(name)) if name == pdf_annotation_caret_name =>
AnnotationCaret
Some(PdfNameObject(name)) if name == pdf_annotation_ink_name =>
AnnotationInk
Some(PdfNameObject(name)) if name == pdf_annotation_file_attachment_name =>
AnnotationFileAttachment
Some(PdfNameObject(name)) if name == pdf_annotation_sound_name =>
AnnotationSound
Some(PdfNameObject(name)) if name == pdf_annotation_movie_name =>
AnnotationMovie
Some(PdfNameObject(name)) if name == pdf_annotation_widget_name =>
AnnotationWidget
Some(PdfNameObject(name)) if name == pdf_annotation_screen_name =>
AnnotationScreen
Some(PdfNameObject(name)) if name == pdf_annotation_printer_mark_name =>
AnnotationPrinterMark
Some(PdfNameObject(name)) if name == pdf_annotation_trap_net_name =>
AnnotationTrapNet
Some(PdfNameObject(name)) if name == pdf_annotation_watermark_name =>
AnnotationWatermark
Some(PdfNameObject(name)) if name == pdf_annotation_three_dee_name =>
AnnotationThreeDee
Some(PdfNameObject(name)) => AnnotationUnknown(name)
_ => AnnotationUnknown(pdf_annotation_empty_name)
}
}
///|
fn PdfDocument::pdf_annotation_number_array(
self : PdfDocument,
object : PdfObject,
) -> Array[Int] raise PdfError {
match self.direct(object) {
PdfArray(items) => {
let output : Array[Int] = []
for item in items {
output.push(self.get_number(item).to_int())
}
output
}
_ => []
}
}
///|
fn PdfDocument::pdf_annotation_border(
self : PdfDocument,
annotation : PdfObject,
) -> PdfAnnotationBorder raise PdfError {
match self.lookup_direct(pdf_annotation_bs_key(), annotation) {
Some(border_style_dict) => {
let width = match
self.lookup_direct(pdf_annotation_width_key(), border_style_dict) {
Some(width) => self.get_number(width)
_ => 1.0
}
let style = match
self.lookup_direct(pdf_annotation_style_key(), border_style_dict) {
Some(PdfNameObject(name)) => pdf_annotation_style_of_name(name)
_ => AnnotationNoStyle
}
let dash_array = match
self.lookup_direct(pdf_annotation_dash_key(), border_style_dict) {
Some(dash) => self.pdf_annotation_number_array(dash)
_ => []
}
{ width, vertical_radius: 0.0, horizontal_radius: 0.0, style, dash_array }
}
None =>
match self.lookup_direct(pdf_annotation_border_key(), annotation) {
Some(PdfArray([horizontal, vertical, width])) =>
{
width: self.get_number(width),
vertical_radius: self.get_number(vertical),
horizontal_radius: self.get_number(horizontal),
style: AnnotationNoStyle,
dash_array: [],
}
Some(PdfArray([horizontal, vertical, width, dash_array])) =>
{
width: self.get_number(width),
vertical_radius: self.get_number(vertical),
horizontal_radius: self.get_number(horizontal),
style: AnnotationNoStyle,
dash_array: self.pdf_annotation_number_array(dash_array),
}
_ => pdf_annotation_default_border()
}
}
}
///|
fn PdfDocument::pdf_annotation_colour(
self : PdfDocument,
annotation : PdfObject,
) -> PdfAnnotationColour? raise PdfError {
match self.lookup_direct(pdf_annotation_colour_key(), annotation) {
Some(PdfArray([red, green, blue])) =>
Some({
red: self.get_number(red).to_int(),
green: self.get_number(green).to_int(),
blue: self.get_number(blue).to_int(),
})
_ => None
}
}
///|
fn pdf_annotation_is_record_key(key : PdfName) -> Bool {
key == pdf_annotation_subtype_key() ||
key == pdf_annotation_contents_key() ||
key == pdf_annotation_rect_key() ||
key == pdf_annotation_border_key() ||
key == pdf_annotation_subj_key() ||
key == pdf_annotation_bs_key() ||
key == pdf_annotation_colour_key()
}
///|
fn pdf_annotation_rest(annotation : PdfObject) -> PdfObject raise PdfError {
match annotation {
PdfDictionary(entries) => {
let output : Array[(PdfName, PdfObject)] = []
for entry in entries {
let (key, _) = entry
if !pdf_annotation_is_record_key(key) {
output.push(entry)
}
}
PdfDictionary(output)
}
_ => raise PdfError::DictionaryExpected
}
}
///|
fn PdfDocument::pdf_annotation_read_depth(
self : PdfDocument,
annotation : PdfObject,
depth : Int,
) -> PdfAnnotation raise PdfError {
let direct_annotation = self.direct(annotation)
{
subtype: self.pdf_annotation_subtype(direct_annotation, depth),
contents: match
self.lookup_direct(pdf_annotation_contents_key(), direct_annotation) {
Some(PdfString(contents)) => Some(contents)
_ => None
},
subject: match
self.lookup_direct(pdf_annotation_subj_key(), direct_annotation) {
Some(PdfString(subject)) => Some(subject)
_ => None
},
rectangle: match
self.lookup_direct(pdf_annotation_rect_key(), direct_annotation) {
Some(rectangle) => self.parse_rectangle(rectangle)
None => raise PdfError::RectangleExpected
},
border: self.pdf_annotation_border(direct_annotation),
colour: self.pdf_annotation_colour(direct_annotation),
rest: pdf_annotation_rest(direct_annotation),
}
}
///|
/// Read one annotation dictionary from this document.
///
/// The annotation object may be direct or indirect. `/Rect` is required. Popup
/// parents are resolved recursively up to a bounded depth to avoid cycles.
pub fn PdfDocument::read_annotation(
self : PdfDocument,
annotation : PdfObject,
) -> PdfAnnotation raise PdfError {
self.pdf_annotation_read_depth(annotation, 0)
}
///|
fn PdfDocument::pdf_annotation_popup_parent(
self : PdfDocument,
annotation : PdfObject,
) -> Int? {
match self.direct(annotation).lookup_immediate(pdf_annotation_parent_key()) {
Some(PdfIndirect(parent)) => Some(parent)
_ => None
}
}
///|
/// Read annotations from a page's `/Annots` array.
///
/// Missing or malformed `/Annots` entries are treated as no annotations. When a
/// popup annotation and its parent both appear in the page array, the parent is
/// skipped and represented through `AnnotationPopup`.
pub fn PdfDocument::annotations_of_page(
self : PdfDocument,
page : PdfPage,
) -> Array[PdfAnnotation] raise PdfError {
match self.lookup_direct(pdf_annotation_annots_key(), page.rest) {
Some(PdfArray(annotations)) => {
let popup_parents : Array[Int] = []
for annotation in annotations {
match self.pdf_annotation_popup_parent(annotation) {
Some(parent) => popup_parents.push(parent)
None => ()
}
}
let popup_parent_set = pdf_number_set(popup_parents)
let output : Array[PdfAnnotation] = []
for annotation in annotations {
match annotation {
PdfIndirect(number) if popup_parent_set.contains(number) => ()
_ => output.push(self.read_annotation(annotation))
}
}
output
}
_ => []
}
}
///|
/// Compatibility wrapper for `PdfDocument::annotations_of_page`.
pub fn pdf_annotations_of_page(
document : PdfDocument,
page : PdfPage,
) -> Array[PdfAnnotation] raise PdfError {
document.annotations_of_page(page)
}
///|
fn pdf_annotation_rectangle_object(rectangle : PdfRectangle) -> PdfObject {
PdfArray([
PdfReal(rectangle.min_x),
PdfReal(rectangle.min_y),
PdfReal(rectangle.max_x),
PdfReal(rectangle.max_y),
])
}
///|
fn pdf_annotation_border_object(border : PdfAnnotationBorder) -> PdfObject {
let base : Array[PdfObject] = [
PdfReal(border.horizontal_radius),
PdfReal(border.vertical_radius),
PdfReal(border.width),
]
if border.dash_array.length() > 0 {
base.push(PdfArray([ for dash in border.dash_array => PdfInteger(dash) ]))
}
PdfArray(base)
}
///|
fn pdf_annotation_rest_entries(
rest : PdfObject,
) -> Array[(PdfName, PdfObject)] raise PdfError {
match rest {
PdfNull => []
PdfDictionary(entries) => [ for entry in entries => entry ]
_ => raise PdfError::DictionaryExpected
}
}
///|
fn pdf_object_of_annotation(
annotation : PdfAnnotation,
) -> PdfObject raise PdfError {
let entries : Array[(PdfName, PdfObject)] = [
(
pdf_annotation_subtype_key(),
PdfNameObject(pdf_annotation_subtype_name(annotation.subtype)),
),
(
pdf_annotation_contents_key(),
match annotation.contents {
Some(contents) => PdfString(contents)
None => PdfNull
},
),
(
pdf_annotation_rect_key(),
pdf_annotation_rectangle_object(annotation.rectangle),
),
(
pdf_annotation_border_key(),
pdf_annotation_border_object(annotation.border),
),
]
for entry in pdf_annotation_rest_entries(annotation.rest) {
entries.push(entry)
}
match annotation.colour {
Some(colour) =>
entries.push(
(
pdf_annotation_colour_key(),
PdfArray([
PdfInteger(colour.red),
PdfInteger(colour.green),
PdfInteger(colour.blue),
]),
),
)
None => ()
}
match annotation.subject {
Some(subject) =>
entries.push((pdf_annotation_subj_key(), PdfString(subject)))
None => ()
}
PdfDictionary(entries)
}
///|
/// Return a page value with an annotation prepended to `/Annots`.
///
/// The annotation is written as a direct dictionary. Existing annotation arrays
/// are preserved after the new entry; a non-array `/Annots` value raises.
pub fn PdfDocument::add_annotation(
self : PdfDocument,
page : PdfPage,
annotation : PdfAnnotation,
) -> PdfPage raise PdfError {
let object = pdf_object_of_annotation(annotation)
let annotations = match
self.lookup_direct(pdf_annotation_annots_key(), page.rest) {
Some(PdfArray(existing)) => [object, ..existing]
Some(_) => raise PdfError::DictionaryExpected
None => [object]
}
{
..page,
rest: page.rest.add_dict_entry(
pdf_annotation_annots_key(),
PdfArray(annotations),
),
}
}
///|
/// Compatibility wrapper for `PdfDocument::add_annotation`.
pub fn pdf_add_annotation(
document : PdfDocument,
page : PdfPage,
annotation : PdfAnnotation,
) -> PdfPage raise PdfError {
document.add_annotation(page, annotation)
}
///|
fn PdfDocument::pdf_annotation_transform_one(
self : PdfDocument,
matrix : TransformMatrix,
annotation_number : Int,
) -> Unit raise PdfError {
let annotation = self.lookup_object_or_null(annotation_number)
let transformed = self.pdf_annotation_transform_object(matrix, annotation)
if transformed != annotation {
self.add_object_given_number(annotation_number, transformed)
}
}
///|
fn PdfDocument::pdf_annotation_transform_object(
self : PdfDocument,
matrix : TransformMatrix,
annotation : PdfObject,
) -> PdfObject raise PdfError {
let mut transformed = annotation
match self.lookup_direct(pdf_annotation_rect_key(), annotation) {
Some(rectangle) =>
transformed = transformed.add_dict_entry(
pdf_annotation_rect_key(),
self.transform_rect(matrix, rectangle),
)
None => ()
}
match self.lookup_direct(pdf_annotation_quadpoints_key(), annotation) {
Some(quadpoints) =>
transformed = transformed.add_dict_entry(
pdf_annotation_quadpoints_key(),
self.transform_quadpoints(matrix, quadpoints),
)
None => ()
}
match self.lookup_direct(pdf_annotation_line_key(), annotation) {
Some(line) =>
transformed = transformed.add_dict_entry(
pdf_annotation_line_key(),
self.transform_rect(matrix, line),
)
None => ()
}
transformed
}
///|
/// Transform annotation geometry referenced by a page dictionary.
///
/// Applies `matrix` to `/Rect`, `/QuadPoints`, and `/L` entries. Indirect
/// annotations are updated in this document; direct annotation dictionaries in
/// the page's `/Annots` array are updated in place.
pub fn PdfDocument::transform_annotations(
self : PdfDocument,
matrix : TransformMatrix,
rest : PdfObject,
) -> Unit raise PdfError {
match self.lookup_direct(pdf_annotation_annots_key(), rest) {
Some(PdfArray(annotations)) =>
for index in 0..
self.pdf_annotation_transform_one(matrix, number)
PdfDictionary(_) as annotation => {
let transformed = self.pdf_annotation_transform_object(
matrix, annotation,
)
if transformed != annotation {
annotations[index] = transformed
}
}
_ => ()
}
}
_ => ()
}
}
///|
/// Compatibility wrapper for `PdfDocument::transform_annotations`.
pub fn pdf_transform_annotations(
document : PdfDocument,
matrix : TransformMatrix,
rest : PdfObject,
) -> Unit raise PdfError {
document.transform_annotations(matrix, rest)
}