From a0de2a3b2a5f4a99f280f5caebbca0d183ae109a Mon Sep 17 00:00:00 2001 From: tknall Date: Wed, 7 Feb 2007 10:08:21 +0000 Subject: Bugfix: Querformat, BKU 2.7.x, ... git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@35 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../wag/egov/egiz/pdf/AbsoluteTextSignature.java | 286 +++++++++++++++++---- .../wag/egov/egiz/pdf/BinarySignature.java | 70 +++-- .../at/knowcenter/wag/egov/egiz/pdf/PDFPage.java | 34 ++- .../knowcenter/wag/egov/egiz/pdf/PDFUtilities.java | 12 +- .../wag/egov/egiz/pdf/PositioningInstruction.java | 131 ++++++++++ .../at/knowcenter/wag/egov/egiz/pdf/TablePos.java | 20 ++ 6 files changed, 450 insertions(+), 103 deletions(-) create mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java (limited to 'src/main/java/at/knowcenter/wag/egov/egiz/pdf') diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java index b3c2e24..85673b5 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java @@ -151,69 +151,89 @@ public class AbsoluteTextSignature SignatureTypes sig_types = SignatureTypes.getInstance(); List signatureTypes_ = sig_types.getSignatureTypeDefinitions(); - List found_candidates = new ArrayList(); + List found_potential_candidates = new ArrayList(); for (int i = 0; i < signatureTypes_.size(); i++) { SignatureTypeDefinition block_type = (SignatureTypeDefinition) signatureTypes_.get(i); List found_candidates_for_type = findPotentialSignaturesForProfile(text, block_type); - found_candidates.addAll(found_candidates_for_type); + found_potential_candidates.addAll(found_candidates_for_type); } - if (found_candidates.isEmpty()) + if (found_potential_candidates.isEmpty()) { logger.debug("no candidates found at all"); return null; } + List found_candidates = new ArrayList(); logger.debug("checking block integrity"); - for (int i = 0; i < found_candidates.size(); i++) + for (int i = 0; i < found_potential_candidates.size(); i++) { - FoundBlock found_block = (FoundBlock) found_candidates.get(i); + FoundBlock found_block = (FoundBlock) found_potential_candidates.get(i); String date_value = getDateValue(text, found_block); logger.debug("date_value = " + date_value); - EGIZDate date = EGIZDate.parseFromString(date_value); + try + { + EGIZDate date = EGIZDate.parseFromString(date_value); + + logger.debug("found_block = " + date + " - " + found_block); - logger.debug("found_block = " + date + " - " + found_block); + checkBlockIntegrity(text, found_block); - checkBlockIntegrity(text, found_block); + found_candidates.add(found_block); + } + catch (Exception e) + { + logger.debug("Exception while checking the integrity of the found block " + found_block + ". Ignoring this block.", e); + } } sortFoundBlocksByDate(text, found_candidates); - - logger.debug("sorted blocks:"); - for (int i = 0; i < found_candidates.size(); i++) + if (logger.isDebugEnabled()) { - FoundBlock found_block = (FoundBlock) found_candidates.get(i); + logger.debug("sorted blocks:"); + for (int i = 0; i < found_candidates.size(); i++) + { + FoundBlock found_block = (FoundBlock) found_candidates.get(i); - String date_value = getDateValue(text, found_block); - EGIZDate date = EGIZDate.parseFromString(date_value); + String date_value = getDateValue(text, found_block); + EGIZDate date = EGIZDate.parseFromString(date_value); - logger.debug(" #" + i + ": " + date + " - " + found_block); + logger.debug(" #" + i + ": " + date + " - " + found_block); + } } List latest_blocks = filterLastDateEqualBlocks(text, found_candidates); - logger.debug("latest blocks:"); - for (int i = 0; i < latest_blocks.size(); i++) + if (logger.isDebugEnabled()) { - FoundBlock found_block = (FoundBlock) latest_blocks.get(i); + logger.debug("latest blocks:"); + for (int i = 0; i < latest_blocks.size(); i++) + { + FoundBlock found_block = (FoundBlock) latest_blocks.get(i); - String date_value = getDateValue(text, found_block); - EGIZDate date = EGIZDate.parseFromString(date_value); + String date_value = getDateValue(text, found_block); + EGIZDate date = EGIZDate.parseFromString(date_value); - logger.debug(" #" + i + ": " + date + " - " + found_block); + logger.debug(" #" + i + ": " + date + " - " + found_block); + } } - boolean semantic_equality = PdfAS.checkForSemanticEquality(latest_blocks); - logger.debug("semantic_equality = " + semantic_equality); - if (!semantic_equality) - { - throw new SignatureException(314, "The latest blocks weren't semantically equal."); - } + // The semantic equality check has been outdated by the + // advanced choosing algorithm. + // boolean semantic_equality = + // PdfAS.checkForSemanticEquality(latest_blocks); + // logger.debug("semantic_equality = " + semantic_equality); + // if (!semantic_equality) + // { + // throw new SignatureException(314, "The latest blocks weren't semantically + // equal."); + // } + + FoundBlock latest_block = chooseMostPossibleBlock(latest_blocks); - FoundBlock latest_block = chooseMostPossibleSemanticallyEqualBlock(latest_blocks); logger.debug("latest block = " + latest_block); return latest_block; } @@ -269,7 +289,6 @@ public class AbsoluteTextSignature } } - for (int lci = 0; lci < found_last_captions.size(); lci++) { int last_caption_index = ((Integer) found_last_captions.get(lci)).intValue(); @@ -470,8 +489,6 @@ public class AbsoluteTextSignature */ public static int findEndOfValue(String text, int start_index) { - // FIXME[tknall]: this method does not work properly for landscape documents because always starts with "\n". Look for errors in PdfAS.java, method findBlockInText(...) to set the start_index accordingly. - // Hint: Captions and values of landscape documents are separated with " \n" and not only with " ". int newline_index = text.indexOf('\n', start_index); if (newline_index < 0) { @@ -685,44 +702,213 @@ public class AbsoluteTextSignature } /** - * Chooses the most possible (best choice) block of the list of semantically - * equal blocks. + * Chooses the most possible (best choice) block of the list of blocks. * *

