///|
priv struct PdfPageReferenceMap {
values : @hashmap.HashMap[Int, Int]
}
///|
fn pdf_page_reference_map(
changes : ArrayView[(Int, Int)],
) -> PdfPageReferenceMap {
let values : @hashmap.HashMap[Int, Int] = HashMap([])
for change in changes {
let (old_number, new_number) = change
if !values.contains(old_number) {
values[old_number] = new_number
}
}
{ values, }
}
///|
fn PdfPageReferenceMap::changed_reference(
self : PdfPageReferenceMap,
number : Int,
) -> Int {
match self.values.get(number) {
Some(new_number) => new_number
None => number
}
}
///|
fn pdf_page_renumber_object_with_map(
object : @syntax.PdfObject,
changes : PdfPageReferenceMap,
) -> @syntax.PdfObject {
match object {
PdfIndirect(number) => PdfIndirect(changes.changed_reference(number))
PdfArray(items) => {
let output : Array[@syntax.PdfObject] = Array(capacity=items.length())
for item in items {
output.push(pdf_page_renumber_object_with_map(item, changes))
}
PdfArray(output)
}
PdfDictionary(entries) => {
let output : Array[(@core.PdfName, @syntax.PdfObject)] = Array(
capacity=entries.length(),
)
for entry in entries {
let (key, value) = entry
output.push((key, pdf_page_renumber_object_with_map(value, changes)))
}
PdfDictionary(output)
}
PdfStreamObject(stream) =>
PdfStreamObject({
dictionary: pdf_page_renumber_object_with_map(
stream.dictionary,
changes,
),
data: stream.data,
})
_ => object
}
}
///|
fn pdf_page_renumber_entry_with_map(
entry : PdfObjectEntry,
changes : PdfPageReferenceMap,
) -> PdfObjectEntry {
match entry.data {
ObjectParsed(object) =>
{
data: ObjectParsed(pdf_page_renumber_object_with_map(object, changes)),
generation: entry.generation,
}
ObjectParsedAlreadyDecrypted(object) =>
{
data: ObjectParsedAlreadyDecrypted(
pdf_page_renumber_object_with_map(object, changes),
),
generation: entry.generation,
}
_ => { data: entry.data, generation: entry.generation, }
}
}
///|
fn PdfDocument::pdf_page_renumber_references(
self : PdfDocument,
changes : ArrayView[(Int, Int)],
) -> Unit {
let change_map = pdf_page_reference_map(changes)
for number in self.object_numbers() {
let entry = self.objects.get_entry(number).unwrap()
self.objects.set_entry(
number,
pdf_page_renumber_entry_with_map(entry, change_map),
)
}
}
///|
fn pdf_page_reference_changes(
old_numbers : ArrayView[Int],
new_numbers : ArrayView[Int],
) -> Array[(Int, Int)] raise @core.PdfError {
if old_numbers.length() != new_numbers.length() {
raise PageTreeExpected
}
let changes : Array[(Int, Int)] = Array(capacity=old_numbers.length())
for i in 0.. Array[(Int, Int)] raise @core.PdfError {
let output : Array[(Int, Int)] = Array(capacity=changes.length())
for change in changes {
let (old_page, new_page) = change
if old_page < 1 ||
old_page > old_numbers.length() ||
new_page < 1 ||
new_page > new_numbers.length() {
raise PageTreeExpected
}
output.push((old_numbers[old_page - 1], new_numbers[new_page - 1]))
}
output
}