///|
fn pdf_merge_parent_tree_change_map(
changes : ArrayView[(Int, Int)],
) -> @hashmap.HashMap[Int, Int] {
let values : @hashmap.HashMap[Int, Int] = HashMap([])
for change in changes {
let (old, replacement) = change
if !values.contains(old) {
values[old] = replacement
}
}
values
}
///|
fn pdf_merge_changed_parent_tree_key(
changes : @hashmap.HashMap[Int, Int],
old_key : Int,
) -> Int? {
changes.get(old_key)
}
///|
fn pdf_merge_renumber_struct_parent_object(
object : @syntax.PdfObject,
changes : @hashmap.HashMap[Int, Int],
) -> @syntax.PdfObject {
match object {
PdfDictionary(entries) => {
let output : Array[(@core.PdfName, @syntax.PdfObject)] = []
for entry in entries {
let (key, value) = entry
if key == pdf_merge_struct_parent_key() ||
key == pdf_merge_struct_parents_key() {
match value {
PdfInteger(old_key) =>
match pdf_merge_changed_parent_tree_key(changes, old_key) {
Some(new_key) => output.push((key, PdfInteger(new_key)))
None => output.push(entry)
}
_ =>
output.push(
(key, pdf_merge_renumber_struct_parent_object(value, changes)),
)
}
} else {
output.push(
(key, pdf_merge_renumber_struct_parent_object(value, changes)),
)
}
}
PdfDictionary(output)
}
PdfArray(items) =>
PdfArray(
[
for item in items => {
pdf_merge_renumber_struct_parent_object(item, changes)
}
],
)
PdfStreamObject(stream) =>
PdfStreamObject({
dictionary: pdf_merge_renumber_struct_parent_object(
stream.dictionary,
changes,
),
data: stream.data,
})
_ => object
}
}
///|
fn pdf_merge_renumber_struct_parent_entry(
entry : PdfObjectEntry,
changes : @hashmap.HashMap[Int, Int],
) -> PdfObjectEntry {
match entry.data {
ObjectParsed(object) =>
{
data: ObjectParsed(
pdf_merge_renumber_struct_parent_object(object, changes),
),
generation: entry.generation,
}
ObjectParsedAlreadyDecrypted(object) =>
{
data: ObjectParsedAlreadyDecrypted(
pdf_merge_renumber_struct_parent_object(object, changes),
),
generation: entry.generation,
}
_ => { data: entry.data, generation: entry.generation, }
}
}
///|
fn PdfDocument::pdf_merge_renumber_struct_parent_entries(
self : PdfDocument,
changes : ArrayView[(Int, Int)],
) -> Unit {
if changes.length() > 0 {
let change_map = pdf_merge_parent_tree_change_map(changes)
for number in self.object_numbers() {
let entry = self.objects.get_entry(number).unwrap()
self.objects.set_entry(
number,
pdf_merge_renumber_struct_parent_entry(entry, change_map),
)
}
}
}
///|
fn pdf_merge_renumber_parent_trees(
documents : ArrayView[PdfDocument],
) -> Array[(Int, @syntax.PdfObject)] raise @core.PdfError {
let merged_entries : Array[(Int, @syntax.PdfObject)] = []
let mut next_key = 0
for document in documents {
let changes : Array[(Int, Int)] = []
for root in pdf_merge_structure_tree_roots([document]) {
for entry in document.pdf_merge_structure_parent_tree_entries(root) {
let (old_key, value) = entry
changes.push((old_key, next_key))
merged_entries.push((next_key, value))
next_key += 1
}
}
document.pdf_merge_renumber_struct_parent_entries(changes)
}
merged_entries
}