From 7fb08fc5b27c7dacb5afe91eb8c1e7f6bf403b04 Mon Sep 17 00:00:00 2001
From: tkellner <tkellner@174cde9d-5d70-4d2a-aa98-46368bc2aaf7>
Date: Wed, 10 Apr 2013 19:03:45 +0000
Subject: Replace ICEPdf with PDFRenderer

git-svn-id: https://joinup.ec.europa.eu/svn/pdf-over/trunk@107 174cde9d-5d70-4d2a-aa98-46368bc2aaf7
---
 .../pdfover/gui/composites/PDFViewerComposite.java | 187 --------------
 .../gui/composites/PositioningComposite.java       | 216 ++++++++--------
 .../pdfover/gui/composites/SignaturePanel.java     | 285 +++++++++++++++++++++
 .../gui/workflow/states/PositioningState.java      |  15 +-
 4 files changed, 405 insertions(+), 298 deletions(-)
 delete mode 100644 pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/PDFViewerComposite.java
 create mode 100644 pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/SignaturePanel.java

(limited to 'pdf-over-gui/src/main/java')

diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/PDFViewerComposite.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/PDFViewerComposite.java
deleted file mode 100644
index f2852fcc..00000000
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/PDFViewerComposite.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright 2012 by A-SIT, Secure Information Technology Center Austria
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * http://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- */
-package at.asit.pdfover.gui.composites;
-
-// Imports
-import java.awt.Canvas;
-import java.awt.Dimension;
-import java.awt.Frame;
-import java.awt.Graphics;
-import java.awt.geom.Rectangle2D;
-import java.io.File;
-import java.io.IOException;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.awt.SWT_AWT;
-import org.eclipse.swt.events.KeyAdapter;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.widgets.Composite;
-import org.icepdf.core.exceptions.PDFException;
-import org.icepdf.core.exceptions.PDFSecurityException;
-import org.icepdf.core.pobjects.Document;
-import org.icepdf.core.pobjects.Page;
-import org.icepdf.core.util.GraphicsRenderingHints;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import at.asit.pdfover.gui.workflow.states.PositioningState;
-
-/**
- * Displays a PDF document
- */
-public class PDFViewerComposite extends Composite {
-	/**
-	 * SFL4J Logger instance
-	 **/
-	private static final Logger log = LoggerFactory
-			.getLogger(PDFViewerComposite.class);
-
-	/**
-	 * PDF document
-	 */
-	protected Document document;
-
-	/**
-	 * Currently selected page in the document
-	 */
-	protected int page;
-
-	/**
-	 * AWT Canvas displaying the document
-	 */
-	private Canvas canvas = null;
-
-	/**
-	 * Dimension of each page at default zoom
-	 */
-	Dimension[] base_dimensions;
-
-	/**
-	 * Set the document to be displayed
-	 * @param document PDF document to be displayed
-	 * @throws PDFException Error parsing PDF document
-	 * @throws PDFSecurityException Error decrypting PDF document (not supported)
-	 * @throws IOException I/O Error
-	 */
-	public void setDocument(File document) throws PDFException, PDFSecurityException, IOException {
-		this.document = new Document();
-		this.document.setFile(document.getPath());
-		int pages = this.document.getNumberOfPages();
-
-		this.base_dimensions = new Dimension[pages];
-		for (int page = 0; page < pages; ++page)
-			this.base_dimensions[page] = this.document.getPageDimension(page, 0f, 1.0f).toDimension();
-
-		this.page = pages - 1;
-
-		if (this.canvas != null)
-			this.canvas.repaint();
-	}
-
-	/**
-	 * Get the currently selected page in the document
-	 * @return current page
-	 */
-	public int getPage() {
-		return this.page;
-	}
-
-	/**
-	 * Set the visible page in the document
-	 * @param page new active page
-	 */
-	public void setPage(int page) {
-		this.page = page;
-		this.canvas.repaint();
-	}
-
-	/**
-	 * Create the PDF Viewer composite.
-	 * Displays a PDF document.
-	 * Starts on the last page.
-	 * @param parent parent Composite
-	 * @param style 
-	 * @param document
-	 * @throws PDFException Error parsing PDF document
-	 * @throws PDFSecurityException Error decrypting PDF document (not supported)
-	 * @throws IOException I/O Error
-	 */
-	public PDFViewerComposite(Composite parent, int style, File document) throws PDFException, PDFSecurityException, IOException {
-		super(parent, style);
-
-		setDocument(document);
-
-		Frame frame = SWT_AWT.new_Frame(this);
-		this.canvas = new Canvas() {
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			public void paint(Graphics g) {
-				if (g == null || g.getClip() == null)
-					return;
-				int page = getPage();
-				// Make page always fit to window
-				Dimension d = getSize();
-				double h_zoom = d.getWidth() / PDFViewerComposite.this.base_dimensions[page].width;
-				double v_zoom = d.getHeight() / PDFViewerComposite.this.base_dimensions[page].height;
-				float zoom = (float) (h_zoom < v_zoom ? h_zoom : v_zoom);
-				if (v_zoom < h_zoom)
-				{
-					// Page is narrower than window, center it
-					g.translate((int) ((d.width - (PDFViewerComposite.this.base_dimensions[page].width * zoom)) / 2), 0);
-				}
-
-				log.debug("Repainting " + g.getClipBounds().width + "x" + g.getClipBounds().height + " - " + d.width + "x" + d.height);
-				PDFViewerComposite.this.document.paintPage(page, g, GraphicsRenderingHints.SCREEN, Page.BOUNDARY_CROPBOX, 0f, zoom);
-			}
-		};
-		frame.add(this.canvas);
-		frame.pack();
-		frame.setVisible(true);
-
-		this.addKeyListener(new KeyAdapter() {
-			@Override
-			public void keyPressed(KeyEvent e) {
-				int page = getPage();
-				int old_page = page;
-
-				switch (e.keyCode)
-				{
-					case SWT.PAGE_DOWN:
-						if (page < (PDFViewerComposite.this.document.getNumberOfPages() - 1))
-							++page;
-						break;
-
-					case SWT.PAGE_UP:
-						if (page > 0)
-							--page;
-						break;
-
-					case SWT.END:
-						page = (PDFViewerComposite.this.document.getNumberOfPages() - 1);
-						break;
-
-					case SWT.HOME:
-						page = 0;
-						break;
-				}
-
-				if (page != old_page)
-					setPage(page);
-			}
-		});
-	}
-}
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/PositioningComposite.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/PositioningComposite.java
index f1f89d79..d1309cf9 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/PositioningComposite.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/PositioningComposite.java
@@ -16,32 +16,30 @@
 package at.asit.pdfover.gui.composites;
 
 // Imports
