mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-06 02:21:45 +00:00
M11: Optimize passes remove_hidden only the ticked categories that hold something
Catching remove_hidden's refusal kept a copy it may have changed: with bookmarks ticked it drops an empty outline root before counting nothing, and its own documentation says to drop such a copy. The optimizer now scans first and passes only the ticked categories the scan finds something in, and with none doesn't call it, so an empty outline root stays, as Remove Hidden Information leaves it. Corrects 278a588bf's message: the ticks are under Discard Objects and Discard User Data, and hidden text is one of them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AmsdeUCdTaD72jkDw2pJKY
This commit is contained in:
1 parent
ada2a1ccb7
commit
c7c018ac6d
2 files changed
+21
-6
No files matched your search
@@ -95,12 +95,12 @@ impl OptimizeJob {
|
||||
let discarded = if discard.is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
// `remove_hidden` refuses a run that removes nothing. Ticked categories that hold
|
||||
// nothing are nothing to discard, not a reason to end the whole optimization.
|
||||
match pdfcraft_redact::sanitize::remove_hidden(&mut cos, &discard) {
|
||||
Err(pdfcraft_redact::RedactError::NothingToApply) => Vec::new(),
|
||||
r => r?,
|
||||
}
|
||||
// Only the ticked categories its scan finds something in: `remove_hidden` refuses when
|
||||
// it counts every one it is given as 0, which would end the whole optimization, and
|
||||
// may have changed the copy by then (an empty outline root goes with bookmarks).
|
||||
let counts = pdfcraft_redact::sanitize::scan(&cos);
|
||||
let which: Vec<Hidden> = discard.iter().copied().filter(|h| counts.iter().any(|(c, n)| c == h && *n > 0)).collect();
|
||||
if which.is_empty() { Vec::new() } else { pdfcraft_redact::sanitize::remove_hidden(&mut cos, &which)? }
|
||||
};
|
||||
let report = optimize::optimize_with_progress(&mut cos, &settings, &mut |s| {
|
||||
step(match s {
|
||||
|
||||
@@ -3618,6 +3618,21 @@ fn optimize_discarding_an_empty_category_still_runs() {
|
||||
let (bytes, report) = s.optimized_bytes(id, &optimize::Settings::default(), &[crate::Hidden::Bookmarks, crate::Hidden::Comments]).unwrap();
|
||||
assert!(bytes.starts_with(b"%PDF-"));
|
||||
assert!(report.discarded.is_empty(), "{:?}", report.discarded);
|
||||
// An outline root with no entries is no bookmarks: it stays, as Remove Hidden Information,
|
||||
// which refuses then, leaves it.
|
||||
let outline = pdfcraft_testkit::Pdf::new()
|
||||
.obj("<< /Type /Catalog /Pages 2 0 R /Outlines 4 0 R /PageMode /UseOutlines >>")
|
||||
.obj("<< /Type /Pages /Kids [3 0 R] /Count 1 /MediaBox [0 0 612 792] >>")
|
||||
.obj("<< /Type /Page /Parent 2 0 R >>")
|
||||
.obj("<< /Type /Outlines /Count 0 >>")
|
||||
.build();
|
||||
let mut s = Session::new();
|
||||
let id = s.open("outline.pdf", None, Arc::new(outline), None).unwrap();
|
||||
let (bytes, report) = s.optimized_bytes(id, &optimize::Settings::default(), &[crate::Hidden::Bookmarks]).unwrap();
|
||||
assert!(report.discarded.is_empty(), "{:?}", report.discarded);
|
||||
let saved = pdfcraft_cos::Document::open(bytes).unwrap();
|
||||
let catalog = saved.get(saved.root().unwrap()).as_dict().cloned().unwrap();
|
||||
assert!(catalog.contains(b"Outlines") && catalog.contains(b"PageMode"), "{catalog:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user