mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-14 19:27:04 -04:00
M11: Optimize PDF and Reduce File Size run in the background with a progress bar (#370)
* M11: Optimize PDF and Reduce File Size run in the background with a progress bar
Advanced optimization and Reduce File Size did all their work on the UI
thread, so on a large file the window stopped repainting until they were
done and looked as if it had crashed.
- pdfcraft-optimize: optimize_with_progress reports each image and the
clean-up; returning false stops with OptimizeError::Cancelled.
- engine: Session::optimize_job captures a copy of the document and the
choices; OptimizeJob::run reports each OptimizeStage (removing user data,
images, cleaning up, merging, writing), stops on request with
EditError::Cancelled and turns a panic into an error so a worker always
reports back. optimized_bytes is the job run in place.
- ui: both commands run the job on a worker thread (inline in tests and on
the web), like OCR and Export. A card at the bottom centre shows the
stage ("Optimizing... image 14 of 40"), a bar that eases towards the
fraction with a light sweeping across it, the percentage and Cancel;
notices stack above it. A second run is refused while one is going. The
control channel's state includes the progress.
The headless doc_optimize and doc_reduce tools stay synchronous. New
strings are translated for es, fr, ja, zh-hans, zh-hant.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Clippy: as_chunks in the signature image background test (follow-up to #355)
#360 switched the image test to as_chunks; #355 added another chunks_exact(4)
in the background test, which clippy's chunks_exact_to_as_chunks rejects.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Optimize: report a failed worker spawn instead of waiting forever
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Brandon Thomas <[email protected]>
This commit is contained in:
22 files changed
+635
-61
No files matched your search
@@ -265,3 +265,42 @@ fn invalid_links_and_unreferenced_destinations_go() {
|
||||
let off = Settings { remove_invalid_links: false, remove_unreferenced_dests: false, ..Settings::default() };
|
||||
assert_eq!(optimize(&mut again, &off).unwrap().invalid_links, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn progress_is_reported_per_image_and_a_refusal_cancels() {
|
||||
use pdfcraft_optimize::{OptimizeError, Stage, optimize_with_progress};
|
||||
let build = || {
|
||||
let mut doc = Document::new_empty();
|
||||
let a = image(&mut doc, 300, 300, 3, false, None);
|
||||
let b = image(&mut doc, 300, 300, 1, false, None);
|
||||
let c = image(&mut doc, 300, 300, 3, true, None);
|
||||
page(&mut doc, &[("A", a), ("B", b), ("C", c)], "q 72 0 0 72 0 0 cm /A Do Q q 72 0 0 72 100 0 cm /B Do Q q 72 0 0 72 200 0 cm /C Do Q");
|
||||
doc
|
||||
};
|
||||
let mut seen = Vec::new();
|
||||
let report = optimize_with_progress(&mut build(), &Settings::default(), &mut |s| {
|
||||
seen.push(s);
|
||||
true
|
||||
})
|
||||
.unwrap();
|
||||
assert_eq!(report.images, 3);
|
||||
assert_eq!(
|
||||
seen,
|
||||
[
|
||||
Stage::Images { done: 0, total: 3 },
|
||||
Stage::Images { done: 1, total: 3 },
|
||||
Stage::Images { done: 2, total: 3 },
|
||||
Stage::Images { done: 3, total: 3 },
|
||||
Stage::CleanUp
|
||||
]
|
||||
);
|
||||
|
||||
// Stopping after the first image.
|
||||
let mut calls = 0;
|
||||
let r = optimize_with_progress(&mut build(), &Settings::default(), &mut |_| {
|
||||
calls += 1;
|
||||
calls < 2
|
||||
});
|
||||
assert!(matches!(r, Err(OptimizeError::Cancelled)), "{r:?}");
|
||||
assert_eq!(calls, 2, "nothing runs after the refusal");
|
||||
}
|
||||
Reference in new issue
Block a user