aboutsummaryrefslogtreecommitdiff
path: root/pdf-as-lib/src/main/java/at/gv/egiz/pdfas
diff options
context:
space:
mode:
authorAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2014-07-01 09:36:09 +0200
committerAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2014-07-01 09:36:09 +0200
commit88486a007fa05986b09d319e62e266ce0db5b38a (patch)
tree49fe4af98fe00864682b5201cf1aeaa29b6e5b8d /pdf-as-lib/src/main/java/at/gv/egiz/pdfas
parent49f9c9de6cd242157092a5eeeb8360d423e7b873 (diff)
downloadpdf-as-4-88486a007fa05986b09d319e62e266ce0db5b38a.tar.gz
pdf-as-4-88486a007fa05986b09d319e62e266ce0db5b38a.tar.bz2
pdf-as-4-88486a007fa05986b09d319e62e266ce0db5b38a.zip
Signatureblock generation refactored
Diffstat (limited to 'pdf-as-lib/src/main/java/at/gv/egiz/pdfas')
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/TableFactory.java16
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/ImageObject.java27
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java345
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxTable.java103
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/TableDrawUtils.java527
5 files changed, 826 insertions, 192 deletions
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/TableFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/TableFactory.java
index 0ff1dd4e..838d9d5a 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/TableFactory.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/TableFactory.java
@@ -198,11 +198,25 @@ public class TableFactory implements IProfileConstants {
resolver.resolve(key, value, profile), key);
if (entry != null)
{
- entry.setColSpan(2);
+ //entry.setColSpan(2);
entry.setStyle(defaultValueStyle_);
row.add(entry);
}
}
+ if (TYPE_CAPTION.equals(type))
+ {
+ // add a single value entry
+ ValueResolver resolver = new ValueResolver(certProvider, operationStatus);
+ String value = profile.getCaption(key);
+ Entry entry = new Entry(Entry.TYPE_CAPTION,
+ resolver.resolve(key, value, profile), key);
+ if (entry != null)
+ {
+ //entry.setColSpan(2);
+ entry.setStyle(defaultCaptionStyle_);
+ row.add(entry);
+ }
+ }
if ((TYPE_VALUE + TYPE_CAPTION).equals(type) || (TYPE_CAPTION + TYPE_VALUE).equals(type))
{
// add a caption value pair
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/ImageObject.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/ImageObject.java
index db057a2b..25659468 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/ImageObject.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/ImageObject.java
@@ -4,11 +4,13 @@ import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;
public class ImageObject {
private PDXObjectImage image;
- private float size;
+ private float width;
+ private float height;
- public ImageObject(PDXObjectImage image, float size) {
+ public ImageObject(PDXObjectImage image, float width, float height) {
this.image = image;
- this.size = size;
+ this.width = width;
+ this.height = height;
}
public PDXObjectImage getImage() {
@@ -19,13 +21,20 @@ public class ImageObject {
this.image = image;
}
- public float getSize() {
- return size;
+ public float getWidth() {
+ return width;
}
- public void setSize(float size) {
- this.size = size;
+ public void setWidth(float width) {
+ this.width = width;
}
-
-
+
+ public float getHeight() {
+ return height;
+ }
+
+ public void setHeight(float height) {
+ this.height = height;
+ }
+
}
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 cd3fd716..f364221b 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
@@ -51,9 +51,42 @@ public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder {
private static final Logger logger = LoggerFactory
.getLogger(PDFAsVisualSignatureBuilder.class);
+ private void drawDebugLine(PDPageContentStream contentStream, float x,
+ float y, float width, float height) {
+ try {
+ contentStream.setStrokingColor(Color.RED);
+ contentStream.drawLine(x, y, x+width, y);
+ contentStream.setStrokingColor(Color.BLUE);
+ contentStream.drawLine(x, y, x, y-height);
+ contentStream.setStrokingColor(Color.GREEN);
+ contentStream.drawLine(x+width, y, x+width, y-height);
+ contentStream.setStrokingColor(Color.ORANGE);
+ contentStream.drawLine(x, y-height, x+width, y-height);
+
+ contentStream.setStrokingColor(Color.BLACK);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void drawDebugPadding(PDPageContentStream contentStream, float x,
+ float y, float padding, float width, float height) {
+ try {
+ contentStream.setStrokingColor(Color.RED);
+ contentStream.drawLine(x, y, x+padding, y-padding);
+ contentStream.drawLine(x+width, y, x+width-padding, y-padding);
+ contentStream.drawLine(x+width, y-height, x+width-padding, y-height+padding);
+ contentStream.drawLine(x, y-height, x+padding, y-height+padding);
+ contentStream.setStrokingColor(Color.BLACK);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
private void drawTable(PDPage page, PDPageContentStream contentStream,
- float x, float y, float width, float height, PDFBoxTable abstractTable, PDDocument doc,
- boolean subtable) throws IOException, PdfAsException {
+ float x, float y, float width, float height,
+ PDFBoxTable abstractTable, PDDocument doc, boolean subtable)
+ throws IOException, PdfAsException {
final int rows = abstractTable.getRowCount();
final int cols = abstractTable.getColCount();
@@ -114,88 +147,66 @@ public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder {
contentStream.drawLine(x, nexty, x + width, nexty);
lasty = nexty;
if (i < abstractTable.getRowHeights().length) {
- nexty -= abstractTable.getRowHeights()[i] + padding * 2;
+ //nexty -= abstractTable.getRowHeights()[i] + padding * 2;
+ nexty -= abstractTable.getRowHeights()[i];
}
-
- if (subtable && i + 1 == abstractTable.getRowHeights().length) {
- nexty -= padding;
- }
-
+
+ //if (subtable && i + 1 == abstractTable.getRowHeights().length) {
+ // nexty -= padding;
+ //}
+
float nextx = x;
float ypos = y;
float yheight = y + abstractTable.getHeight();
if (subtable) {
- ypos -= padding;
+ //ypos -= padding;
yheight = y + abstractTable.getHeight();
}
-
+
for (int j = 0; j < row.size(); j++) {
Entry cell = (Entry) row.get(j);
-
+
if (subtable && j == cols) {
continue;
}
logger.debug("COL LINE: {} {} {} {}", nextx, ypos, nextx,
yheight);
contentStream.drawLine(nextx, lasty, nextx, nexty);
- for(int k = 0; k < cell.getColSpan(); k++) {
+ for (int k = 0; k < cell.getColSpan(); k++) {
if (k + j < colsSizes.length) {
- nextx += (colsSizes != null) ? colsSizes[k + j] : colWidth;
+ nextx += (colsSizes != null) ? colsSizes[k + j]
+ : colWidth;
}
}
}
- if(!subtable) {
+ if (!subtable) {
contentStream.drawLine(nextx, lasty, nextx, nexty);
}
}
-
+
contentStream.drawLine(x, nexty, x + tableWidth, nexty);
- /*
- // draw the rows
- float nexty = y + tableHeight;
- for (int i = 0; i <= rows; i++) {
- logger.debug("ROW LINE: {} {} {} {}", x, nexty, x + tableWidth,
- nexty);
- contentStream.drawLine(x, nexty, x + tableWidth, nexty);
- if (i < abstractTable.getRowHeights().length) {
- nexty -= abstractTable.getRowHeights()[i] + padding * 2;
- }
- if (subtable && i + 1 == abstractTable.getRowHeights().length) {
- nexty -= padding;
- }
- }
-
- // draw the columns
- float nextx = x;
- float ypos = y;
- float yheight = y + abstractTable.getHeight();
- if (subtable) {
- ypos -= padding;
- yheight = y + abstractTable.getHeight();
- }
- for (int i = 0; i <= cols; i++) {
- if (subtable && i == cols) {
- continue;
- }
- logger.debug("COL LINE: {} {} {} {}", nextx, ypos, nextx,
- yheight);
- contentStream.drawLine(nextx, ypos, nextx, yheight);
- if (i < colsSizes.length) {
- nextx += (colsSizes != null) ? colsSizes[i] : colWidth;
- }
- }*/
}
- float textx = x + padding;
+ float textx = x;
float texty = y + tableHeight;
for (int i = 0; i < abstractTable.getRowCount(); i++) {
ArrayList<Entry> row = abstractTable.getRow(i);
for (int j = 0; j < row.size(); j++) {
Entry cell = (Entry) row.get(j);
-
- Style inherit_style = Style.doInherit(abstractTable.style, cell.getStyle());
- cell.setStyle(inherit_style);
+
+ Style inherit_style = Style.doInherit(cell.getStyle(), abstractTable.style);
+ cell.setStyle(inherit_style);
+
+ //if(subtable) {
+ drawDebugPadding(contentStream, textx, texty, padding,
+ ((colsSizes != null) ? colsSizes[j] : colWidth),
+ abstractTable.getRowHeights()[i]);
+ //}
+ //if(true) {
+ // textx += (colsSizes != null) ? colsSizes[j] : colWidth;
+ // continue;
+ //}
if (cell.getType() == Entry.TYPE_CAPTION
|| cell.getType() == Entry.TYPE_VALUE) {
@@ -208,94 +219,98 @@ public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder {
fontSize = abstractTable.getValueFont().getFontSize();
}
+
String text = (String) cell.getValue();
- float ttexty = texty - fontSize - padding * 0.5f;
+
// COSName name = COSName.getPDFName("ANDI_TAG!");
// contentStream.beginMarkedContentSequence(COSName.ALT,
// name);
String fontName = textFont.equals(PDType1Font.COURIER) ? "COURIER"
: "HELVETICA";
- contentStream.beginText();
-
- if (innerFormResources.getFonts().containsValue(textFont)) {
- String fontID = getFontID(textFont);
- logger.debug("Using Font: " + fontID);
- contentStream.appendRawCommands("/" + fontID + " "
- + fontSize + " Tf\n");
- } else {
- contentStream.setFont(textFont, fontSize);
- }
-
- // TODO: use halign and valgin
+ float fheight = textFont.getFontDescriptor().getCapHeight() / 1000 * fontSize;
- float fheight = textFont.getFontDescriptor().getFontBoundingBox()
- .getHeight()
- / 1000 * fontSize;
-
String[] tlines = text.split("\n");
- float textHeight = fheight * tlines.length;
-
+ float textHeight = fontSize * tlines.length;
+
Style cellStyle = cell.getStyle();
String valign = null;
String halign = null;
-
- if (cell.getType() == Entry.TYPE_CAPTION && cellStyle != null) {
+
+ if (cell.getType() == Entry.TYPE_CAPTION
+ && cellStyle != null) {
valign = cellStyle.getVAlign();
halign = cellStyle.getHAlign();
- } else if (cell.getType() == Entry.TYPE_VALUE && cellStyle != null) {
+ } else if (cell.getType() == Entry.TYPE_VALUE
+ && cellStyle != null) {
valign = cellStyle.getValueVAlign();
halign = cellStyle.getValueHAlign();
}
- float ty = ttexty;
- if(Style.BOTTOM.equals(valign)) {
- float bottom_offset = abstractTable.getRowHeights()[i] - textHeight;
+ float ty = texty - padding;
+ float tx = textx+padding;
+ if (Style.BOTTOM.equals(valign)) {
+ float bottom_offset = abstractTable.getRowHeights()[i]
+ - textHeight;
ty -= bottom_offset;
- } else if(Style.MIDDLE.equals(valign)) {
- float bottom_offset = abstractTable.getRowHeights()[i] - textHeight;
+ } else if (Style.MIDDLE.equals(valign)) {
+ float bottom_offset = abstractTable.getRowHeights()[i]
+ - textHeight;
bottom_offset = bottom_offset / 2.0f;
ty -= bottom_offset;
}
-
- float columnWidth = (colsSizes != null) ? colsSizes[j] : colWidth;
+
+ float columnWidth = (colsSizes != null) ? colsSizes[j]
+ : colWidth;
float maxWidth = 0;
for (int k = 0; k < tlines.length; k++) {
float lineWidth;
if (textFont instanceof PDType1Font) {
- lineWidth = textFont.getStringWidth(tlines[k]) / 1000.0f * fontSize;
- //fwidth = textFont.getFontDescriptor().getFontBoundingBox().getWidth()
- // / 1000.0f * fontSize;
+ lineWidth = textFont.getStringWidth(tlines[k])
+ / 1000.0f * fontSize;
} else {
- float fwidth = textFont.getStringWidth("abcdefghijklmnopqrstuvwxyz ") / 1000.0f * fontSize;
- fwidth = fwidth / (float)"abcdefghijklmnopqrstuvwxyz".length();
+ float fwidth = textFont
+ .getStringWidth("abcdefghijklmnopqrstuvwxyz ")
+ / 1000.0f * fontSize;
+ fwidth = fwidth
+ / (float) "abcdefghijklmnopqrstuvwxyz"
+ .length();
lineWidth = tlines[k].length() * fwidth;
}
-
-
-
- //float w = textFont.getStringWidth(tlines[k]) / 1000 * fontSize;
+
if (maxWidth < lineWidth) {
maxWidth = lineWidth;
}
}
- float tx = textx;
- if(Style.CENTER.equals(halign)) {
- float offset = columnWidth - maxWidth - 2 * padding;
- if(offset > 0) {
+ if (Style.CENTER.equals(halign)) {
+ float offset = columnWidth - maxWidth - 2 * padding;
+ if (offset > 0) {
offset = offset / 2.0f;
tx += offset;
}
- } else if(Style.RIGHT.equals(halign)) {
- float offset = columnWidth - maxWidth - 2 * padding;
- if(offset > 0) {
+ } else if (Style.RIGHT.equals(halign)) {
+ float offset = columnWidth - maxWidth - 2 * padding;
+ if (offset > 0) {
tx += offset;
}
}
+
+ drawDebugLine(contentStream, tx, ty, maxWidth, textHeight);
+
+ contentStream.beginText();
+
+ if (innerFormResources.getFonts().containsValue(textFont)) {
+ String fontID = getFontID(textFont);
+ logger.debug("Using Font: " + fontID);
+ contentStream.appendRawCommands("/" + fontID + " "
+ + fontSize + " Tf\n");
+ } else {
+ contentStream.setFont(textFont, fontSize);
+ }
- logger.debug("Writing: " + tx + " : " + ty + " = "
- + text + " as " + cell.getType() + " w " + fontName);
- contentStream.moveTextPositionByAmount(tx, ty);
+ logger.debug("Writing: " + tx + " : " + (ty-fheight) + " = " + text
+ + " as " + cell.getType() + " w " + fontName);
+ contentStream.moveTextPositionByAmount(tx, (ty-fheight));
if (text.contains("\n")) {
String[] lines = text.split("\n");
@@ -320,69 +335,83 @@ public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder {
}
ImageObject image = images.get(img_ref);
PDXObjectImage pdImage = image.getImage();
- // text = "Row :" + i + "COL: " + j;
- // COSName name = COSName.getPDFName("ANDI_TAG!");
- // contentStream.beginMarkedContentSequence(COSName.ALT,
- // name);
-
- // TODO: use HAlign
- float imgy = texty;
+ float imgx = textx + padding;
+ float hoffset = ((colsSizes != null) ? colsSizes[j]
+ : colWidth)
+ - image.getWidth();
+ if (cell.getStyle().getImageVAlign() != null
+ && cell.getStyle().getImageVAlign()
+ .equals(Style.CENTER)) {
+ hoffset = hoffset / 2.0f;
+ imgx += hoffset;
+ } else if (cell.getStyle().getImageHAlign() != null
+ && cell.getStyle().getImageHAlign()
+ .equals(Style.RIGHT)) {
+ imgx += hoffset;
+ }
+
+ float imgy = texty - padding;
+ float voffset = abstractTable.getRowHeights()[i]
+ - image.getHeight();
if (cell.getStyle().getImageVAlign() != null
&& cell.getStyle().getImageVAlign()
- .equals(Style.TOP)) {
- imgy = texty - padding - image.getSize();
+ .equals(Style.MIDDLE)) {
+ voffset = voffset / 2.0f;
+ imgy -= voffset;
} else if (cell.getStyle().getImageVAlign() != null
&& cell.getStyle().getImageVAlign()
.equals(Style.BOTTOM)) {
- // Should allready be at bottom ...
- imgy = texty - abstractTable.getRowHeights()[i]
- + padding;
- } else {
- // default to middle
- imgy = texty - padding
- - abstractTable.getRowHeights()[i] / 2;
- imgy = imgy - image.getSize() / 2;
- }
- logger.debug("Image: " + textx + " : " + imgy);
- contentStream.drawXObject(pdImage, textx, imgy,
- image.getSize(), image.getSize());
+ imgy -= voffset;
+ }
+
+ drawDebugLine(contentStream, imgx, imgy, image.getWidth(), image.getHeight());
+
+ logger.debug("Image: " + imgx + " : " + (imgy - image.getHeight()));
+ contentStream.drawXObject(pdImage, imgx, imgy - image.getHeight(),
+ image.getWidth(), image.getHeight());
// contentStream.endMarkedContentSequence();
} else if (cell.getType() == Entry.TYPE_TABLE) {
-
- float tableY = texty - abstractTable.getRowHeights()[i]
- - padding;
+
+ float tableY = texty - abstractTable.getRowHeights()[i];
float tableX = textx;
// texty = texty - padding;
- tableX = textx - padding;
PDFBoxTable tbl_value = (PDFBoxTable) cell.getValue();
-
- Style inherit_styletab = Style.doInherit(abstractTable.style, cell.getStyle());
+
+ Style inherit_styletab = Style.doInherit(
+ abstractTable.style, cell.getStyle());
tbl_value.table.setStyle(inherit_styletab);
-
+
logger.debug("Table: " + tableX + " : " + tableY);
- drawTable(page, contentStream, tableX, tableY,
- (colsSizes != null) ? colsSizes[j] : colWidth,
- abstractTable.getRowHeights()[i] + padding * 2,
- tbl_value, doc, true);
+ //logger.debug("Table height: " + );
+ TableDrawUtils.drawTable(page, contentStream, tableX, tableY,
+ (colsSizes != null) ? colsSizes[j] : colWidth,
+ abstractTable.getRowHeights()[i],
+ tbl_value, doc, true, innerFormResources, images, settings);
}
textx += (colsSizes != null) ? colsSizes[j] : colWidth;
}
// if (i + 1 < abstractTable.getRowHeights().length) {
logger.debug("Row {} from {} - {} - {} = {}", i, texty,
abstractTable.getRowHeights()[i], padding * 2, texty
- - (abstractTable.getRowHeights()[i] + padding * 2));
- texty -= abstractTable.getRowHeights()[i] + padding * 2;
+ - (abstractTable.getRowHeights()[i]));
+ texty -= abstractTable.getRowHeights()[i];
// texty = texty - abstractTable.getRowHeights()[i + 1] - padding
// * 2;
// texty = texty - abstractTable.getRowHeights()[i] - padding
// * 2;
// }
- textx = x + padding;
+ textx = x;
}
}
+ private void drawTable2(PDPage page, PDPageContentStream contentStream,
+ float x, float y, float width, float height,
+ PDFBoxTable abstractTable, PDDocument doc, boolean subtable) {
+
+ }
+
private PDFAsVisualSignatureProperties properties;
private PDFAsVisualSignatureDesigner designer;
private ISettings settings;
@@ -402,7 +431,7 @@ public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder {
}
public PDFAsVisualSignatureBuilder(
- PDFAsVisualSignatureProperties properties, ISettings settings,
+ PDFAsVisualSignatureProperties properties, ISettings settings,
PDFAsVisualSignatureDesigner designer) {
this.properties = properties;
this.settings = settings;
@@ -504,26 +533,46 @@ public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder {
}
float width = colsSizes[j];
+ float height = table.getRowHeights()[i] + padding * 2;
- float size = (int) Math.floor((double) width);
- size -= 2 * padding;
- logger.debug("Scaling image to: " + size);
+ float iwidth = (int) Math.floor((double) width);
+ iwidth -= 2 * padding;
+
+ float iheight = (int) Math.floor((double) height);
+ iheight -= 2 * padding;
+
+ float origWidth = (float) img.getWidth();
+ float origHeight = (float) img.getHeight();
+
+ float wfactor = iwidth / origWidth;
+ float hfactor = iheight / origHeight;
+ float scaleFactor = wfactor;
+ if(hfactor < wfactor) {
+ scaleFactor = hfactor;
+ }
+
+ iwidth = (float) Math.floor((double)(scaleFactor * origWidth));
+ iheight = (float) Math.floor((double)(scaleFactor * origHeight));
if (table.style != null) {
if (table.style.getImageScaleToFit() != null) {
- size = table.style.getImageScaleToFit()
+ iwidth = table.style.getImageScaleToFit()
.getWidth();
+ iheight = table.style.getImageScaleToFit()
+ .getHeight();
}
}
- if(img.getAlphaRaster() == null && img.getColorModel().hasAlpha()) {
+ logger.debug("Scaling image to: " + iwidth + " x " + iheight);
+
+ if (img.getAlphaRaster() == null
+ && img.getColorModel().hasAlpha()) {
img = ImageUtils.removeAlphaChannel(img);
}
PDXObjectImage pdImage = new PDJpeg(template, img);
-
- ImageObject image = new ImageObject(pdImage, size);
+ ImageObject image = new ImageObject(pdImage, iwidth, iheight);
images.put(img_ref, image);
innerFormResources.addXObject(pdImage, "Im");
}
@@ -538,7 +587,7 @@ public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder {
@Override
public void createInnerFormStream(PDDocument template) {
try {
-
+
// Hint we have to create all PDXObjectImages before creating the
// PDPageContentStream
// only PDFbox developers know why ...
@@ -549,9 +598,9 @@ public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder {
PDPageContentStream stream = new PDPageContentStream(template,
getStructure().getPage());
// stream.setFont(PDType1Font.COURIER, 5);
- drawTable(getStructure().getPage(), stream, 1, 1,
+ TableDrawUtils.drawTable(getStructure().getPage(), stream, 1, 1,
designer.getWidth(), designer.getHeight(),
- properties.getMainTable(), template, false);
+ properties.getMainTable(), template, false, innerFormResources, images, settings);
stream.close();
PDStream innterFormStream = getStructure().getPage().getContents();
getStructure().setInnterFormStream(innterFormStream);
@@ -608,7 +657,7 @@ public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder {
String innerFormComment = getStructure().getInnterFormStream()
.getInputStreamAsString();
- logger.debug("Inner Form Stream: " + innerFormComment);
+ //logger.debug("Inner Form Stream: " + innerFormComment);
// appendRawCommands(getStructure().getInnterFormStream().createOutputStream(),
// getStructure().getInnterFormStream().getInputStreamAsString());
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxTable.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxTable.java
index 01cb031d..24331652 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxTable.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxTable.java
@@ -39,6 +39,7 @@ public class PDFBoxTable {
float tableHeight;
Color bgColor;
+ boolean[] addPadding;
float[] rowHeights;
float[] colWidths;
@@ -148,6 +149,8 @@ public class PDFBoxTable {
}
}
calculateHeightsBasedOnWidths();
+
+ logger.debug("Generating Table with fixed With {} got width {}", fixSize, getWidth());
}
public PDFBoxTable(Table abstractTable, PDFBoxTable parent,
@@ -160,6 +163,7 @@ public class PDFBoxTable {
private void calculateHeightsBasedOnWidths() throws IOException {
int rows = this.table.getRows().size();
rowHeights = new float[rows];
+ addPadding = new boolean[rows];
for (int i = 0; i < rows; i++) {
rowHeights[i] = 0;
@@ -247,13 +251,28 @@ public class PDFBoxTable {
this.tableHeight = 0;
for (int i = 0; i < rowHeights.length; i++) {
- this.tableHeight += rowHeights[i] + padding * 2;
+ this.tableHeight += rowHeights[i];
}
+ // Post Process heights for inner Tables ...
+ for (int i = 0; i < rowHeights.length; i++) {
+ ArrayList<Entry> row = this.table.getRows().get(i);
+ for (int j = 0; j < row.size(); j++) {
+ Entry cell = (Entry) row.get(j);
+ if(cell.getType() == Entry.TYPE_TABLE) {
+ PDFBoxTable tbl = (PDFBoxTable)cell.getValue();
+ if(rowHeights[i] != tbl.getHeight())
+ {
+ tbl.setHeight(rowHeights[i]);
+ }
+ }
+ }
+ }
+
this.tableWidth = 0;
for (int i = 0; i < colWidths.length; i++) {
- this.tableWidth += colWidths[i] + padding * 2;
+ this.tableWidth += colWidths[i];
}
}
@@ -309,8 +328,6 @@ public class PDFBoxTable {
return pdfBoxTable.getWidth();
default:
logger.warn("Invalid Cell Entry Type: " + cell.getType());
- // return font.getFontDescriptor().getFontBoundingBox().getHeight()
- // / 1000 * fontSize;
}
return 0;
}
@@ -437,6 +454,32 @@ public class PDFBoxTable {
// return lines.toArray(new String[0]);
// }
+ private float[] getStringHeights(String[] lines, PDFont c, float fontSize) {
+ float[] heights = new float[lines.length];
+ for (int i = 0; i < lines.length; i++) {
+ float maxLineHeight = 0;
+ try {
+ byte[] linebytes = StringUtils.applyWinAnsiEncoding(lines[i]);
+ for(int j = 0; j < linebytes.length; j++) {
+ float he = c.getFontHeight(linebytes, j, 1) / 1000 * fontSize;
+ if(he > maxLineHeight) {
+ maxLineHeight = he;
+ }
+ }
+ } catch (UnsupportedEncodingException e) {
+ logger.warn("failed to determine String height", e);
+ maxLineHeight = c.getFontDescriptor().getCapHeight() / 1000 * fontSize;
+ } catch (IOException e) {
+ logger.warn("failed to determine String height", e);
+ maxLineHeight = c.getFontDescriptor().getCapHeight() / 1000 * fontSize;
+ }
+
+ heights[i] = maxLineHeight;
+ }
+
+ return heights;
+ }
+
private float getCellHeight(Entry cell, float width) throws IOException {
boolean isValue = true;
switch (cell.getType()) {
@@ -453,51 +496,35 @@ public class PDFBoxTable {
c = font.getFont(null);
fontSize = font.getFontSize();
}
- /*
- * float fwidth; if (c instanceof PDType1Font) { fwidth =
- * c.getFontDescriptor().getFontBoundingBox().getWidth() / 1000.0f *
- * fontSize * 0.9f; } else if (c instanceof PDTrueTypeFont) {
- * PDTrueTypeFont t = (PDTrueTypeFont)c; fwidth =
- * t.getAverageFontWidth() / 1000.0f * fontSize; } else { fwidth =
- * c.getStringWidth("abcdefghijklmnopqrstuvwxyz ") / 1000.0f *
- * fontSize; fwidth = fwidth /
- * (float)"abcdefghijklmnopqrstuvwxyz".length(); }
- *
- * logger.debug("Font Width: {}", fwidth); int maxcharcount = (int)
- * ((width - padding * 2) / fwidth) - 1;
- * logger.debug("Max {} chars per line!", maxcharcount);
- */
- float fheight = c.getFontDescriptor().getFontBoundingBox()
- .getHeight()
- / 1000 * fontSize * 0.9f;
String[] lines = breakString(string, (width - padding * 2.0f), c,
fontSize);
cell.setValue(concatLines(lines));
- return fheight * lines.length;// - padding;
+ float[] heights = getStringHeights(lines, c, fontSize);
+ return fontSize * heights.length + padding * 2;
case Entry.TYPE_IMAGE:
if (style != null && style.getImageScaleToFit() != null) {
- if (style.getImageScaleToFit().getHeight() < width) {
+ //if (style.getImageScaleToFit().getHeight() < width) {
return style.getImageScaleToFit().getHeight();
- }
+ //}
}
return width;
case Entry.TYPE_TABLE:
PDFBoxTable pdfBoxTable = null;
if (cell.getValue() instanceof Table) {
pdfBoxTable = new PDFBoxTable((Table) cell.getValue(), this,
- width - padding, this.settings);
+ width, this.settings);
cell.setValue(pdfBoxTable);
} else if (cell.getValue() instanceof PDFBoxTable) {
// recreate here beacuse of fixed width!
pdfBoxTable = (PDFBoxTable) cell.getValue();
- pdfBoxTable = new PDFBoxTable(pdfBoxTable.table, this, width
- - padding, this.settings);
+ pdfBoxTable = new PDFBoxTable(pdfBoxTable.table, this, width,
+ this.settings);
cell.setValue(pdfBoxTable);
} else {
throw new IOException("Failed to build PDFBox Table");
}
- return pdfBoxTable.getHeight() - padding;
+ return pdfBoxTable.getHeight();
default:
logger.warn("Invalid Cell Entry Type: " + cell.getType());
}
@@ -520,15 +547,13 @@ public class PDFBoxTable {
c = font.getFont(null);
fontSize = font.getFontSize();
}
- float fheight = c.getFontDescriptor().getFontBoundingBox()
- .getHeight()
- / 1000 * fontSize;
+
if (string.contains("\n")) {
String[] lines = string.split("\n");
- return fheight * lines.length;
+ return fontSize * lines.length + padding * 2;
} else {
- return fheight;
+ return fontSize + padding * 2;
}
case Entry.TYPE_IMAGE:
if (style != null && style.getImageScaleToFit() != null) {
@@ -568,6 +593,16 @@ public class PDFBoxTable {
public float getHeight() {
return tableHeight;
}
+
+ public void setHeight(float height) {
+ float diff = height - this.getHeight();
+ if(diff > 0) {
+ this.rowHeights[rowHeights.length - 1] += diff;
+ calcTotals();
+ } else {
+ logger.warn("Table cannot be this small!");
+ }
+ }
public float[] getRowHeights() {
return rowHeights;
@@ -578,7 +613,7 @@ public class PDFBoxTable {
}
public int getColCount() {
- return this.table.getMaxCols();//.getColsRelativeWith().length;
+ return this.table.getMaxCols();// .getColsRelativeWith().length;
}
public float[] getColsRelativeWith() {
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/TableDrawUtils.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/TableDrawUtils.java
new file mode 100644
index 00000000..26aef4cb
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/TableDrawUtils.java
@@ -0,0 +1,527 @@
+package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDResources;
+import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.pdmodel.font.PDType1Font;
+import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.exceptions.PdfAsWrappedIOException;
+import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.knowcenter.wag.egov.egiz.table.Entry;
+import at.knowcenter.wag.egov.egiz.table.Style;
+
+public class TableDrawUtils {
+
+ private static final Logger logger = LoggerFactory
+ .getLogger(TableDrawUtils.class);
+
+ public static final String TABLE_DEBUG = "debug.table";
+
+ public static void drawTable(PDPage page,
+ PDPageContentStream contentStream, float x, float y, float width,
+ float height, PDFBoxTable abstractTable, PDDocument doc,
+ boolean subtable, PDResources formResources,
+ Map<String, ImageObject> images, ISettings settings)
+ throws PdfAsException {
+
+ logger.debug("Drawing Table: X {} Y {} WIDTH {} HEIGHT {} \n{}", x, y,
+ width, height, abstractTable.getOrigTable().toString());
+
+ abstractTable.getOrigTable().setWidth(width);
+
+ drawTableBackground(page, contentStream, x, y, width, height,
+ abstractTable, settings);
+
+ drawBorder(page, contentStream, x, y, width, height, abstractTable,
+ doc, subtable, settings);
+
+ drawContent(page, contentStream, x, y, width, height, abstractTable,
+ doc, subtable, formResources, images, settings);
+ }
+
+ public static void drawContent(PDPage page,
+ PDPageContentStream contentStream, float x, float y, float width,
+ float height, PDFBoxTable abstractTable, PDDocument doc,
+ boolean subtable, PDResources formResources,
+ Map<String, ImageObject> images, ISettings settings)
+ throws PdfAsException {
+
+ float contentx = x;
+ float contenty = y + height;
+ float padding = abstractTable.getPadding();
+ float[] colsSizes = getColSizes(abstractTable);
+
+ for (int i = 0; i < abstractTable.getRowCount(); i++) {
+ ArrayList<Entry> row = abstractTable.getRow(i);
+ for (int j = 0; j < row.size(); j++) {
+ Entry cell = (Entry) row.get(j);
+
+ Style inherit_style = Style.doInherit(cell.getStyle(),
+ abstractTable.style);
+ cell.setStyle(inherit_style);
+
+ drawDebugPadding(contentStream, contentx, contenty, padding,
+ colsSizes[j], abstractTable.getRowHeights()[i], settings);
+
+ switch (cell.getType()) {
+ case Entry.TYPE_CAPTION:
+ drawCaption(page, contentStream, contentx, contenty,
+ colsSizes[j], abstractTable.getRowHeights()[i],
+ padding, abstractTable, doc, cell, formResources, settings);
+ break;
+ case Entry.TYPE_VALUE:
+ drawValue(page, contentStream, contentx, contenty,
+ colsSizes[j], abstractTable.getRowHeights()[i],
+ padding, abstractTable, doc, cell, formResources, settings);
+ break;
+ case Entry.TYPE_IMAGE:
+ drawImage(page, contentStream, contentx, contenty,
+ colsSizes[j], abstractTable.getRowHeights()[i],
+ padding, abstractTable, doc, cell, formResources,
+ images, settings);
+ break;
+ case Entry.TYPE_TABLE:
+
+ PDFBoxTable tbl_value = (PDFBoxTable) cell.getValue();
+
+ Style inherit_styletab = Style.doInherit(
+ abstractTable.style, cell.getStyle());
+ tbl_value.table.setStyle(inherit_styletab);
+
+ drawTable(page, contentStream, contentx, contenty
+ - abstractTable.getRowHeights()[i], colsSizes[j],
+ abstractTable.getRowHeights()[i], tbl_value, doc,
+ true, formResources, images, settings);
+ break;
+ default:
+ logger.warn("Unknown Cell entry type: " + cell.getType());
+ break;
+ }
+
+ // Move content pointer
+ contentx += colsSizes[j];
+ }
+
+ // Move content pointer
+ contenty -= abstractTable.getRowHeights()[i];
+ contentx = x;
+ }
+ }
+
+ private static void drawString(PDPage page,
+ PDPageContentStream contentStream, float contentx, float contenty,
+ float width, float height, float padding,
+ PDFBoxTable abstractTable, PDDocument doc, Entry cell,
+ float fontSize, float textHeight, String valign, String halign,
+ String[] tlines, PDFont textFont, PDResources formResources,
+ ISettings settings) throws PdfAsException {
+ try {
+ float ty = contenty - padding;
+ float tx = contentx + padding;
+ float innerHeight = height - (2 * padding);
+ float innerWidth = width - (2 * padding);
+ if (Style.BOTTOM.equals(valign)) {
+ float bottom_offset = innerHeight - textHeight;
+ ty -= bottom_offset;
+ } else if (Style.MIDDLE.equals(valign)) {
+ float bottom_offset = innerHeight - textHeight;
+ bottom_offset = bottom_offset / 2.0f;
+ ty -= bottom_offset;
+ }
+
+ // calculate the max with of the text content
+ float maxWidth = 0;
+ for (int k = 0; k < tlines.length; k++) {
+ float lineWidth;
+ // if (textFont instanceof PDType1Font) {
+ lineWidth = textFont.getStringWidth(tlines[k]) / 1000.0f
+ * fontSize;
+ /*
+ * } else { float fwidth = textFont
+ * .getStringWidth("abcdefghijklmnopqrstuvwxyz ") / 1000.0f *
+ * fontSize; fwidth = fwidth / (float)
+ * "abcdefghijklmnopqrstuvwxyz" .length(); lineWidth =
+ * tlines[k].length() * fwidth; }
+ */
+ if (maxWidth < lineWidth) {
+ maxWidth = lineWidth;
+ }
+ }
+
+ if (Style.CENTER.equals(halign)) {
+ float offset = innerWidth - maxWidth;
+ if (offset > 0) {
+ offset = offset / 2.0f;
+ tx += offset;
+ }
+ } else if (Style.RIGHT.equals(halign)) {
+ float offset = innerWidth - maxWidth;
+ if (offset > 0) {
+ tx += offset;
+ }
+ }
+
+ logger.debug("Text tx {} ty {} maxWidth {} textHeight {}", tx, ty,
+ maxWidth, textHeight);
+
+ drawDebugLine(contentStream, tx, ty, maxWidth, textHeight, settings);
+
+ contentStream.beginText();
+
+ if (formResources.getFonts().containsValue(textFont)) {
+ String fontID = getFontID(textFont, formResources);
+ logger.debug("Using Font: " + fontID);
+ contentStream.appendRawCommands("/" + fontID + " " + fontSize
+ + " Tf\n");
+ } else {
+ contentStream.setFont(textFont, fontSize);
+ }
+
+ logger.debug("Writing: " + tx + " : " + (ty - fontSize) + " as "
+ + cell.getType());
+ contentStream.moveTextPositionByAmount(tx, (ty - fontSize));
+
+ contentStream.appendRawCommands(fontSize + " TL\n");
+ for (int k = 0; k < tlines.length; k++) {
+ contentStream.drawString(tlines[k]);
+ if (k < tlines.length - 1) {
+ contentStream.appendRawCommands("T*\n");
+ }
+ }
+
+ contentStream.endText();
+
+ } catch (IOException e) {
+ logger.error("IO Exception", e);
+ throw new PdfAsException("Error", e);
+ }
+ }
+
+ public static void drawCaption(PDPage page,
+ PDPageContentStream contentStream, float contentx, float contenty,
+ float width, float height, float padding,
+ PDFBoxTable abstractTable, PDDocument doc, Entry cell,
+ PDResources formResources, ISettings settings)
+ throws PdfAsException {
+
+ logger.debug("Drawing Caption @ X: {} Y: {}", contentx, contenty);
+
+ try {
+ float fontSize = PDFBoxFont.defaultFontSize;
+ PDFont textFont = PDFBoxFont.defaultFont;
+
+ textFont = abstractTable.getFont().getFont(doc);
+ fontSize = abstractTable.getFont().getFontSize();
+
+ // get the cell Text
+ String text = (String) cell.getValue();
+ String[] tlines = text.split("\n");
+ float textHeight = fontSize * tlines.length;
+
+ Style cellStyle = cell.getStyle();
+ String valign = cellStyle.getVAlign();
+ String halign = cellStyle.getHAlign();
+
+ drawString(page, contentStream, contentx, contenty, width, height,
+ padding, abstractTable, doc, cell, fontSize, textHeight,
+ valign, halign, tlines, textFont, formResources, settings);
+ } catch (IOException e) {
+ logger.error("IO Exception", e);
+ throw new PdfAsException("Error", e);
+ }
+ }
+
+ public static void drawValue(PDPage page,
+ PDPageContentStream contentStream, float contentx, float contenty,
+ float width, float height, float padding,
+ PDFBoxTable abstractTable, PDDocument doc, Entry cell,
+ PDResources formResources, ISettings settings)
+ throws PdfAsException {
+
+ logger.debug("Drawing Value @ X: {} Y: {}", contentx, contenty);
+
+ try {
+ float fontSize = PDFBoxFont.defaultFontSize;
+ PDFont textFont = PDFBoxFont.defaultFont;
+
+ textFont = abstractTable.getValueFont().getFont(doc);
+ fontSize = abstractTable.getValueFont().getFontSize();
+
+ // get the cell Text
+ String text = (String) cell.getValue();
+ String[] tlines = text.split("\n");
+ float textHeight = fontSize * tlines.length;
+
+ Style cellStyle = cell.getStyle();
+ String valign = cellStyle.getValueVAlign();
+ String halign = cellStyle.getValueHAlign();
+
+ drawString(page, contentStream, contentx, contenty, width, height,
+ padding, abstractTable, doc, cell, fontSize, textHeight,
+ valign, halign, tlines, textFont, formResources, settings);
+ } catch (IOException e) {
+ logger.error("IO Exception", e);
+ throw new PdfAsException("Error", e);
+ }
+ }
+
+ public static void drawImage(PDPage page,
+ PDPageContentStream contentStream, float contentx, float contenty,
+ float width, float height, float padding,
+ PDFBoxTable abstractTable, PDDocument doc, Entry cell,
+ PDResources formResources, Map<String, ImageObject> images,
+ ISettings settings) throws PdfAsException {
+ try {
+ float innerHeight = height;
+ float innerWidth = width;
+
+ String img_ref = (String) cell.getValue();
+ if (!images.containsKey(img_ref)) {
+ logger.error("Image not prepared! : " + img_ref);
+ throw new PdfAsException("Image not prepared! : " + img_ref);
+ }
+ ImageObject image = images.get(img_ref);
+ PDXObjectImage pdImage = image.getImage();
+
+ float imgx = contentx;
+ float hoffset = innerWidth - image.getWidth();
+ if (cell.getStyle().getImageHAlign() != null
+ && cell.getStyle().getImageHAlign().equals(Style.LEFT)) {
+ hoffset = hoffset / 2.0f;
+ imgx += hoffset;
+ } else if (cell.getStyle().getImageHAlign() != null
+ && cell.getStyle().getImageHAlign().equals(Style.RIGHT)) {
+ imgx += hoffset;
+ } else {
+ hoffset = hoffset / 2.0f;
+ imgx += hoffset;
+ }
+
+ float imgy = contenty;
+ float voffset = innerHeight - image.getHeight();
+ if (cell.getStyle().getImageVAlign() != null
+ && cell.getStyle().getImageVAlign().equals(Style.MIDDLE)) {
+ voffset = voffset / 2.0f;
+ imgy -= voffset;
+ } else if (cell.getStyle().getImageVAlign() != null
+ && cell.getStyle().getImageVAlign().equals(Style.BOTTOM)) {
+ imgy -= voffset;
+ }
+
+ drawDebugLine(contentStream, imgx, imgy, image.getWidth(),
+ image.getHeight(), settings);
+
+ // logger.debug("Image: " + imgx + " : " + (imgy -
+ // image.getHeight()));
+ contentStream.drawXObject(pdImage, imgx, imgy - image.getHeight(),
+ image.getWidth(), image.getHeight());
+ } catch (IOException e) {
+ logger.error("IO Exception", e);
+ throw new PdfAsException("Error", e);
+ }
+
+ }
+
+ public static float[] getColSizes(PDFBoxTable abstractTable) {
+ float[] origcolsSizes = abstractTable.getColsRelativeWith();
+ int max_cols = abstractTable.getColCount();
+ float[] colsSizes = new float[max_cols];
+ if (origcolsSizes == null) {
+ // set the column ratio for all columns to 1
+ for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+ colsSizes[cols_idx] = 1;
+ }
+ } else {
+ // set the column ratio for all columns to 1
+ for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+ colsSizes[cols_idx] = origcolsSizes[cols_idx];
+ }
+ }
+
+ // adapt
+ float total = 0;
+
+ for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+ total += colsSizes[cols_idx];
+ }
+
+ for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+ colsSizes[cols_idx] = (colsSizes[cols_idx] / total)
+ * abstractTable.getWidth();
+ }
+
+ float sum = 0;
+
+ for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+ sum += colsSizes[cols_idx];
+ }
+
+ logger.info("Table Col Sizes SUM {} Table Width {}", sum,
+ abstractTable.getWidth());
+ logger.info("Table Table Height {}", abstractTable.getHeight());
+
+ return colsSizes;
+ }
+
+ public static void drawBorder(PDPage page,
+ PDPageContentStream contentStream, float x, float y, float width,
+ float height, PDFBoxTable abstractTable, PDDocument doc,
+ boolean subtable, ISettings settings) throws PdfAsException {
+ try {
+
+ logger.debug("Drawing Table borders for "
+ + abstractTable.getOrigTable().getName());
+
+ final int rows = abstractTable.getRowCount();
+ float border = abstractTable.style.getBorder();
+ float[] colsSizes = getColSizes(abstractTable);
+
+ if (border > 0) {
+ contentStream.setLineWidth(border);
+
+ float x_from = x;
+ float x_to = x + width;
+ float y_from = y + height;
+ float y_to = y + height;
+
+ // draw first line
+ logger.debug("ROW LINE: {} {} {} {}", x_from, y_from, x_to,
+ y_from);
+ contentStream.drawLine(x, y_from, x_to, y_from);
+
+ // Draw all row borders
+ for (int i = 0; i < rows; i++) {
+ y_from -= abstractTable.getRowHeights()[i];
+
+ // Draw row border!
+ logger.debug("ROW LINE: {} {} {} {}", x_from, y_from, x_to,
+ y_from);
+ contentStream.drawLine(x, y_from, x_to, y_from);
+
+ }
+
+ // reset y for "line feed"
+ y_from = y + height;
+ y_to = y_from - abstractTable.getRowHeights()[0];
+
+ // Draw all column borders
+ for (int i = 0; i < rows; i++) {
+ ArrayList<Entry> row = abstractTable.getRow(i);
+
+ // reset x for "line feed"
+ x_from = x;
+
+ // draw first line
+ logger.debug("COL LINE: {} {} {} {}", x_from, y_from,
+ x_from, y_to);
+
+ contentStream.drawLine(x_from, y_from, x_from, y_to);
+
+ for (int j = 0; j < row.size(); j++) {
+ Entry cell = (Entry) row.get(j);
+
+ for (int k = 0; k < cell.getColSpan(); k++) {
+ if (k + j < colsSizes.length) {
+ x_from += colsSizes[k + j];
+ }
+ }
+ logger.debug("COL LINE: {} {} {} {}", x_from, y_from,
+ x_from, y_to);
+ contentStream.drawLine(x_from, y_from, x_from, y_to);
+ }
+
+ if (i + 1 < rows) {
+ y_from = y_to;
+ y_to = y_from - abstractTable.getRowHeights()[i + 1];
+ }
+ }
+
+ }
+ } catch (Throwable e) {
+ logger.warn("drawing table borders", e);
+ throw new PdfAsException("drawing table borders", e);
+ }
+ }
+
+ public static void drawTableBackground(PDPage page,
+ PDPageContentStream contentStream, float x, float y, float width,
+ float height, PDFBoxTable abstractTable, ISettings settings)
+ throws PdfAsException {
+ try {
+ if (abstractTable.getBGColor() != null) {
+ contentStream.setNonStrokingColor(abstractTable.getBGColor());
+ contentStream.fillRect(x, y, abstractTable.getWidth(),
+ abstractTable.getHeight());
+ contentStream.setNonStrokingColor(Color.BLACK);
+ }
+ } catch (Throwable e) {
+ logger.warn("drawing table borders", e);
+ throw new PdfAsException("drawing table borders", e);
+ }
+ }
+
+ private static void drawDebugLine(PDPageContentStream contentStream,
+ float x, float y, float width, float height, ISettings settings) {
+ if ("true".equals(settings.getValue(TABLE_DEBUG))) {
+ try {
+ contentStream.setStrokingColor(Color.RED);
+ contentStream.drawLine(x, y, x + width, y);
+ contentStream.setStrokingColor(Color.BLUE);
+ contentStream.drawLine(x, y, x, y - height);
+ contentStream.setStrokingColor(Color.GREEN);
+ contentStream.drawLine(x + width, y, x + width, y - height);
+ contentStream.setStrokingColor(Color.ORANGE);
+ contentStream.drawLine(x, y - height, x + width, y - height);
+
+ contentStream.setStrokingColor(Color.BLACK);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private static void drawDebugPadding(PDPageContentStream contentStream,
+ float x, float y, float padding, float width, float height,
+ ISettings settings) {
+ if ("true".equals(settings.getValue(TABLE_DEBUG))) {
+ try {
+ contentStream.setStrokingColor(Color.RED);
+ contentStream.drawLine(x, y, x + padding, y - padding);
+ contentStream.drawLine(x + width, y, x + width - padding, y
+ - padding);
+ contentStream.drawLine(x + width, y - height, x + width
+ - padding, y - height + padding);
+ contentStream.drawLine(x, y - height, x + padding, y - height
+ + padding);
+ contentStream.setStrokingColor(Color.BLACK);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private static String getFontID(PDFont font, PDResources resources) {
+ Iterator<java.util.Map.Entry<String, PDFont>> it = resources.getFonts()
+ .entrySet().iterator();
+ while (it.hasNext()) {
+ java.util.Map.Entry<String, PDFont> entry = it.next();
+ if (entry.getValue().equals(font)) {
+ return entry.getKey();
+ }
+ }
+ return "";
+ }
+
+}