From f891dca529c9dc199114ae4f0857d28812315b11 Mon Sep 17 00:00:00 2001
From: Andreas Fitzek <andreas.fitzek@iaik.tugraz.at>
Date: Thu, 3 Apr 2014 15:38:01 +0200
Subject: Fixed Positioning to recognize Annotations

---
 .../lib/impl/signing/pdfbox/PADESPDFBOXSigner.java | 19 +++++++
 .../pdfbox/PDFAsVisualSignatureBuilder.java        |  9 ++--
 .../pdfbox/tagging/PDFBoxTaggingUtils.java         | 35 ++++++++++++
 .../at/knowcenter/wag/egov/egiz/pdf/PDFPage.java   | 31 +++++++++++
 .../knowcenter/wag/egov/egiz/pdf/PDFUtilities.java | 62 +++++++++++++---------
 5 files changed, 125 insertions(+), 31 deletions(-)
 create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/tagging/PDFBoxTaggingUtils.java

(limited to 'pdf-as-lib/src/main/java')

diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java
index 767887b3..c04dca59 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java
@@ -42,6 +42,8 @@ import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
 import org.apache.pdfbox.pdmodel.PDPage;
 import org.apache.pdfbox.pdmodel.PDPageNode;
+import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureElement;
+import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureTreeRoot;
 import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent;
 import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg;
 import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
@@ -69,6 +71,7 @@ import at.gv.egiz.pdfas.lib.impl.stamping.TableFactory;
 import at.gv.egiz.pdfas.lib.impl.stamping.ValueResolver;
 import at.gv.egiz.pdfas.lib.impl.stamping.pdfbox.PDFAsVisualSignatureProperties;
 import at.gv.egiz.pdfas.lib.impl.stamping.pdfbox.PdfBoxVisualObject;
+import at.gv.egiz.pdfas.lib.impl.stamping.pdfbox.tagging.PDFBoxTaggingUtils;
 import at.gv.egiz.pdfas.lib.impl.status.PDFObject;
 import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;
 import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
@@ -288,6 +291,22 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
 								e);
 					}
 				}
+				
+				/*if(signatureProfileSettings.isPDFA()) {
+					// Check for PDF-UA
+					PDDocumentCatalog root = doc.getDocumentCatalog();
+					PDStructureTreeRoot treeRoot = root.getStructureTreeRoot();
+					if(treeRoot != null) {
+						// Handle as PDF-UA
+						logger.info("Tree Root: {}", treeRoot.toString());
+						PDStructureElement docElement = PDFBoxTaggingUtils.getDocumentElement(treeRoot);
+						PDStructureElement sigBlock = new PDStructureElement("Table", docElement);
+						root.getCOSObject().setNeedToBeUpdate(true);
+						docElement.getCOSObject().setNeedToBeUpdate(true);
+						treeRoot.getCOSObject().setNeedToBeUpdate(true);
+						sigBlock.setTitle("Signature Table");
+					}
+				}*/
 
 				options.setPreferedSignatureSize(0x1000);
 				options.setPage(positioningInstruction.getPage());
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java
index 0b183c08..e24ff939 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java
@@ -41,14 +41,13 @@ import org.slf4j.LoggerFactory;
 
 import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
 import at.gv.egiz.pdfas.common.settings.ISettings;
