aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Maierhofer <cmaierhofer@iaik.tugraz.at>2016-06-13 13:17:30 +0200
committerAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2016-08-17 16:46:09 +0200
commit06705460473fe1d911d29f264b9ac505d5111fbf (patch)
treecda49ac87432643f1a9a0a4b03df4e7c4de02017
parent4a0feb2e69b86cd4a7c574de49907af2620f5e23 (diff)
downloadpdf-as-4-06705460473fe1d911d29f264b9ac505d5111fbf.tar.gz
pdf-as-4-06705460473fe1d911d29f264b9ac505d5111fbf.tar.bz2
pdf-as-4-06705460473fe1d911d29f264b9ac505d5111fbf.zip
Modified sig-block positioning to image-based
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java8
-rw-r--r--pdf-as-pdfbox-2/build.gradle3
-rw-r--r--pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/PDFBOXObject.java14
-rw-r--r--pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/Positioning.java18
-rw-r--r--pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/PositioningPageDrawer.java68
-rw-r--r--pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/PositioningRenderer.java22
-rw-r--r--pdf-as-pdfbox-2/src/main/java/at/knowcenter/wag/egov/egiz/pdfbox2/pdf/PDFUtilities.java181
7 files changed, 258 insertions, 56 deletions
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java
index d47b05fa..cd0a4699 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java
@@ -26,6 +26,8 @@ package at.gv.egiz.pdfas.lib.api;
import iaik.security.ec.provider.ECCelerate;
import iaik.security.provider.IAIK;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
@@ -175,6 +177,7 @@ public class PdfAsFactory implements IConfigurationConstants {
synchronized (init_mutex) {
if (!initialized) {
initialized = true;
+ registerGraphicsEnvironment();
registerSecurityProvider(configuration);
teeInformation("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
teeInformation("+ PDF-AS: " + getVersion());
@@ -188,6 +191,11 @@ public class PdfAsFactory implements IConfigurationConstants {
}
}
}
+
+ private static void registerGraphicsEnvironment(){
+ BufferedImage bim = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D graphics = bim.createGraphics();
+ }
/**
* Create a new instance of PDF-AS
diff --git a/pdf-as-pdfbox-2/build.gradle b/pdf-as-pdfbox-2/build.gradle
index 2a6248fa..4fe4b427 100644
--- a/pdf-as-pdfbox-2/build.gradle
+++ b/pdf-as-pdfbox-2/build.gradle
@@ -23,7 +23,8 @@ dependencies {
compile project (':pdf-as-lib')
compile group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion
compile 'org.slf4j:jcl-over-slf4j:1.7.18'
- compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '2.0.1'
+ compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '2.0.2'
+ compile group: 'org.apache.pdfbox', name: 'pdfbox-tools', version: '2.0.2'
compile group: 'commons-io', name: 'commons-io', version: '2.4'
compile group: 'ognl', name: 'ognl', version: '3.0.6'
testCompile group: 'junit', name: 'junit', version: '4.+'
diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/PDFBOXObject.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/PDFBOXObject.java
index 0eee4cd3..e380e483 100644
--- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/PDFBOXObject.java
+++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/PDFBOXObject.java
@@ -9,6 +9,7 @@ import javax.activation.DataSource;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.font.PDFont;
+import at.gv.egiz.pdfas.lib.impl.stamping.pdfbox2.PDFAsFontCache;
import at.gv.egiz.pdfas.lib.impl.status.OperationStatus;
import at.gv.egiz.pdfas.lib.impl.status.PDFObject;
@@ -18,6 +19,16 @@ public class PDFBOXObject extends PDFObject {
private Map<String, PDFont> fontCache = new HashMap<String, PDFont>();
+ private PDFAsFontCache sigBlockFontCache = new PDFAsFontCache();
+
+ public PDFAsFontCache getSigBlockFontCache() {
+ return sigBlockFontCache;
+ }
+
+ public void setSigBlockFontCache(PDFAsFontCache sigBlockFontCache) {
+ this.sigBlockFontCache = sigBlockFontCache;
+ }
+
public PDFBOXObject(OperationStatus operationStatus) {
super(operationStatus);
}
@@ -64,7 +75,4 @@ public class PDFBOXObject extends PDFObject {
return String.valueOf(getDocument().getDocument().getVersion());
}
- public Map<String, PDFont> getFontCache() {
- return fontCache;
- }
}
diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/Positioning.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/Positioning.java
index 429fe518..0966ba11 100644
--- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/Positioning.java
+++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/Positioning.java
@@ -25,6 +25,7 @@ package at.gv.egiz.pdfas.lib.impl.pdfbox2.positioning;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
+import java.io.IOException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
@@ -32,6 +33,7 @@ import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import at.gv.egiz.pdfas.common.exceptions.PDFIOException;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
import at.gv.egiz.pdfas.lib.impl.pdfbox2.utils.PdfBoxUtils;
import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject;
@@ -263,11 +265,19 @@ public class Positioning {
// Now we have to getfreespace in page and reguard footerline
float footer_line = pos.getFooterLine();
- float pre_page_length = PDFUtilities.calculatePageLength(pdfDataSource,
- page - 1, page_height - footer_line, /* page_rotation, */
- legacy32, legacy40);
+// float pre_page_length = PDFUtilities.calculatePageLength(pdfDataSource,
+// page - 1, page_height - footer_line, /* page_rotation, */
+// legacy32, legacy40);
- if (pre_page_length == Float.NEGATIVE_INFINITY) {
+ float pre_page_length = Float.NEGATIVE_INFINITY;
+ try {
+ pre_page_length = PDFUtilities.getMaxYPosition(pdfDataSource, page-1, pdf_table, SIGNATURE_MARGIN_VERTICAL, footer_line);
+ //pre_page_length = PDFUtilities.getFreeTablePosition(pdfDataSource, page-1, pdf_table,SIGNATURE_MARGIN_VERTICAL);
+ } catch (IOException e) {
+ logger.warn("Could not determine page length, using -INFINITY");
+ }
+
+ if (pre_page_length == Float.NEGATIVE_INFINITY){
// we do have an empty page or nothing in area above footerline
pre_page_length = page_height;
// no text --> SIGNATURE_BORDER
diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/PositioningPageDrawer.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/PositioningPageDrawer.java
new file mode 100644
index 00000000..72c333b7
--- /dev/null
+++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/PositioningPageDrawer.java
@@ -0,0 +1,68 @@
+package at.gv.egiz.pdfas.lib.impl.pdfbox2.positioning;
+
+import java.awt.Color;
+import java.awt.Paint;
+import java.io.IOException;
+
+import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
+import org.apache.pdfbox.rendering.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawerParameters;
+
+public class PositioningPageDrawer extends PageDrawer{
+
+ public PositioningPageDrawer(PageDrawerParameters parameters)
+ throws IOException {
+ super(parameters);
+ // TODO Auto-generated constructor stub
+ }
+
+ private static final Color POSCOLOR = new Color(234, 14, 184, 211);
+
+ @Override
+ protected Paint getPaint(PDColor color){
+ return POSCOLOR;
+ }
+
+// @Override
+// protected void showGlyph(Matrix textRenderingMatrix, PDFont font, int code, String unicode,Vector displacement) throws IOException{
+// // bbox in EM -> user units
+// Shape bbox = new Rectangle2D.Float(0, 0, font.getWidth(code) / 1000, 1);
+// AffineTransform at = textRenderingMatrix.createAffineTransform();
+// bbox = at.createTransformedShape(bbox);
+//
+// // save
+// Graphics2D graphics = getGraphics();
+//
+// // draw
+// graphics.setClip(graphics.getDeviceConfiguration().getBounds());
+// graphics.setColor(POSCOLOR);
+// graphics.setStroke(new BasicStroke(.5f));
+// graphics.draw(bbox);
+//
+// // restore
+// }
+//
+// @Override
+// public void fillPath(int windingRule) throws IOException
+// {
+// // bbox in user units
+// Shape bbox = getLinePath().getBounds2D();
+//
+// // draw path (note that getLinePath() is now reset)
+// //super.fillPath(windingRule);
+//
+// // save
+// Graphics2D graphics = getGraphics();
+//
+//
+// // draw
+// graphics.setClip(graphics.getDeviceConfiguration().getBounds());
+// graphics.setColor(POSCOLOR);
+// graphics.setStroke(new BasicStroke(.5f));
+// graphics.draw(bbox);
+//
+// }
+
+
+
+}
diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/PositioningRenderer.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/PositioningRenderer.java
new file mode 100644
index 00000000..64e8fd17
--- /dev/null
+++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/PositioningRenderer.java
@@ -0,0 +1,22 @@
+package at.gv.egiz.pdfas.lib.impl.pdfbox2.positioning;
+
+import java.io.IOException;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.rendering.PDFRenderer;
+import org.apache.pdfbox.rendering.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawerParameters;
+
+public class PositioningRenderer extends PDFRenderer{
+
+ public PositioningRenderer(PDDocument document) {
+ super(document);
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ protected PageDrawer createPageDrawer(PageDrawerParameters params) throws IOException{
+ return new PositioningPageDrawer(params);
+ }
+
+}
diff --git a/pdf-as-pdfbox-2/src/main/java/at/knowcenter/wag/egov/egiz/pdfbox2/pdf/PDFUtilities.java b/pdf-as-pdfbox-2/src/main/java/at/knowcenter/wag/egov/egiz/pdfbox2/pdf/PDFUtilities.java
index c1578120..79e75b99 100644
--- a/pdf-as-pdfbox-2/src/main/java/at/knowcenter/wag/egov/egiz/pdfbox2/pdf/PDFUtilities.java
+++ b/pdf-as-pdfbox-2/src/main/java/at/knowcenter/wag/egov/egiz/pdfbox2/pdf/PDFUtilities.java
@@ -48,65 +48,150 @@
*/
package at.knowcenter.wag.egov.egiz.pdfbox2.pdf;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
+import java.util.HashMap;
-import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.pdmodel.PDDocument;
-import org.apache.pdfbox.pdmodel.PDPage;
-import org.apache.pdfbox.pdmodel.PDPageTree;
-import org.apache.pdfbox.pdmodel.PDResources;
-import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+import org.apache.pdfbox.rendering.PDFRenderer;
+import org.apache.pdfbox.tools.imageio.ImageIOUtil;
-import at.gv.egiz.pdfas.common.exceptions.PDFIOException;
+import at.gv.egiz.pdfas.lib.impl.pdfbox2.positioning.PositioningRenderer;
+import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject;
-/**
- * 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, boolean legacy40)
- throws PDFIOException {
- // int last_page_id = document.getNumberOfPages();
- PDPageTree allPages = document.getDocumentCatalog().getPages();
- PDPage pdpage = allPages.get(page);
- // pdpage.setRotation(pagerotation);
- return calculatePageLength(pdpage, effectivePageHeight, legacy32, legacy40);
- }
- public static float calculatePageLength(PDPage page,
- float effectivePageHeight, boolean legacy32, boolean legacy40) throws PDFIOException {
- try {
- PDFPage my_page = new PDFPage(effectivePageHeight, legacy32, legacy40);
- //PDResources resources = page.getResources();
- if (page.getContents() != null) {
- //COSStream stream = page.getContents();
- // List<PDThreadBead> articles = page.getThreadBeads();
- // my_page.processMyPage(page);
- //my_page.processStream(page, resources, stream); //TODO: pdfbox2 -> right?
- my_page.processPage(page);
- }
- if (!legacy32) {
- if (page.getAnnotations() != null) {
- Iterator<PDAnnotation> annotationsIt = page
- .getAnnotations().iterator();
+ public static Color MAGIC_COLOR = new Color(152,254,52);// green-ish background
+
+ public static float getMaxYPosition(
+ PDDocument pdfDataSource, int page, IPDFVisualObject pdfTable, float signatureMarginVertical, float footer_line) throws IOException {
+ long t0 = System.currentTimeMillis();
+ PositioningRenderer renderer = new PositioningRenderer(pdfDataSource);
+ //BufferedImage bim = renderer.renderImage(page);
+ long t1 = System.currentTimeMillis();
+ int width = (int) pdfDataSource.getPage(page).getCropBox().getWidth();
+ int height = (int) pdfDataSource.getPage(page).getCropBox().getHeight();
+ BufferedImage bim = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ long t2 = System.currentTimeMillis();
+ Graphics2D graphics = bim.createGraphics();
+ long t3 = System.currentTimeMillis();
+// graphics.setPaint(MAGIC_COLOR);
+// graphics.fillRect(0, 0, width, height);
+ graphics.setBackground(MAGIC_COLOR);
+
+ renderer.renderPageToGraphics(page, graphics);
+ long t4 = System.currentTimeMillis();
+ Color bgColor = MAGIC_COLOR;
+
+ if(true){ //only used if background color should be determined automatically
+ bgColor = determineBackgroundColor(bim);
+ }
+ long t5 = System.currentTimeMillis();
+ int yCoord = bim.getHeight() - 1 - (int)footer_line;
- while (annotationsIt.hasNext()) {
- PDAnnotation annotation = annotationsIt.next();
- if (!annotation.isInvisible()) {
- my_page.processAnnotation(annotation);
- }
- }
+ for(int row = yCoord; row >= 0; row--){
+ for(int col = 0; col < bim.getWidth(); col++){
+ int val = bim.getRGB(col, row);
+ if(val != bgColor.getRGB()){
+ yCoord = row;
+ row=-1;
+ break;
}
}
- return my_page.getMaxPageLength();
- } catch (IOException e) {
- throw new PDFIOException("error.pdf.stamp.11", e);
}
+ long t6 = System.currentTimeMillis();
+
+ System.out.println("new Renderer: "+ (t1-t0));
+ System.out.println("new BI: "+ (t2-t1));
+ System.out.println("Create Graphics: "+ (t3-t2));
+ System.out.println("Render to Graphics: "+ (t4-t3));
+ System.out.println("Determined bg color: "+ (t5-t4));
+ System.out.println("Calc y: "+ (t6-t5));
+
+// for(int i=0; i < bim.getWidth(); i++){
+// bim.setRGB(i, yCoord, 255);
+// }
+//
+ ImageIOUtil.writeImage(bim, "/home/cmaierhofer/temp/bufferer.png", 72);
+
+ return yCoord;
}
+
+// public static float getFreeTablePosition(
+// PDDocument pdfDataSource, int page, IPDFVisualObject pdfTable, float signatureMarginVertical) throws IOException {
+//
+// float table_height = pdfTable.getHeight();
+//
+// PDFRenderer renderer = new PDFRenderer(pdfDataSource);
+//
+// BufferedImage bim = renderer.renderImage(page);
+//
+// Color bgColor = determineBackgroundColor(bim);
+// float posY = bim.getHeight();
+//
+// for(int row=0; row<bim.getHeight();row++){
+// boolean backgroundOnly = true;
+// int countFreeRows = 0;
+// for(int c = row; c<bim.getHeight();c++){
+// countFreeRows++;
+// for(int col = 0; col < bim.getWidth(); col++){
+// int val = bim.getRGB(col, c);
+// if(val != bgColor){//end of bg
+// backgroundOnly = false;
+// row = c;
+// break;
+// }
+// }
+// if(!backgroundOnly){
+// break;
+// }else{
+// if(countFreeRows >= table_height+signatureMarginVertical){
+// posY = row;
+// row=bim.getHeight();
+// break;
+// }
+// }
+// }
+// }
+//
+// if(posY == -1)
+// return Float.NEGATIVE_INFINITY;
+// return posY;
+// }
+
+ public static Color determineBackgroundColor(BufferedImage bim){
+
+ int inset = 5;//px
+
+ int pixelUpLeft = bim.getRGB(inset,inset);
+ int pixelUpRight = bim.getRGB(bim.getWidth()-inset,inset);
+ int pixelDownLeft = bim.getRGB(inset, bim.getHeight()-inset);
+ int pixelDownRight = bim.getRGB(bim.getWidth()-inset, bim.getHeight()-inset);
+
+ HashMap<Integer, Integer> stats = new HashMap<Integer, Integer>();
+ stats.put(pixelUpLeft, 0);
+ stats.put(pixelUpRight, 0);
+ stats.put(pixelDownLeft, 0);
+ stats.put(pixelDownRight, 0);
+
+ stats.put(pixelUpLeft, stats.get(pixelUpLeft)+1);
+ stats.put(pixelUpRight, stats.get(pixelUpRight)+1);
+ stats.put(pixelDownLeft, stats.get(pixelDownLeft)+1);
+ stats.put(pixelDownRight, stats.get(pixelDownRight)+1);
+ int bgValue = -1;
+ int cnt =0;
+ for(int key:stats.keySet()){
+ if(stats.get(key) > cnt){
+ cnt = stats.get(key);
+ bgValue = key;
+ }
+ }
+
+ return new Color(bgValue);
+ }
+
}