- * Thus blocks are considered semantically equal if their required keys are - * semantically equal, semantically equal blocks may still differ in the - * number of their non required fields. This may lead to multiple found blocks - * of the same size in characters, but where some blocks' elements swallow - * elements found by other blocks. + * The strategy to find the most possible block is to choose the very one + * block with the maximum number of captions. This block has extracted most + * information from the text. *

*

- * The strategy to avoid this is to choose the very one block with the maximum - * number of captions. This block has extracted most information from the - * text. + * If there are still multiple blocks with the same number of cations, the + * blocks are compared caption-wise. The block with all captions being longer + * or equal to all other blocks' captions wins. *

* * @param found_blocks * The List of semantically equal blocks. * @return Returns the best choice FoundBlock. + * @throws SignatureException + */ + public static FoundBlock chooseMostPossibleBlock(List found_blocks) throws SignatureException + { + // int largest_block_index = 0; + // FoundBlock largest_block = (FoundBlock) found_blocks.get(0); + // + // for (int i = 1; i < found_blocks.size(); i++) + // { + // FoundBlock current_block = (FoundBlock) found_blocks.get(i); + // + // if (current_block.found_keys.size() > largest_block.found_keys.size()) + // { + // largest_block = current_block; + // largest_block_index = i; + // } + // } + + List vertically_largest = filterVerticallyLargestBlocks(found_blocks); + if (logger.isDebugEnabled()) + { + logger.debug("vertically largest blocks:"); + for (int i = 0; i < vertically_largest.size(); i++) + { + FoundBlock found_block = (FoundBlock) vertically_largest.get(i); + + logger.debug(" #" + i + ": " + found_block); + } + } + + List horizontally_largest = filterHorizontallyLargestBlocks(vertically_largest); + if (logger.isDebugEnabled()) + { + logger.debug("horizontally largest blocks:"); + for (int i = 0; i < horizontally_largest.size(); i++) + { + FoundBlock found_block = (FoundBlock) horizontally_largest.get(i); + + logger.debug(" #" + i + ": " + found_block); + } + } + + FoundBlock largest_block = (FoundBlock) horizontally_largest.get(0); + + logger.debug("Chose largest block: " + largest_block); + return largest_block; + } + + /** + * Filters out all blocks but the vertically largest ones. + * + *

+ * A vertically largest block has the most found keys. + *

+ * + * @param found_blocks + * The List of FoundBlock objects to be filtered. + * @return Returns the List of the vertically largest FoundBlock objects. */ - public static FoundBlock chooseMostPossibleSemanticallyEqualBlock( - List found_blocks) + public static List filterVerticallyLargestBlocks(List found_blocks) { - int largest_block_index = 0; + // determine the size of the largest block(s) + int largest_size = Integer.MIN_VALUE; + for (int i = 1; i < found_blocks.size(); i++) + { + FoundBlock fb = (FoundBlock) found_blocks.get(i); + final int current_size = fb.found_keys.size(); + if (current_size > largest_size) + { + largest_size = current_size; + } + } + + // keep all blocks that have the largest_size + List largest_blocks = new ArrayList(); + for (int i = 0; i < found_blocks.size(); i++) + { + FoundBlock fb = (FoundBlock) found_blocks.get(i); + if (fb.found_keys.size() < largest_size) + { + continue; + } + largest_blocks.add(fb); + } + + return largest_blocks; + } + + /** + * Filters out all blocks but the horizonally largest ones. + * + *

+ * A vertically largest block has the most found keys. + *

+ * + * @param found_blocks + * The List of FoundBlock objects to be filtered. All of these + * FoundBlock objects must have the same number of found keys. + * @return Returns the List of the horizontally largest FoundBlock objects. + * @throws SignatureException + */ + public static List filterHorizontallyLargestBlocks(List found_blocks) throws SignatureException + { + List horizontally_largest = new ArrayList(); FoundBlock largest_block = (FoundBlock) found_blocks.get(0); + horizontally_largest.add(largest_block); for (int i = 1; i < found_blocks.size(); i++) { - FoundBlock current_block = (FoundBlock) found_blocks.get(i); + FoundBlock fb = (FoundBlock) found_blocks.get(i); + + if (isHorizontallyEqual(fb, largest_block)) + { + horizontally_largest.add(fb); + continue; + } - if (current_block.found_keys.size() > largest_block.found_keys.size()) + if (isHorizontallyLarger(fb, largest_block)) + { + horizontally_largest = new ArrayList(); + largest_block = fb; + horizontally_largest.add(largest_block); + } + else { - largest_block = current_block; - largest_block_index = i; + if (!isHorizontallyLarger(largest_block, fb)) + { + // The block is neither equal nor larger nor lower. + // We cannot exactly determine which one to use. + throw new SignatureException(315, "The blocks are neither larger nor lower nor equal. Cannot decide which one to pick. fb = " + fb + ", largest_block = " + largest_block); + } } + } - logger.debug("Chose largest block with index #" + largest_block_index + ": " + largest_block); - return largest_block; + return horizontally_largest; } + + protected static boolean isHorizontallyEqual(FoundBlock fb0, FoundBlock fb1) + { + final int num_keys = fb0.found_keys.size(); + if (num_keys != fb1.found_keys.size()) + { + throw new IllegalArgumentException("Cannot compare FoundBlock keys: fb0 doesn't have the same number of keys as fb1. " + fb0.found_keys.size() + " vs. " + fb1.found_keys.size()); + } + + for (int i = 0; i < num_keys; i++) + { + FoundKey fk0 = (FoundKey) fb0.found_keys.get(i); + FoundKey fk1 = (FoundKey) fb1.found_keys.get(i); + + if (fk0.caption.length() != fk1.caption.length()) + { + return false; + } + } + + return true; + } + + protected static boolean isHorizontallyLarger(FoundBlock fb0, FoundBlock fb1) + { + final int num_keys = fb0.found_keys.size(); + if (num_keys != fb1.found_keys.size()) + { + throw new IllegalArgumentException("Cannot compare FoundBlock keys: fb0 doesn't have the same number of keys as fb1. " + fb0.found_keys.size() + " vs. " + fb1.found_keys.size()); + } + + boolean larger = false; + + for (int i = 0; i < num_keys; i++) + { + FoundKey fk0 = (FoundKey) fb0.found_keys.get(i); + FoundKey fk1 = (FoundKey) fb1.found_keys.get(i); + + if (fk0.caption.length() == fk1.caption.length()) + { + continue; + } + + if (fk0.caption.length() > fk1.caption.length()) + { + larger = true; + continue; + } + + // if (fk0.caption.length() < fk1.caption.length()) + return false; + } + + return larger; + } + } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java index c5acbc4..e10061c 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java @@ -667,17 +667,15 @@ public abstract class BinarySignature * The original document. * @param pdf_table * The PdfPTable that contains the signature block. - * @param pos - * The Position object giving the exact location where to place the - * table. if page is -1, a new page will be appended to the document. - * Then the table will be inserted on that new page using the - * coordinates. + * @param pi + * The PositioningInstruction telling the algorithm where to place + * the signature block. * @return Returns the new document. * @throws PresentableException * Forwarded exception. */ public static IncrementalUpdateInformation writeIncrementalUpdate( - byte[] original_document, PdfPTable pdf_table, TablePos pos, + byte[] original_document, PdfPTable pdf_table, PositioningInstruction pi, List variable_field_definitions, List all_field_definitions) throws PresentableException { try @@ -697,30 +695,20 @@ public abstract class BinarySignature // The stamper allows this by setting append = true PdfStamper stamper = new PdfStamper(reader, baos, '\0', true); - int pdf_page_num = reader.getNumberOfPages(); - - // int signature_page = -1; - // - // if (pos_y >= 0) - // { - // signature_page = pdf_page_num; - // } - if (pos.page == -1) + if (pi.isMakeNewPage()) { - pos.page = pdf_page_num + 1; + int pdf_page_num = reader.getNumberOfPages(); Rectangle psize = reader.getPageSizeWithRotation(pdf_page_num); Rectangle rect = new Rectangle(psize); - stamper.insertPage(pos.page, rect); - - // pos_y *= -1; + stamper.insertPage(pdf_page_num + 1, rect); } - if (pos.page < 1 || pos.page > stamper.getReader().getNumberOfPages()) + if (pi.getPage() < 1 || pi.getPage() > stamper.getReader().getNumberOfPages()) { - throw new PDFDocumentException(224, "The provided pos.page (=" + pos.page + ") is out of range."); + throw new PDFDocumentException(224, "The provided page (=" + pi.getPage() + ") is out of range."); } - PdfContentByte content = stamper.getOverContent(pos.page); + PdfContentByte content = stamper.getOverContent(pi.getPage()); // content = StampContent einer PageStamp. // System.out.println("table_width = " + pdf_table.getTotalWidth() + ", @@ -741,27 +729,27 @@ public abstract class BinarySignature // pdf_table.writeSelectedRows(0, -1, SIGNATURE_BORDER / 2, // table_position, content); - content.addTemplate(table_template, pos.pos_x, pos.pos_y - pdf_table.getTotalHeight()); + content.addTemplate(table_template, pi.getX(), pi.getY() - pdf_table.getTotalHeight()); // For debugging print a 100x100 grid -// { -// Rectangle psize = reader.getPageSizeWithRotation(pos.page); -// float page_width = psize.width(); -// float page_height = psize.height(); -// for (float x = 0; x < page_width; x += 100) -// { -// content.moveTo(x, 0); -// content.lineTo(x, page_height); -// content.stroke(); -// } -// for (float y = 0; y < page_height; y += 100) -// { -// content.moveTo(0, y); -// content.lineTo(page_width, y); -// content.stroke(); -// } -// } - + // { + // Rectangle psize = reader.getPageSizeWithRotation(pos.page); + // float page_width = psize.width(); + // float page_height = psize.height(); + // for (float x = 0; x < page_width; x += 100) + // { + // content.moveTo(x, 0); + // content.lineTo(x, page_height); + // content.stroke(); + // } + // for (float y = 0; y < page_height; y += 100) + // { + // content.moveTo(0, y); + // content.lineTo(page_width, y); + // content.stroke(); + // } + // } + // content.setLineWidth(10.0f); // content.moveTo(0, 0); // content.lineTo(100, 100); diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java index c98aee8..c1d6681 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java @@ -66,14 +66,23 @@ public class PDFPage extends PDFTextStripper protected float max_image_ypos = Float.NEGATIVE_INFINITY; /** - * The empty constructor. + * The y coordinate of the footer line. PDF elements below this footer line will not be regarded. + */ + protected float footer_line = 0.0f; + + /** + * Constructor. + * + * @param footer_line The y coordinate of the footer line. PDF elements below this footer line will not be regarded. * * @throws IOException */ - public PDFPage() throws IOException + public PDFPage(float footer_line) throws IOException { super(); + this.footer_line = footer_line; + OperatorProcessor newInvoke = new MyInvoke(); newInvoke.setContext(this); operators.put("Do", newInvoke); @@ -341,17 +350,24 @@ public class PDFPage extends PDFTextStripper */ protected void showCharacter(TextPosition text) { - float current_y = text.getY(); - String character = text.getCharacter(); + final float current_y = text.getY(); + final String character = text.getCharacter(); + +// if (current_y > this.footer_line) +// { +// logger_.debug("character is below footer_line. footer_line = " + this.footer_line + ", text.character=" + character + ", y=" + current_y); +// return; +// } + // store ypos of the char if it is not empty if (!character.equals(" ") && current_y > this.max_character_ypos) { this.max_character_ypos = current_y; - //logger_.debug("text.character=" + character + ", y=" + current_y); + logger_.debug("text.character=" + character + ", y=" + current_y); // System.err.println(character + "|" + current_y); } - // logger_.debug("text.character=" + character + ", y=" + current_y); + logger_.debug("text.character=" + character + ", y=" + current_y); // System.err.println(character + "|" + current_y); } @@ -454,6 +470,12 @@ public class PDFPage extends PDFTextStripper logger_.debug("actual_lowest_point = " + actual_lowest_point); + if (actual_lowest_point > PDFPage.this.footer_line) + { + logger_.debug("image is below footer_line. footer_line = " + PDFPage.this.footer_line); + return; + } + if (actual_lowest_point > PDFPage.this.max_image_ypos) { PDFPage.this.max_image_ypos = actual_lowest_point; diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java index 8fa3b35..05854dd 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java @@ -38,7 +38,7 @@ import com.lowagie.text.DocumentException; */ public abstract class PDFUtilities { - public static float calculateLastPageLength(final byte[] pdf) throws PDFDocumentException + public static float calculateLastPageLength(final byte[] pdf, float footer_line) throws PDFDocumentException { try { @@ -53,7 +53,7 @@ public abstract class PDFUtilities parser.parse(); PDDocument pdfDocument_ = parser.getPDDocument(); - float last_page_length = calculateLastPageLength(pdfDocument_); + float last_page_length = calculateLastPageLength(pdfDocument_, footer_line); pdfDocument_.close(); return last_page_length; @@ -68,20 +68,20 @@ public abstract class PDFUtilities } } - public static float calculateLastPageLength(PDDocument document) throws IOException + public static float calculateLastPageLength(PDDocument document, float footer_line) throws IOException { int last_page_id = document.getNumberOfPages(); List allPages = document.getDocumentCatalog().getAllPages(); PDPage last_page = (PDPage) allPages.get(last_page_id - 1); - return calculatePageLength(last_page); + return calculatePageLength(last_page, footer_line); } - public static float calculatePageLength(PDPage page) throws IOException + public static float calculatePageLength(PDPage page, float footer_line) throws IOException { // logger_.debug("Last Page id:" + last_page_id); // PDPage last_page = (PDPage) allPages.get(0); - PDFPage my_page = new PDFPage(); + PDFPage my_page = new PDFPage(footer_line); my_page.processStream(page, page.findResources(), page.getContents().getStream()); return my_page.getMaxPageLength(); } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java new file mode 100644 index 0000000..c04177b --- /dev/null +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2006 by Know-Center, Graz, Austria + * + * This software is the confidential and proprietary information of Know-Center, + * Graz, Austria. You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Know-Center. + * + * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF + * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY + * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. + * + * $Id: $ + */ +package at.knowcenter.wag.egov.egiz.pdf; + +/** + * The positioning instruction holds information of where to place the signature + * block. + * + *

+ * This instruction is given to the PDF writer in order to place the signature. + *

+ * + * @author wprinz + */ +public class PositioningInstruction +{ + + /** + * Tells, if a new plain page should be appended. + * + *

+ * This command is executed before the signature block is positioned according + * to page, x and y. + *

+ */ + protected boolean make_new_page = false; + + /** + * The number of the page on which the signature block is to be placed. If + * specified to make a new page, the number of this newly created page can be + * used here as well. + */ + protected int page = 0; + + /** + * The x coordinate where the upper left corner of the signature block should + * be placed. + */ + protected float x = 0.0f; + + /** + * The y coordinate where the upper left corner of the signature block should + * be placed. + */ + protected float y = 0.0f; + + /** + * + * @param make_new_page + * Tells, if a new plain page should be appended. This command is + * executed before the signature block is positioned according to + * page, x and y. + * @param page + * The number of the page on which the signature block is to be + * placed. If specified to make a new page, the number of this newly + * created page can be used here as well. + * @param x + * The x coordinate where the upper left corner of the signature + * block should be placed. + * @param y + * The y coordinate where the upper left corner of the signature + * block should be placed. + */ + public PositioningInstruction(boolean make_new_page, int page, float x, float y) + { + this.make_new_page = make_new_page; + this.page = page; + this.x = x; + this.y = y; + } + + /** + * Tells, if a new plain page should be appended to the document. + * + * @return Returns true, if a new plain page should be appended. + */ + public boolean isMakeNewPage() + { + return this.make_new_page; + } + + /** + * Returns the page on which the signature is to be printed. + * + * @return Returns the page on which the signature is to be printed. + */ + public int getPage() + { + return this.page; + } + + /** + * Returns the x coordinate where the upper left corner of the signature block + * should be placed. + * + * @return Returns the x coordinate where the upper left corner of the + * signature block should be placed. + */ + public float getX() + { + return this.x; + } + + /** + * Returns the y coordinate where the upper left corner of the signature block + * should be placed. + * + * @return Returns the y coordinate where the upper left corner of the + * signature block should be placed. + */ + public float getY() + { + return this.y; + } + +} diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java index ba55cdf..6cfdded 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java @@ -35,6 +35,22 @@ public class TablePos implements Serializable /** * The page on which the block should be displayed. + * + *

+ * A value greater than or equal 1 means to absolutely position the signature + * on that page. + *

+ *

+ * A value of -1 means to append a new page to the document and absolutely + * position the signature on the new page. + *

+ *

+ * A value of -2 means to determine the length of the last page as without + * absolute positioning, but ignore all text below a certain footer line. If + * there is enough space between the end of the text and this footer line, the + * signature should be positioned automatically in there. Otherwise it should + * be placed on a new page. + *

*/ public int page = 0; @@ -53,4 +69,8 @@ public class TablePos implements Serializable */ public float width = 0.0f; + /** + * The top y position of the footer line. + */ + public float footer_line = 0.0f; } -- cgit v1.2.3