-import at.gv.egiz.pdfas.lib.test.mains.TestPDFBoxTable;
 import at.knowcenter.wag.egov.egiz.table.Entry;
 import at.knowcenter.wag.egov.egiz.table.Style;
 
 public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder {
 
 	private static final Logger logger = LoggerFactory
-			.getLogger(TestPDFBoxTable.class);
+			.getLogger(PDFAsVisualSignatureBuilder.class);
 
 	private void drawTable(PDPage page, PDPageContentStream contentStream,
 			float x, float y, PDFBoxTable abstractTable, PDDocument doc,
@@ -157,9 +156,8 @@ public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder {
 
 					String text = (String) cell.getValue();
 					float ttexty = texty - padding - fontSize;
-					// COSName name = COSName.getPDFName("ANDI_TAG!");
-					// contentStream.beginMarkedContentSequence(COSName.ALT,
-					// name);
+					//COSName name = COSName.getPDFName("ANDI_TAG!");
+					//contentStream.beginMarkedContentSequence(COSName.ALT, name);
 					String fontName = textFont.equals(PDType1Font.COURIER) ? "COURIER" : "HELVETICA";
 					
 					contentStream.beginText();
@@ -254,7 +252,6 @@ public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder {
 
 	private PDFAsVisualSignatureProperties properties;
 	private ISettings settings;
-//	private List<PDFont> addedFonts = new ArrayList<PDFont>();
 	private PDResources innerFormResources;
 	private Map<String, ImageObject> images = new HashMap<String, ImageObject>();
 
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/tagging/PDFBoxTaggingUtils.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/tagging/PDFBoxTaggingUtils.java
new file mode 100644
index 00000000..3501e354
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/tagging/PDFBoxTaggingUtils.java
@@ -0,0 +1,35 @@
+package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox.tagging;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDMarkedContentReference;
+import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureElement;
+import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureNode;
+import org.apache.pdfbox.pdmodel.documentinterchange.markedcontent.PDMarkedContent;
+
+public class PDFBoxTaggingUtils {
+
+	public static String DOCUMENT = "Document";
+	
+	public static void beginMarkedContent(PDMarkedContentReference reference) {
+		PDMarkedContentReference ref;
+		PDMarkedContent mc;
+	}
+	
+	public static PDStructureElement getDocumentElement(PDStructureNode structElem) {
+		List<Object> kids = structElem.getKids();
+		Iterator<Object> kidsit = kids.iterator();
+		while (kidsit.hasNext()) {
+			Object kid = kidsit.next();
+			if (kid instanceof PDStructureElement) {
+				PDStructureElement elem = (PDStructureElement) kid;
+				if(elem.getStructureType().equals(DOCUMENT)) {
+					return elem;
+				}
+			} 
+		}
+		return null;
+	}
+	
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java
index 540179b8..e482d50c 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java
@@ -64,6 +64,7 @@ import org.apache.pdfbox.pdmodel.common.PDRectangle;
 import org.apache.pdfbox.pdmodel.common.PDStream;
 import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObject;
 import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectForm;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
 import org.apache.pdfbox.util.Matrix;
 import org.apache.pdfbox.util.PDFOperator;
 import org.apache.pdfbox.util.PDFTextStripper;
@@ -534,4 +535,34 @@ public class PDFPage extends PDFTextStripper {
 		return min;
 	}
 
+	public void processAnnotation(PDAnnotation anno) {
+		float current_y = anno.getRectangle().getLowerLeftY();
+		
+		int pageRotation = this.getCurrentPage().findRotation();
+		// logger_.debug("PageRotation = " + pageRotation);
+		if (pageRotation == 0) {
+			float page_height = this.getCurrentPage().findMediaBox().getHeight();
+			current_y = page_height - anno.getRectangle().getLowerLeftY();
+		}
+		if (pageRotation == 90) {
+			current_y = anno.getRectangle().getLowerLeftX();
+		}
+		if (pageRotation == 180) {
+			current_y = anno.getRectangle().getUpperRightY();
+		}
+		if (pageRotation == 270) {
+			float page_height = this.getCurrentPage().findMediaBox().getHeight();
+			current_y = page_height - anno.getRectangle().getUpperRightX();
+		}
+
+		if (current_y > this.effectivePageHeight) {
+			return;
+		}
+
+		// store ypos of the char if it is not empty
+		if (current_y > this.max_character_ypos) {
+			this.max_character_ypos = current_y;
+		}
+	}
+	
 }
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java
index c68f6229..3f5e67fc 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java
@@ -49,47 +49,59 @@
 package at.knowcenter.wag.egov.egiz.pdf;
 
 import java.io.IOException;
+import java.util.Iterator;
 import java.util.List;
 
 import org.apache.pdfbox.cos.COSStream;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.PDPage;
 import org.apache.pdfbox.pdmodel.PDResources;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
 
 import at.gv.egiz.pdfas.common.exceptions.PDFIOException;
 
-
 /**
  * Contains useful helpers for accessing PDF documents.
  *
  * @author wprinz
  * @author mruhmer
  */
-public abstract class PDFUtilities
-{
-    public static float calculatePageLength(PDDocument document, int page, float effectivePageHeight, /*int pagerotation,*/ boolean legacy32) throws PDFIOException {
-	    //int last_page_id = document.getNumberOfPages();
-	    List<?> allPages = document.getDocumentCatalog().getAllPages();
-	    PDPage pdpage = (PDPage) allPages.get(page);
-	    //pdpage.setRotation(pagerotation);
-	    return calculatePageLength(pdpage, effectivePageHeight, legacy32);
+public abstract class PDFUtilities {
+	public static float calculatePageLength(PDDocument document, int page,
+			float effectivePageHeight, /* int pagerotation, */boolean legacy32)
+			throws PDFIOException {
+		// int last_page_id = document.getNumberOfPages();
+		List<?> allPages = document.getDocumentCatalog().getAllPages();
+		PDPage pdpage = (PDPage) allPages.get(page);
+		// pdpage.setRotation(pagerotation);
+		return calculatePageLength(pdpage, effectivePageHeight, legacy32);
 	}
 
-    public static float calculatePageLength(PDPage page, float effectivePageHeight, boolean legacy32) throws PDFIOException
-    {
-        try{
-            PDFPage my_page = new PDFPage(effectivePageHeight, legacy32);
-            PDResources resources = page.findResources();
-            COSStream stream = page.getContents().getStream();
-            //List<PDThreadBead> articles = page.getThreadBeads();
-            //my_page.processMyPage(page);
-            my_page.processStream(page, resources, stream);
-            return my_page.getMaxPageLength();
-        }
-        catch (IOException e)
-        {
-            throw new PDFIOException("error.pdf.stamp.11", e);
-        }
-    }
+	public static float calculatePageLength(PDPage page,
+			float effectivePageHeight, boolean legacy32) throws PDFIOException {
+		try {
+			PDFPage my_page = new PDFPage(effectivePageHeight, legacy32);
+			PDResources resources = page.findResources();
+			COSStream stream = page.getContents().getStream();
+			// List<PDThreadBead> articles = page.getThreadBeads();
+			// my_page.processMyPage(page);
+			my_page.processStream(page, resources, stream);
+
+			if (!legacy32) {
+				Iterator<PDAnnotation> annotationsIt = page.getAnnotations()
+						.iterator();
+
+				while (annotationsIt.hasNext()) {
+					PDAnnotation annotation = annotationsIt.next();
+					if(!annotation.isInvisible()) {
+						my_page.processAnnotation(annotation);
+					}
+				}
+			}
+			return my_page.getMaxPageLength();
+		} catch (IOException e) {
+			throw new PDFIOException("error.pdf.stamp.11", e);
+		}
+	}
 
 }
-- 
cgit v1.2.3