+import java.awt.Frame;
+import java.awt.Image;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
 import java.io.File;
 import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
 
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.DragDetectEvent;
-import org.eclipse.swt.events.DragDetectListener;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseMoveListener;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.awt.SWT_AWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.icepdf.core.exceptions.PDFException;
-import org.icepdf.core.exceptions.PDFSecurityException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import at.asit.pdfover.gui.workflow.states.State;
 import at.asit.pdfover.signator.SignaturePosition;
 
+import com.sun.pdfview.PDFFile;
+
 /**
  * 
  *
@@ -53,55 +51,40 @@ public class PositioningComposite extends StateComposite {
 	static final Logger log = LoggerFactory
 			.getLogger(PositioningComposite.class);
 
-	PDFViewerComposite viewer = null;
+	private SignaturePanel viewer = null;
 
-	Canvas signature = null;
+	private PDFFile pdf = null;
 
-	private SignaturePosition position = null;
+	private Frame frame = null;
 
-	boolean doDrag = false;
+	int currentPage;
 
-	Point origMousePos = null;
-	Rectangle origSigPos = null;
+	int numPages;
 
-	/**
-	 * Gets the position of the signature
-	 * @return the SignaturePosition
-	 */
-	public SignaturePosition getPosition() {
-		return this.position;
-	}
-
-	/**
-	 * Sets the position
-	 * @param position
-	 */
-	public void setPosition(SignaturePosition position) {
-		this.position = position;
-	}
+	private SignaturePosition position = null;
 
 	/**
 	 * Set the PDF Document to display
 	 * @param document document to display
-	 * @throws PDFException Error parsing PDF document
-	 * @throws PDFSecurityException Error decrypting PDF document (not supported)
 	 * @throws IOException I/O Error
 	 */
