///|
priv struct PdfSqueezeDuplicateCandidate {
number : Int
object : @syntax.PdfObject
}
///|
fn pdf_squeeze_materialized_object(
object : @syntax.PdfObject,
) -> @syntax.PdfObject raise @core.PdfError {
match object {
PdfStreamObject(stream) =>
PdfStreamObject({
dictionary: stream.dictionary,
data: StreamGot(@syntax.pdf_stream_data_bytes(stream.data)),
})
_ => object
}
}
///|
fn pdf_squeeze_duplicate_candidate(
number : Int,
object : @syntax.PdfObject,
) -> PdfSqueezeDuplicateCandidate raise @core.PdfError {
{ number, object: pdf_squeeze_materialized_object(object), }
}
///|
fn PdfDocument::pdf_squeeze_skip_duplicate_candidate(
self : PdfDocument,
object : @syntax.PdfObject,
) -> Bool {
match self.lookup_direct(pdf_squeeze_type_key(), object) {
Some(PdfNameObject(name)) if name == pdf_squeeze_page_name() => true
_ =>
match self.lookup_direct(pdf_squeeze_subtype_key(), object) {
Some(PdfNameObject(name)) => pdf_squeeze_annotation_subtype(name)
_ => false
}
}
}
///|
fn PdfDocument::pdf_squeeze_duplicate_object_changes(
self : PdfDocument,
) -> Array[(Int, Int)] raise @core.PdfError {
let entries = self.parsed_object_entries()
let unique : Array[PdfSqueezeDuplicateCandidate] = Array(
capacity=entries.length(),
)
let changes : Array[(Int, Int)] = Array(capacity=entries.length())
for entry in entries {
let (number, _, object) = entry
let candidate = pdf_squeeze_duplicate_candidate(number, object)
if !self.pdf_squeeze_skip_duplicate_candidate(candidate.object) {
let duplicate = for existing in unique {
if existing.object == candidate.object {
changes.push((candidate.number, existing.number))
break true
}
} nobreak {
false
}
if !duplicate {
unique.push(candidate)
}
}
}
changes
}
///|
fn PdfDocument::pdf_squeeze_apply_duplicate_changes(
self : PdfDocument,
changes : ArrayView[(Int, Int)],
) -> Unit {
if changes.length() > 0 {
let change_map = pdf_page_reference_map(changes)
self.pdf_page_renumber_references(changes)
self.set_trailer_dict(
pdf_page_renumber_object_with_map(self.trailer_dict(), change_map),
)
for change in changes {
let (duplicate_number, _) = change
self.remove_object(duplicate_number)
}
}
}
///|
fn PdfDocument::pdf_squeeze_prune_duplicate_objects_once(
self : PdfDocument,
) -> Unit raise @core.PdfError {
self.pdf_squeeze_apply_duplicate_changes(
self.pdf_squeeze_duplicate_object_changes(),
)
}