From 65aa495c982c105619f1d14a04517b749df51366 Mon Sep 17 00:00:00 2001 From: FredApps Date: Thu, 5 Nov 2026 13:19:49 +0100 Subject: [PATCH] Enhance scanned file: re-render the page shown after a successful run --- crates/ui-egui/src/canvas/tests.rs | 37 +++++++++++++++++++ crates/ui-egui/src/workflows/scan_clean_ui.rs | 4 ++ 2 files changed, 41 insertions(+) diff --git a/crates/ui-egui/src/canvas/tests.rs b/crates/ui-egui/src/canvas/tests.rs index d5b8312d6c..5260ccc4ed 100644 --- a/crates/ui-egui/src/canvas/tests.rs +++ b/crates/ui-egui/src/canvas/tests.rs @@ -2380,3 +2380,40 @@ fn a_camera_corner_at_the_page_edge_is_hit_on_the_page_only() { assert!(crate::camera_ui::hit(&xf, 0, &v, pos2(14.0, 24.0)).is_some(), "on the page"); assert!(crate::camera_ui::hit(&xf, 0, &v, pos2(6.0, 16.0)).is_none(), "just off it"); } + +/// #5125: after Enhance scanned file, the page shown is re-rendered, not the raster of the +/// scan before it was cleaned (same scale, so nothing else would replace it). +#[test] +fn enhancing_a_scan_re_renders_the_page_shown() { + let (w, h) = (64usize, 64usize); + let px: Vec = (0..w * h).map(|i| if i % w < 4 { 30 } else { 198 }).collect(); + let mut pdf = format!( + "%PDF-1.7\n1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n2 0 obj\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\nendobj\n3 0 obj\n<< /Type /Page /Parent 2 0 R /MediaBox [0 0 {w} {h}] /Resources << /XObject << /Im0 4 0 R >> >> /Contents 5 0 R >>\nendobj\n4 0 obj\n<< /Type /XObject /Subtype /Image /Width {w} /Height {h} /ColorSpace /DeviceGray /BitsPerComponent 8 /Length {} >>\nstream\n", + px.len() + ) + .into_bytes(); + pdf.extend_from_slice(&px); + let content = format!("q {w} 0 0 {h} 0 0 cm /Im0 Do Q"); + pdf.extend_from_slice( + format!( + "\nendstream\nendobj\n5 0 obj\n<< /Length {} >>\nstream\n{content}\nendstream\nendobj\ntrailer\n<< /Root 1 0 R >>\n%%EOF\n", + content.len() + ) + .as_bytes(), + ); + let mut app = PdfCraftApp::new(); + app.open_bytes("scan.pdf", None, pdf).unwrap(); + let (i, doc) = app.active_ids().unwrap(); + let ctx = egui::Context::default(); + let tex = ctx.load_texture("before", egui::ColorImage::filled([1, 1], Color32::WHITE), TextureOptions::LINEAR); + app.views[i].pages.insert(0, PageTex { tag: 1000, tex }); + let job = app.session.scan_clean_job(doc, &[], pdfcraft_engine::scan_clean::ScanCleanSettings::default()).unwrap(); + let cleaned = job.run(|_, _| true).unwrap(); + assert_eq!(cleaned.report.pages, vec![0], "the page is a scan and gets cleaned"); + let progress = + std::sync::Arc::new(std::sync::Mutex::new(crate::scan_clean_ui::ScanCleanProgress { result: Some(Ok(cleaned)), ..Default::default() })); + app.scan_clean_run = Some(crate::scan_clean_ui::ScanCleanRun { doc, progress }); + app.poll_scan_clean(); + assert!(app.scan_clean_run.is_none()); + assert_eq!(app.views[i].pages.get(&0).unwrap().tag, STALE_TAG, "the old raster is re-rendered"); +} diff --git a/crates/ui-egui/src/workflows/scan_clean_ui.rs b/crates/ui-egui/src/workflows/scan_clean_ui.rs index 64f8ce48eb..81d6764af9 100644 --- a/crates/ui-egui/src/workflows/scan_clean_ui.rs +++ b/crates/ui-egui/src/workflows/scan_clean_ui.rs @@ -230,6 +230,10 @@ impl PdfCraftApp { self.progress_notice = None; match result.and_then(|cleaned| self.session.apply_scan_clean(doc, cleaned)) { Ok(report) => { + // The page rasters, tiles and thumbnails show the old pixels at the same scale. + for v in self.views.iter_mut().filter(|v| v.id == doc) { + v.invalidate_content(); + } let msg = summary(&report); self.notify(msg); }