summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Heher <jakob.heher@iaik.tugraz.at>2022-08-08 13:32:30 +0200
committerJakob Heher <jakob.heher@iaik.tugraz.at>2022-08-08 13:32:30 +0200
commit3679f37f129b16daadb490d6987fdd038b096bfc (patch)
tree960193629b0899d90297d5f918f337024fad1db5
parent84a9465b14154f3e56a6b772d21e70f1c60bdf47 (diff)
downloadpdf-over-3679f37f129b16daadb490d6987fdd038b096bfc.tar.gz
pdf-over-3679f37f129b16daadb490d6987fdd038b096bfc.tar.bz2
pdf-over-3679f37f129b16daadb490d6987fdd038b096bfc.zip
cached asynchronous pdf-as placeholders
-rw-r--r--pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/SignaturePanel.java2
-rw-r--r--pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/configuration/SimpleConfigurationComposite.java73
-rw-r--r--pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PositioningState.java7
-rw-r--r--pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4SignatureParameter.java2
-rw-r--r--pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4SignaturePlaceholder.java70
5 files changed, 112 insertions, 42 deletions
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/SignaturePanel.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/SignaturePanel.java
index 879a3e98..02b1e21e 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/SignaturePanel.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/SignaturePanel.java
@@ -156,6 +156,8 @@ public class SignaturePanel extends JPanel {
this.sigPageWidth = placeholder.getWidth(null) / 4;
this.sigPageHeight = placeholder.getHeight(null) / 4;
this.sigPlaceholderTransparency = transparency;
+ renderPageToImage();
+ repaint();
}
/**
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/configuration/SimpleConfigurationComposite.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/configuration/SimpleConfigurationComposite.java
index 28baa158..6a074187 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/configuration/SimpleConfigurationComposite.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/configuration/SimpleConfigurationComposite.java
@@ -15,7 +15,6 @@
*/
package at.asit.pdfover.gui.composites.configuration;
-import java.awt.image.BufferedImage;
// Imports
import java.io.File;
import java.util.Arrays;
@@ -34,7 +33,6 @@ import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormLayout;
@@ -58,13 +56,13 @@ import at.asit.pdfover.gui.controls.Dialog.BUTTONS;
import at.asit.pdfover.gui.controls.ErrorDialog;
import at.asit.pdfover.gui.controls.ErrorMarker;
import at.asit.pdfover.gui.exceptions.InvalidEmblemFile;
-import at.asit.pdfover.gui.utils.ImageConverter;
import at.asit.pdfover.gui.utils.SWTUtils;
-import at.asit.pdfover.gui.workflow.config.ConfigurationManager;
import at.asit.pdfover.gui.workflow.config.ConfigurationDataInMemory;
+import at.asit.pdfover.gui.workflow.config.ConfigurationManager;
import at.asit.pdfover.gui.workflow.states.State;
import at.asit.pdfover.signator.Emblem;
import at.asit.pdfover.signer.pdfas.PdfAs4SignatureParameter;
+import at.asit.pdfover.signer.pdfas.PdfAs4SignaturePlaceholder;
/**
*
@@ -338,41 +336,9 @@ public class SimpleConfigurationComposite extends ConfigurationCompositeBase {
reloadResources();
}
- boolean needSigPreviewUpdate = true;
+ private PdfAs4SignatureParameter sigPreviewParam = null;
private Image sigPreview = null;
void paintSignaturePreview(PaintEvent evt) {
- if (needSigPreviewUpdate)
- {
- String image = this.configurationContainer.getEmblemPath();
- ImageData img = null;
-
- try {
- PdfAs4SignatureParameter param = new PdfAs4SignatureParameter();
- param.signatureProfile = this.configurationContainer.getSignatureProfile();
- if(this.configurationContainer.signatureNote != null && !this.configurationContainer.signatureNote.isEmpty()) {
- param.signatureNote = this.configurationContainer.signatureNote;
- }
-
- param.signatureLanguage = this.configurationContainer.signatureLocale.getLanguage();
- param.enablePDFACompat = this.configurationContainer.signaturePDFACompat;
- if (image != null && !image.trim().isEmpty()) {
- param.emblem = new Emblem(image);
- }
-
- // TODO getPlaceholder is super slow, can we async this somehow?
- img = ImageConverter.convertToSWT((BufferedImage) param.getPlaceholder());
- } catch (Exception e) {
- log.error("Failed to load image for display...", e);
- }
-
- if (img != null) {
- this.sigPreview = new Image(this.getDisplay(), img);
- } else {
- this.sigPreview = null;
- }
- needSigPreviewUpdate = false;
- }
-
if (this.sigPreview == null)
return;
Rectangle r = this.sigPreview.getBounds();
@@ -443,8 +409,37 @@ public class SimpleConfigurationComposite extends ConfigurationCompositeBase {
}
void signatureBlockPreviewChanged() {
- needSigPreviewUpdate = true;
- this.cSigPreview.redraw();
+ try {
+ PdfAs4SignatureParameter param = new PdfAs4SignatureParameter();
+ param.signatureProfile = this.configurationContainer.getSignatureProfile();
+ if(this.configurationContainer.signatureNote != null && !this.configurationContainer.signatureNote.isEmpty()) {
+ param.signatureNote = this.configurationContainer.signatureNote;
+ }
+
+ param.signatureLanguage = this.configurationContainer.signatureLocale.getLanguage();
+ param.enablePDFACompat = this.configurationContainer.signaturePDFACompat;
+ String image = this.configurationContainer.getEmblemPath();
+ if (image != null && !image.trim().isEmpty()) {
+ param.emblem = new Emblem(image);
+ }
+
+ this.sigPreviewParam = param;
+ PdfAs4SignaturePlaceholder.For(param, (p) -> {
+ if (this.isDisposed())
+ return;
+
+ this.getDisplay().syncExec(() -> {
+ if (this.sigPreviewParam != param)
+ return;
+ if (this.sigPreview != null)
+ this.sigPreview.dispose();
+ this.sigPreview = new Image(this.getDisplay(), p.getSWTImage());
+ this.cSigPreview.redraw();
+ });
+ });
+ } catch (Exception e) {
+ log.error("Failed to load image for display...", e);
+ }
}
void processEmblemChanged(String filename) {
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PositioningState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PositioningState.java
index f814bd85..1a4767dd 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PositioningState.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PositioningState.java
@@ -37,6 +37,7 @@ import at.asit.pdfover.gui.workflow.config.ConfigurationManager;
import at.asit.pdfover.signator.Emblem;
import at.asit.pdfover.signator.SignaturePosition;
import at.asit.pdfover.signer.pdfas.PdfAs4SignatureParameter;
+import at.asit.pdfover.signer.pdfas.PdfAs4SignaturePlaceholder;
/**
* Decides where to position the signature block
@@ -117,9 +118,11 @@ public class PositioningState extends State {
param.signatureLanguage = config.getSignatureLocale().getLanguage();
param.enablePDFACompat = config.getSignaturePdfACompat();
- this.positionComposite.setPlaceholder(
- param.getPlaceholder(),
+ PdfAs4SignaturePlaceholder.For(param, (p) -> {
+ this.positionComposite.setPlaceholder(
+ p.getAWTImage(),
config.getPlaceholderTransparency());
+ });
if (this.previousPosition != null && !this.previousPosition.useAutoPositioning())
{
diff --git a/pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4SignatureParameter.java b/pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4SignatureParameter.java
index 4356f1e0..78dda185 100644
--- a/pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4SignatureParameter.java
+++ b/pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4SignatureParameter.java
@@ -83,7 +83,7 @@ public class PdfAs4SignatureParameter {
/** The signature profile in use */
public Profile signatureProfile = Profile.getDefaultProfile();
- public Image getPlaceholder() {
+ Image getPlaceholder() {
String sigProfile = getPdfAsSignatureProfileId();
String sigEmblem = (this.emblem == null ? null : this.emblem.getCachedFileName());
diff --git a/pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4SignaturePlaceholder.java b/pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4SignaturePlaceholder.java
new file mode 100644
index 00000000..b944bf24
--- /dev/null
+++ b/pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4SignaturePlaceholder.java
@@ -0,0 +1,70 @@
+package at.asit.pdfover.signer.pdfas;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.TreeMap;
+import java.util.function.Consumer;
+
+import at.asit.pdfover.commons.utils.ImageUtil;
+
+/**
+ * caches placeholders for signature parameters (placeholder generation is pretty slow)
+ */
+public final class PdfAs4SignaturePlaceholder implements Runnable {
+ private static TreeMap<PdfAs4SignatureParameter, PdfAs4SignaturePlaceholder> cache = new TreeMap<>(
+ Comparator
+ .comparing(PdfAs4SignatureParameter::getPdfAsSignatureProfileId)
+ .thenComparing((p) -> { return (p.emblem != null) ? p.emblem.getOriginalFileHash() : ""; })
+ .thenComparing((p) -> { return p.signatureNote; }, Comparator.nullsFirst(String::compareTo))
+ );
+
+ /**
+ * request a placeholder for the specified parameter asynchronously
+ * @param callback the callback to be invoked on completion (may also be invoked before this function returns!)
+ */
+ public static void For(PdfAs4SignatureParameter param, Consumer<PdfAs4SignaturePlaceholder> callback) {
+ synchronized(cache) {
+ cache.computeIfAbsent(param, (p) -> new PdfAs4SignaturePlaceholder(p)).AddCallback(callback);
+ }
+ }
+
+ private final PdfAs4SignatureParameter param;
+ private PdfAs4SignaturePlaceholder(PdfAs4SignatureParameter param) {
+ this.param = param;
+ new Thread(this).start();
+ }
+
+ private java.awt.image.BufferedImage awtImageData;
+ /** AWT image data for the placeholder */
+ public java.awt.image.BufferedImage getAWTImage() { return this.awtImageData; }
+ private org.eclipse.swt.graphics.ImageData swtImageData;
+ /** SWT image data for the placeholder */
+ public org.eclipse.swt.graphics.ImageData getSWTImage() { return this.swtImageData; }
+
+ private ArrayList<Consumer<PdfAs4SignaturePlaceholder>> callbacks = new ArrayList<>();
+ private void AddCallback(Consumer<PdfAs4SignaturePlaceholder> c) {
+ synchronized (this) {
+ if (this.callbacks != null)
+ {
+ this.callbacks.add(c);
+ return;
+ } /* else... */
+ }
+ /* ... else, not synchronized */
+ c.accept(this);
+ }
+
+
+ @Override
+ public void run() {
+ this.awtImageData = (java.awt.image.BufferedImage) this.param.getPlaceholder();
+ this.swtImageData = ImageUtil.convertToSWT(this.awtImageData);
+ ArrayList<Consumer<PdfAs4SignaturePlaceholder>> _callbacks;
+ synchronized (this) {
+ _callbacks = this.callbacks;
+ this.callbacks = null;
+ }
+ _callbacks.forEach((c) -> c.accept(this));
+ }
+
+}