diff options
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)); +    } +     +} | 