-	public void displayDocument(File document) throws PDFException, PDFSecurityException, IOException {
+	public void displayDocument(File document) throws IOException {
+		RandomAccessFile rafile = new RandomAccessFile(document, "r"); //$NON-NLS-1$
+		FileChannel chan = rafile.getChannel();
+		ByteBuffer buf = chan.map(FileChannel.MapMode.READ_ONLY, 0, chan.size());
+		chan.close();
+		rafile.close();
+
+		this.pdf = new PDFFile(buf);
 		if (this.viewer == null)
 		{
-			this.viewer = new PDFViewerComposite(this, SWT.EMBEDDED | SWT.NO_BACKGROUND, document);
-			resizeViewer();
+			this.viewer = new SignaturePanel(this.pdf);
+			this.frame.add(this.viewer);
 		}
 		else
-			this.viewer.setDocument(document);
-	}
-
-	void resizeViewer()
-	{
-		Rectangle clientArea = this.getClientArea();
-		log.debug("Resizing to " + clientArea.width + "x" + clientArea.height);
-		this.viewer.setBounds(0, 0, clientArea.width, clientArea.height);
+			this.viewer.setDocument(this.pdf);
+		this.numPages = this.pdf.getNumPages();
+		showPage(this.numPages);
 	}
 
 	/**
@@ -111,62 +94,73 @@ public class PositioningComposite extends StateComposite {
 	 * @param state 
 	 */
 	public PositioningComposite(Composite parent, int style, State state) {
-		super(parent, style, state);
-		this.setLayout(null);
-
-		this.addListener(SWT.Resize, new Listener() {
-			@Override
-			public void handleEvent(Event e) {
-				if (PositioningComposite.this.viewer != null)
-					resizeViewer();
-			}
-		});
-
-		this.signature = new Canvas(this, SWT.NO_BACKGROUND);
-		this.signature.setBounds(200, 200, 150, 40);
-		this.signature.addPaintListener(new PaintListener() {
-			@Override
-			public void paintControl(PaintEvent e) {
-//				PositioningComposite.this.viewer.redraw();
-				Rectangle r = ((Canvas) e.widget).getBounds();
-				e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_BLUE));
-				e.gc.drawFocus(5, 5, r.width - 10, r.height - 10);
-				e.gc.drawText("Position Signature", 10, 10);
-			}
-		});
-		this.signature.addDragDetectListener(new DragDetectListener() {
-			@Override
-			public void dragDetected(DragDetectEvent e) {
-				PositioningComposite.this.doDrag = true;
-				origMousePos = Display.getCurrent().getCursorLocation();
-				origSigPos = ((Canvas) e.widget).getBounds();
+		super(parent, style | SWT.EMBEDDED, state);
+		//this.setLayout(null);
+		this.frame = SWT_AWT.new_Frame(this);
+		this.addKeyListener(this.keyListener);
+		this.frame.addMouseWheelListener(this.mouseListener);
+	}
+
+	private KeyListener keyListener = new KeyAdapter() {
+		@Override
+		public void keyPressed(KeyEvent e) {
+			int newPage = PositioningComposite.this.currentPage;
+
+			switch (e.keyCode)
+			{
+				case SWT.PAGE_DOWN:
+					if (PositioningComposite.this.currentPage < PositioningComposite.this.numPages)
+						++newPage;
+					break;
+
+				case SWT.PAGE_UP:
+					if (PositioningComposite.this.currentPage > 1)
+						--newPage;
+					break;
+
+				case SWT.END:
+					newPage = PositioningComposite.this.numPages;
+					break;
+
+				case SWT.HOME:
+					newPage = 1;
+					break;
+
+				case SWT.CR:
+				case SWT.KEYPAD_CR:
+					PositioningComposite.this.setFinalPosition();
+					break;
 			}
-		});
-		this.signature.addMouseMoveListener(new MouseMoveListener() {
-			@Override
-			public void mouseMove(MouseEvent e) {
-				if (PositioningComposite.this.doDrag)
-				{
-					Point newMousePos = Display.getCurrent().getCursorLocation();
-					int x = origSigPos.x + (newMousePos.x - origMousePos.x);
-					int y = origSigPos.y + (newMousePos.y - origMousePos.y);
-					PositioningComposite.this.signature.setBounds(x, y, origSigPos.width, origSigPos.height);
-				}
+
+			if (newPage != PositioningComposite.this.currentPage)
+				showPage(newPage);
+		}
+	};
+
+	private MouseWheelListener mouseListener = new MouseWheelListener() {
+		@Override
+		public void mouseWheelMoved(MouseWheelEvent e) {
+			int newPage = PositioningComposite.this.currentPage;
+
+			if (e.getUnitsToScroll() < 0)
+			{
+				if (PositioningComposite.this.currentPage > 1)
+					newPage--;
 			}
-		});
-		this.signature.addMouseListener(new MouseAdapter() {
-			@Override
-			public void mouseUp(MouseEvent e) {
-				if (PositioningComposite.this.doDrag)
-				{
-					PositioningComposite.this.doDrag = false;
-					return;
-				}
-				// TODO: FIX to get real position
-				PositioningComposite.this.setPosition(new SignaturePosition()); // Setting auto position for testing
-				PositioningComposite.this.state.updateStateMachine();
+			else if (e.getUnitsToScroll() > 0)
+			{
+				if (PositioningComposite.this.currentPage < PositioningComposite.this.numPages)
+					newPage++;
 			}
-		});
+
+			if (newPage != PositioningComposite.this.currentPage)
+				showPage(newPage);
+		}		
+	};
+
+	void showPage(int page) {
+		this.currentPage = page;
+		this.viewer.showPage(page);
 	}
 
 	@Override
@@ -181,4 +175,22 @@ public class PositioningComposite extends StateComposite {
 	public void doLayout() {
 		this.layout(true, true);
 	}
+
+	/**
+	 * Set the signature position and continue to the next state
+	 * @param position the signature position
+	 */
+	void setFinalPosition() {
+		// TODO: check if this is the real position
+		this.position = new SignaturePosition(this.viewer.getSignaturePositionX(), this.viewer.getSignaturePositionY());
+		PositioningComposite.this.state.updateStateMachine();
+	}
+
+	/**
+	 * Get the signature position
+	 * @return the signature position
+	 */
+	public SignaturePosition getPosition() {
+		return this.position;
+	}
 }
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
new file mode 100644
index 00000000..f90b2591
--- /dev/null
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/SignaturePanel.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright 2012 by A-SIT, Secure Information Technology Center Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package at.asit.pdfover.gui.composites;
+
+// Imports
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Point2D;
+
+import javax.swing.JPanel;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.pdfview.PDFFile;
+import com.sun.pdfview.PDFPage;
+
+/**
+ * 
+ */
+public class SignaturePanel extends JPanel {
+	/**
+	 * SLF4J Logger instance
+	 **/
+	private static final Logger log = LoggerFactory
+			.getLogger(SignaturePanel.class);
+
+	/** Default serial version ID */
+	private static final long serialVersionUID = 1L;
+
+	/** The PDF file being displayed */
+	private PDFFile pdf;
+	/** The image of the rendered PDF page being displayed */
+	Image currentImage;
+	/** The current PDFPage that was rendered into currentImage */
+	private PDFPage currentPage;
+	/** The current page number */
+	AffineTransform currentXform;
+	/** The horizontal offset of the image from the left edge of the panel */
+	int offx;
+	/** The vertical offset of the image from the top of the panel */
+	int offy;
+	/** The size of the image */
+	private Dimension prevSize;
+	/** The position of the signature, in document space */
+	Point2D sigPagePos;
+	/** The position of the signature, in screen space */
+	Point2D sigScreenPos;
+
+	/**
+	 * Create a new PagePanel, with a default size of 800 by 600 pixels.
+	 * @param pdf the PDFFile to display
+	 */
+	public SignaturePanel(PDFFile pdf) {
+		super(new BorderLayout());
+		this.pdf = pdf;
+		this.sigPagePos = null;
+		setPreferredSize(new Dimension(800, 600));
+		setFocusable(true);
+		addMouseListener(this.mouseListener);
+		addMouseMotionListener(this.mouseListener);
+	}
+
+	/**
+	 * Set a new document to be displayed
+	 * @param pdf the PDFFile to be displayed
+	 */
+	public void setDocument(PDFFile pdf)
+	{
+		this.pdf = pdf;
+		this.sigPagePos = null;
+		showPage(pdf.getNumPages());
+	}
+
+	/**
+	 * Change the currently displayed page
+	 * @param page the number of the page to display
+	 */
+	public void showPage(int page) {
+		//sigPagePos = null;
+		showPage(this.pdf.getPage(page));
+	}
+
+	/**
+	 * Get the current horizontal position of the signature
+	 * @return signature x coordinate
+	 */
+	public float getSignaturePositionX() {
+		return (float) this.sigPagePos.getX();
+	}
+
+	/**
+	 * Get the current vertical position of the signature
+	 * @return signature y coordinate
+	 */
+	public float getSignaturePositionY() {
+		return (float) this.sigPagePos.getY();
+	}
+
+	/**
+	 * Stop the generation of any previous page, and draw the new one.
+	 * 
+	 * @param page the PDFPage to draw.
+	 */
+	private synchronized void showPage(PDFPage page) {
+		// stop drawing the previous page
+		if (this.currentPage != null && this.prevSize != null) {
+			this.currentPage.stop(this.prevSize.width, this.prevSize.height, null);
+		}
+
+		// set up the new page
+		this.currentPage = page;
+
+		if (this.currentPage == null) {
+			// no page
+			this.currentImage = null;
+			this.currentXform = null;
+			repaint();
+		} else {
+			// start drawing
+			Dimension sz = getSize();
+			if (sz.width + sz.height == 0) {
+				// no image to draw.
+				return;
+			}
+
+			Dimension pageSize = this.currentPage.getUnstretchedSize(sz.width, sz.height,
+					null);
+
+			// get the new image
+			this.currentImage = this.currentPage.getImage(pageSize.width, pageSize.height,
+					null, this);
+
+			// calculate the transform from page to screen space
+			this.currentXform = this.currentPage.getInitialTransform(pageSize.width,
+					pageSize.height, null);
+
+			if (this.sigPagePos != null)
+				this.sigScreenPos = this.currentXform.transform(this.sigPagePos, this.sigScreenPos);
+
+			// invert the transform (screen to page space)
+			try {
+				this.currentXform = this.currentXform.createInverse();
+			} catch (NoninvertibleTransformException nte) {
+				log.error("Error inverting page transform!", nte);
+			}
+
+			if (this.sigPagePos == null)
+			{
+				this.sigScreenPos = new Point2D.Double((pageSize.getWidth() / 3) * 2, (pageSize.getHeight() / 4) * 3);
+				this.sigPagePos = this.currentXform.transform(this.sigScreenPos, this.sigPagePos);
+			}
+
+			this.prevSize = pageSize;
+
+			repaint();
+		}
+	}
+
+	/**
+	 * Draw the image.
+	 */
+	@Override
+	public void paint(Graphics g) {
+		Dimension sz = getSize();
+		g.setColor(getBackground());
+		g.fillRect(0, 0, getWidth(), getHeight());
+		if (this.currentImage == null) {
+			g.setColor(Color.black);
+			g.drawString("No page selected", getWidth() / 2 - 30,
+					getHeight() / 2);
+			if (this.currentPage != null) {
+				showPage(this.currentPage);
+			}
+		} else {
+			// draw the image
+			int imwid = this.currentImage.getWidth(null);
+			int imhgt = this.currentImage.getHeight(null);
+
+			// draw it centered within the panel
+			this.offx = (sz.width - imwid) / 2;
+			this.offy = (sz.height - imhgt) / 2;
+
+			if ((imwid == sz.width && imhgt <= sz.height)
+					|| (imhgt == sz.height && imwid <= sz.width)) {
+
+				g.drawImage(this.currentImage, this.offx, this.offy, this);
+
+				g.setColor(Color.red);
+				int sigx = (int) (this.offx + this.sigScreenPos.getX());
+				int sigy = (int) (this.offy + this.sigScreenPos.getY());
+				g.drawRect(sigx - 10, sigy - 10, 20, 20);
+
+			} else {
+				// the image is bogus. try again, or give up.
+				if (this.currentPage != null) {
+					showPage(this.currentPage);
+				}
+				g.setColor(Color.black);
+				g.drawString("Could not render page", getWidth() / 2 - 30,
+						getHeight() / 2);
+			}
+		}
+	}
+
+	/**
+	 * Handles notification of the fact that some part of the image changed.
+	 * Repaints that portion.
+	 * 
+	 * @return true if more updates are desired.
+	 */
+	@Override
+	public boolean imageUpdate(Image img, int infoflags, int x, int y,
+			int width, int height) {
+		if ((infoflags & (SOMEBITS | ALLBITS)) != 0) {
+			repaint(x + this.offx, y + this.offy, width, height);
+		}
+		return ((infoflags & (ALLBITS | ERROR | ABORT)) == 0);
+	}
+
+	private MouseAdapter mouseListener = new MouseAdapter() {
+
+		private void updateSigPos(int sigx, int sigy) {
+			if (SignaturePanel.this.currentImage == null)
+				return;
+			sigx -= SignaturePanel.this.offx;
+			sigx = clamp(sigx, 0, SignaturePanel.this.currentImage.getWidth(null));
+			sigy -= SignaturePanel.this.offy;
+			sigy = clamp(sigy, 0, SignaturePanel.this.currentImage.getHeight(null));
+			SignaturePanel.this.sigScreenPos = new Point2D.Double(sigx, sigy);
+			SignaturePanel.this.sigPagePos = SignaturePanel.this.currentXform.transform(SignaturePanel.this.sigScreenPos, SignaturePanel.this.sigPagePos);
+			repaint();
+		}
+
+		/** Handles a mousePressed event */
+		@Override
+		public void mousePressed(MouseEvent evt) {
+			updateSigPos(evt.getX(), evt.getY());
+		}
+
+		/**
+		 * Handles a mouseDragged event.
+		 */
+		@Override
+		public void mouseDragged(MouseEvent evt) {
+			updateSigPos(evt.getX(), evt.getY());
+		}
+	};
+
+	/**
+	 * Clamp x to be within [min-max]
+	 * @param x int to clamp
+	 * @param min minimum value
+	 * @param max maximum value
+	 * @return clamped x
+	 */
+	static int clamp(int x, int min, int max)
+	{
+		if (x < min)
+			x = min;
+		else if (x > max)
+			x = max;
+		return x;
+	}
+}
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 b595d9e1..1837cdc7 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
@@ -19,8 +19,6 @@ package at.asit.pdfover.gui.workflow.states;
 import java.io.IOException;
 
 import org.eclipse.swt.SWT;
-import org.icepdf.core.exceptions.PDFException;
-import org.icepdf.core.exceptions.PDFSecurityException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -29,6 +27,10 @@ import at.asit.pdfover.gui.MainWindowBehavior;
 import at.asit.pdfover.gui.composites.PositioningComposite;
 import at.asit.pdfover.gui.workflow.StateMachine;
 import at.asit.pdfover.gui.workflow.Status;
+import at.asit.pdfover.signator.Emblem;
+import at.asit.pdfover.signator.FileNameEmblem;
+import at.asit.pdfover.signator.SignatureException;
+import at.asit.pdfover.signator.SignatureParameter;
 
 /**
  * Decides where to position the signature block
@@ -50,7 +52,7 @@ public class PositioningState extends State {
 
 	private PositioningComposite positionComposite = null;
 
-	private PositioningComposite getPositioningComposite() throws PDFException, PDFSecurityException, IOException {
+	private PositioningComposite getPositioningComposite() throws IOException {
 		if (this.positionComposite == null) {
 			this.positionComposite =
 					this.stateMachine.getGUIProvider().createComposite(PositioningComposite.class, SWT.RESIZE, this);
@@ -75,14 +77,9 @@ public class PositioningState extends State {
 			PositioningComposite position = null;
 			try {
 				position = this.getPositioningComposite();
-			} catch (PDFException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			} catch (PDFSecurityException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
 			} catch (IOException e) {
 				// TODO Auto-generated catch block
+				// FIXME
 				e.printStackTrace();
 			}
 			
-- 
cgit v1.2.3