From cf2984c6f72efb6467e868a3bcc4c60a9f26aca5 Mon Sep 17 00:00:00 2001 From: Sebastian Rasmussen Date: Thu, 28 Sep 2023 02:39:35 +0200 Subject: [PATCH] java: Add progress meter for rendering of page contents. For slow-rendering PDFs this will pop up a progress meter dialog that allows the user get feed back on progress or abort the rendering. An example of this is torture-test.pdf with its huge amount of paths. --- platform/java/example/Viewer.java | 81 ++++++++++++++++++++++++++- platform/java/example/ViewerCore.java | 4 +- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/platform/java/example/Viewer.java b/platform/java/example/Viewer.java index 67579bb5ad..7a72c79e11 100644 --- a/platform/java/example/Viewer.java +++ b/platform/java/example/Viewer.java @@ -126,6 +126,7 @@ public class Viewer extends Frame implements WindowListener, ActionListener, Ite protected List outlineList; protected OCRProgressmeter OCRmeter; + protected RenderProgressmeter renderMeter; protected int number = 0; @@ -578,10 +579,17 @@ protected void render() { ctm.f -= atOrigin.y0; Rect bounds = new Rect(bbox).transform(ctm); - doc.renderPage(ctm, bounds, icc, antialias, invert, tint, tintBlack, tintWhite, + Cookie cookie = new Cookie(); + + renderMeter = new RenderProgressmeter(this, "Rendering...", cookie, 250); + renderMeter.setLocationRelativeTo(this); + pageCanvas.requestFocusInWindow(); + + doc.renderPage(ctm, bounds, icc, antialias, invert, tint, tintBlack, tintWhite, cookie, new ViewerCore.OnException() { public void run(Throwable t) { - exception(t); + if (!renderMeter.cancelled) + exception(t); } } ); @@ -1804,6 +1812,73 @@ public boolean progress(int page, int percent) { } } + class RenderProgressmeter extends Progressmeter { + Cookie cookie; + + public RenderProgressmeter(Frame parent, String title, Cookie cookie, final int update) { + super(parent, title, false, "Progress: 100%"); + this.cookie = cookie; + + (new Thread() { + public void run() { + try { + int slept = 0; + while (!progress(slept)) + { + sleep(update); + slept += update; + } + } catch (InterruptedException e) { + } + } + }).start(); + } + + public void cancel() { + super.cancel(); + cookie.abort(); + } + + public boolean progress(int slept) { + int progress = cookie.getProgress(); + int max = cookie.getProgressMax(); + + if (max <= 0 && progress < 100) + max = 100; + else if (max <= 0 && progress > 100) + { + int v = progress; + max = 10; + while (v > 10) + { + v /= 10; + max *= 10; + } + } + + if (progress >= max) + done = true; + + int percent = (int) ((float) progress / max * 100.0f); + + StringBuilder text = new StringBuilder(); + text.append("Progress: "); + text.append(percent); + text.append("%"); + + if (slept > 0) + setVisible(true); + + if (progress(text.toString())) + { + setVisible(false); + dispose(); + return true; + } + + return false; + } + } public static void main(String[] args) { String selectedPath; @@ -1938,6 +2013,8 @@ public void onPageContentsChange(Pixmap pixmap, Rect[] links, String[] linkURIs, this.linkURIs = linkURIs; this.hits = hits; redraw(); + if (renderMeter != null) + renderMeter.done(); } public void onSearchStart(Location startPage, Location finalPage, int direction, String needle) { searchField.setEnabled(false); diff --git a/platform/java/example/ViewerCore.java b/platform/java/example/ViewerCore.java index f4b4b91bcf..5cb4d0ca71 100644 --- a/platform/java/example/ViewerCore.java +++ b/platform/java/example/ViewerCore.java @@ -408,7 +408,7 @@ public void exception(Throwable t) { }); } - public void renderPage(final Matrix ctm, final Rect bbox, final boolean icc, final int antialias, final boolean invert, final boolean tint, final int tintBlack, final int tintWhite, final OnException onException) { + public void renderPage(final Matrix ctm, final Rect bbox, final boolean icc, final int antialias, final boolean invert, final boolean tint, final int tintBlack, final int tintWhite, final Cookie cookie, final OnException onException) { worker.add(new Worker.Task() { Pixmap pixmap = null; Rect[] links = null; @@ -452,7 +452,7 @@ public void work() { Context.setAntiAliasLevel(antialias); DrawDevice dev = new DrawDevice(pixmap); - page.run(dev, ctm, null); + page.run(dev, ctm, cookie); dev.close(); dev.destroy();