aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/knowcenter/wag/egov/egiz/pdf/StructContentHelper.java
diff options
context:
space:
mode:
authortknall <tknall@7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c>2013-01-09 15:41:29 +0000
committertknall <tknall@7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c>2013-01-09 15:41:29 +0000
commit535a04fa05f739ec16dd81666e3b0f82dfbd442d (patch)
tree0804f301c1a9ceb303a8441b7b29244fc8eb7ff0 /src/main/java/at/knowcenter/wag/egov/egiz/pdf/StructContentHelper.java
parent1efaf6fd5619dfa95c9d7e8c71eda4c2ffba4998 (diff)
downloadpdf-as-3-535a04fa05f739ec16dd81666e3b0f82dfbd442d.tar.gz
pdf-as-3-535a04fa05f739ec16dd81666e3b0f82dfbd442d.tar.bz2
pdf-as-3-535a04fa05f739ec16dd81666e3b0f82dfbd442d.zip
pdf-as-lib maven project files moved to pdf-as-lib
git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/pdf-as/trunk@926 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c
Diffstat (limited to 'src/main/java/at/knowcenter/wag/egov/egiz/pdf/StructContentHelper.java')
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/pdf/StructContentHelper.java716
1 files changed, 0 insertions, 716 deletions
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/StructContentHelper.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/StructContentHelper.java
deleted file mode 100644
index 7ca5a0a..0000000
--- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/StructContentHelper.java
+++ /dev/null
@@ -1,716 +0,0 @@
-/**
- * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
- * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
- * joint initiative of the Federal Chancellery Austria and Graz University of
- * Technology.
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * http://www.osor.eu/eupl/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- */
-package at.knowcenter.wag.egov.egiz.pdf;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-
-import at.gv.egiz.pdfas.exceptions.ErrorCode;
-import at.knowcenter.wag.egov.egiz.exceptions.PresentableException;
-import at.knowcenter.wag.egov.egiz.sig.SignatureObject;
-
-import com.lowagie.text.Rectangle;
-import com.lowagie.text.pdf.PdfArray;
-import com.lowagie.text.pdf.PdfContentByte;
-import com.lowagie.text.pdf.PdfDictionary;
-import com.lowagie.text.pdf.PdfFormField;
-import com.lowagie.text.pdf.PdfIndirectReference;
-import com.lowagie.text.pdf.PdfName;
-import com.lowagie.text.pdf.PdfNumber;
-import com.lowagie.text.pdf.PdfObject;
-import com.lowagie.text.pdf.PdfStamper;
-import com.lowagie.text.pdf.PdfStamperImp;
-import com.lowagie.text.pdf.PdfString;
-import com.lowagie.text.pdf.PdfTemplate;
-import com.lowagie.text.pdfas.StructContentWriter;
-import com.lowagie.text.pdfas.StructContentWriterHolder;
-import com.lowagie.text.pdfas.UrlInTextFinder;
-
-/**
- * Helper class for writing the structure hierarchy of the signature elements.
- * Everything is written with the PdfObject low level API because there is no better support.
- * The structured content is only written for structured (==tagged) input documents. The methods have to be called in the
- * defined order. The object cannot be reused for several signatures.<br>
- * See pdf spec "Logical Structure" for details.<br>
- * The struct writing could be a little more abstracted, but this would include quite some itext extension work. And like this it
- * fits better to PDF-AS / wprinz coding style :-(
- * @author exthex
- *
- */
-public class StructContentHelper implements StructContentWriter {
- private static final Logger logger = Logger.getLogger(StructContentHelper.class);
-
- private static final String SIGBLOCK_STRUCT_TYPE = "P";
- private static final PdfName PARENTTREENEXTKEY = new PdfName("ParentTreeNextKey");
- private static final String ALT_TEXT_DEFAULT = "Signaturbildmarke";
- private final static String ALT_TEXT_CONF_KEY = "sigLogoAltText";
-
-
- private int nextMcid = 0;
- /**
- * MCID value used for the sigblock marked contend identifier
- */
- private int sigBlockMcid =-1;
- /**
- * MCID value for "Bildmarke" marked content sequence
- */
- private int figureMcid = -1;
- /**
- * MCID value for verify link marked content sequence
- */
- private int linkMcid = -1;
- private String linkUrlString = null;
- private boolean isTagged = false;
- private Map linkPosMap = new HashMap();
- private Map tmpMap = new HashMap();
-
- private PdfStamper stamper;
- private PdfStamperImp stamperImp;
- private PdfContentByte content;
- private PdfDictionary page;
- private PdfNumber parentTreeNextKey = null;
- private PdfNumber annotationParentTreeKey = null;
-
- /**
- * Temporary save a pos
- */
- private Rectangle tempMarkedPos = null;
- /**
- * Cell position of the signature verify link overlay
- */
- private Rectangle verifyLinkCellPos = null;
-
- /**
- * Kids array (K) of the <code>StructTreeRoot</code>
- */
- private PdfArray structTreeRootKids = null;
-
- /**
- * Entry in the ParentTree.Nums array used for sigtable structs
- */
- private PdfArray mainParentTreeNumEntry;
-
- /**
- * Create new helper for one signature, and bind it to {@link StructContentWriterHolder}
- * for thread local access from itext.
- *
- * @param stamper
- * @param content
- * @param pageNr
- */
- StructContentHelper(PdfStamper stamper, PdfContentByte content, int pageNr) {
- this.stamper = stamper;
- this.content = content;
- stamperImp = ((PdfStamperImp) stamper.getWriter());
- page = stamper.getReader().getPageN(pageNr);
- StructContentWriterHolder.setThreadLocalWriter(this);
- }
-
- /**
- * Remove thread local helper
- */
- public void removeCurrent() {
- StructContentWriterHolder.removeThreadLocalWriter();
- }
-
- /**
- * Prepare structured content for signature block. This method initializes the whole StructTreeRoot stuff.
- * @param sigBlockObj
- * @throws PresentableException
- */
- void prepareStructData(PdfTemplate sigBlockObj) throws PresentableException {
-
- try {
- checkTagging();
- if (!isTagged) {
- return;
- }
-
- doAnnoTabOrder();
-
- PdfDictionary structTreeRoot = getStructTreeRoot();
- stamperImp.markUsed(structTreeRoot);
-
- PdfArray parentTreeNums = getParentTreeNums();
-
- PdfNumber structParentsNr = page.getAsNumber(PdfName.STRUCTPARENTS); // read StructParents entry from current page
-
- mainParentTreeNumEntry = obtainParentTreeEntry(structTreeRoot, parentTreeNums, structParentsNr, sigBlockObj);
-
- nextMcid = mainParentTreeNumEntry.size();
- sigBlockMcid = nextMcid;
- nextMcid++;
-
- this.structTreeRootKids = obtainStructTreeRootKids(structTreeRoot);
-
- if(this.structTreeRootKids == null)
- {
- this.structTreeRootKids = this.createStructTreeRootKids(structTreeRoot);
- }
-
- } catch (Exception ex) {
- logger.error("error", ex);
- throw new PresentableException(ErrorCode.CANNOT_WRITE_PDF,
- "error writing structured signature content", ex);
- }
- }
-
- PdfArray createStructTreeRootKids(PdfDictionary structTreeRoot) {
- PdfArray tmp = new PdfArray();
- structTreeRoot.put(PdfName.K, tmp);
- return tmp;
- }
-
- /**
- * Create struct data for main signature block
- * @throws PresentableException
- */
- void buildSigBlockStructData() throws PresentableException {
- if (!isTagged) return;
- try {
- PdfIndirectReference newStructRef = createStructElem(SIGBLOCK_STRUCT_TYPE, new PdfNumber(
- sigBlockMcid), getStructTreeRoot().getIndRef());
-
- // ADD everything at the end because nothing can be written afterwards
- structTreeRootKids.add(newStructRef);
- mainParentTreeNumEntry.add(newStructRef);
-
- stamperImp.markUsed(mainParentTreeNumEntry);
-
- } catch (Exception ex) {
- logger.error("error", ex);
- throw new PresentableException(ErrorCode.CANNOT_WRITE_PDF,
- "error writing structured signature content", ex);
- }
- }
-
-
- /**
- * Finish struct data for signblock and it's elements (NOT for the external link and annot!)
- * @throws PresentableException
- */
- void finishMainStructData() throws PresentableException {
- try {
- if (isTagged && mainParentTreeNumEntry.getIndRef() == null) {
- getParentTreeNums().add(
- stamper.getWriter().addToBody(mainParentTreeNumEntry).getIndirectReference());
- stamperImp.markUsed(getParentTreeNums());
- stamperImp.markUsed(getStructTreeRoot().getAsDict(PdfName.PARENTTREE));
- }
- } catch (Exception ex) {
- logger.error("error", ex);
- throw new PresentableException(ErrorCode.CANNOT_WRITE_PDF,
- "error writing structured signature content", ex);
- }
- }
-
- /**
- * Build the structured content for the signature logo (bildmarke). {@link #beginFigureContent(PdfContentByte)} and
- * {@link #endFigureContent(PdfContentByte)} have to be called before this method to mark the logo in the stream. This
- * is done implicitly in the modified itext source (see {@link StructContentWriterHolder}).
- * @param so
- * @param sigBlockObj
- * @throws PresentableException
- */
- void buildFigureStructData(SignatureObject so, PdfTemplate sigBlockObj) throws PresentableException {
- try {
- if (isTagged && isFigureMarked()) {
-
- PdfDictionary structTreeRoot = getStructTreeRoot();
- PdfIndirectReference mcrRef = createMcrStructElem(this.figureMcid, sigBlockObj.getIndirectReference());
- PdfIndirectReference figureRef = createStructElem("Figure", mcrRef,
- getAltText(so.getSignatureTypeDefinition().getType()), structTreeRoot.getIndRef());
-
- structTreeRootKids.add(figureRef);
- mainParentTreeNumEntry.add(figureRef);
-
- stamperImp.markUsed(structTreeRootKids);
- stamperImp.markUsed(structTreeRoot);
- stamperImp.markUsed(mainParentTreeNumEntry);
-
- }
-
- } catch (Exception ex) {
- logger.error("error", ex);
- throw new PresentableException(ErrorCode.CANNOT_WRITE_PDF,
- "error writing structured signature content", ex);
- }
-
- }
-
- /**
- * Build the link annotation for the signature verification link and the structured content accordingly.<br>
- * The tagging does NOT work if the link is placed in a binary signature replace cell (phlengh for this cell)!!
- * @param sigBlockObj
- * @param atp
- * @throws PresentableException
- */
- void buildVerifyLinkStructData(PdfTemplate sigBlockObj, ActualTablePos atp) throws PresentableException {
- if (!this.isTagged || !this.isLinkMarked() || !isLinkFound()) return;
-
- try {
- PdfNumber parentTreeKey = getNewParentTreeKey();
-
- PdfArray annots = obrainAnnotsFromPage();
-
- PdfIndirectReference linkAnnotRef = createLinkAnnot(parentTreeKey, atp);
- annots.add(linkAnnotRef);
-
- PdfIndirectReference objr = createObjrStructElem(linkAnnotRef);
- PdfIndirectReference mcr = createMcrStructElem(this.linkMcid, sigBlockObj.getIndirectReference());
-
- PdfDictionary structTreeRoot = getStructTreeRoot();
-
- PdfArray linkKids = new PdfArray();
- PdfIndirectReference linkKidsRef = stamper.getWriter().getPdfIndirectReference();
-
- PdfIndirectReference linkRef = createStructElem("Link", linkKidsRef, structTreeRoot.getIndRef());
- linkKids.add(objr);
-
- PdfIndirectReference span = createStructElem("Span", mcr, linkRef);
- linkKids.add(span);
-
- stamper.getWriter().addToBody(linkKids, linkKidsRef);
- structTreeRootKids.add(linkRef);
-
- // create new entry in ParentTree
- PdfArray parentTreeNums = getParentTreeNums();
- parentTreeNums.add(parentTreeKey);
- parentTreeNums.add(linkRef);
-
- stamperImp.markUsed(parentTreeNums);
- stamperImp.markUsed(structTreeRoot.getAsDict(PdfName.PARENTTREE));
- stamperImp.markUsed(structTreeRootKids);
- stamperImp.markUsed(linkKids);
-
- stamperImp.markUsed(structTreeRoot);
-
- } catch (IOException e) {
- logger.error("error", e);
- throw new PresentableException(ErrorCode.CANNOT_WRITE_PDF,
- "error writing structured signature content", e);
- }
- }
-
- private boolean isLinkFound() {
- return this.linkUrlString != null && this.verifyLinkCellPos != null && this.linkPosMap.size() > 0 && this.linkMcid >= 0;
- }
-
- /**
- * Build new StructParent entry for signature annotation.
- * @return
- */
- PdfNumber buildAdobeSigStructParent() {
- if (this.isTagged) {
- this.annotationParentTreeKey = getNewParentTreeKey();
- return annotationParentTreeKey;
- } else {
- return null;
- }
- }
-
- /**
- * Build and write structured content for adobe signature annotation
- *
- * @param sigFormField
- * @param title
- * @throws PresentableException
- */
- void buildAdobeSigStruct(PdfFormField sigFormField, String title) throws PresentableException {
- if (!isTagged)
- return;
- try {
-
- PdfDictionary root = getStructTreeRoot();
-
- PdfIndirectReference objrRef = createObjrStructElem(sigFormField.getIndirectReference());
-
- PdfIndirectReference adobeSigStructRef = createStructElem("Link", objrRef, root.getIndRef());
-
- PdfArray parentTreeNums = getParentTreeNums();
- // create new entry in ParentTree
- parentTreeNums.add(annotationParentTreeKey);
- parentTreeNums.add(adobeSigStructRef);
-
- structTreeRootKids.add(adobeSigStructRef);
- stamperImp.markUsed(structTreeRootKids);
-
- stamperImp.markUsed(parentTreeNums);
- stamperImp.markUsed(root.getAsDict(PdfName.PARENTTREE));
-
- } catch (Exception ex) {
- logger.error("error", ex);
- throw new PresentableException(ErrorCode.CANNOT_WRITE_PDF,
- "error writing structured signature content", ex);
- }
-
- }
-
- /**
- * Start tag for signature block content stream. Place this before the signature block is written to a content stream.
- * Call {@link #endSigBlockContent()} afterwards
- */
- void beginSigBlockContent() {
- if (isTagged) {
- content.getInternalBuffer().append(new PdfName(SIGBLOCK_STRUCT_TYPE).getBytes()).append(" <</MCID ")
- .append(sigBlockMcid).append(">> BDC").append('\n');
- }
- }
-
- /**
- * End tag for signature block content stream. Place this after the signature block is written to a content stream
- */
- void endSigBlockContent() {
- if (isTagged) {
- content.endMarkedContentSequence();
- }
- }
-
- /**
- * Writes start tag for signature logo marked content sequence.
- */
- public void beginFigureContent(PdfContentByte localContent) {
- if (isTagged) {
- if (!isFigureMarked()) {
- this.figureMcid = this.nextMcid++;
- localContent.getInternalBuffer().append("/Figure <</MCID ").append(this.figureMcid).append(">> BDC\n");
- } else {
- logger.warn("cannot tag multiple figures (bildmarken)");
- }
- }
- }
-
- /**
- * Writes end tag for signature logo marked content sequence.
- */
- public void endFigureContent(PdfContentByte localContent) {
- if (isTagged && isFigureMarked()) {
- localContent.endMarkedContentSequence();
- }
- }
-
- /**
- * Writes start tag for verify link marked content sequence.
- */
- public void beginLinkContent(PdfContentByte localContent, String urlString) {
- // it's called from here com.lowagie.text.pdf.PdfContentByte.showText(String)
-
- if (isTagged) {
- if (!isLinkMarked()) {
- this.linkUrlString = urlString;
- this.linkMcid = this.nextMcid++;
- localContent.getInternalBuffer().append("/Span <</MCID ").append(this.linkMcid).append(">> BDC\n");
- } else {
- logger.warn("cannot tag multiple verify links");
- }
- }
- }
-
- /**
- * Writes end tag for verify link marked content sequence.
- */
- public void endLinkContent(PdfContentByte localContent) {
- if (isTagged && isLinkMarked()) {
- localContent.endMarkedContentSequence();
- }
- }
-
- /**
- * Implements {@link StructContentWriter#markPos(Rectangle)}
- */
- public void markPos(Rectangle pos) {
- this.tempMarkedPos = pos;
- }
-
- /**
- * Implements {@link StructContentWriter#storeCurrentPosAsLink()}
- */
- public void storeCurrentPosAsLink() {
- this.verifyLinkCellPos = new Rectangle(this.tempMarkedPos);
- }
-
- public void putVal(String key, Object val) {
- tmpMap.put(key, val);
- }
-
- public void storeVals() {
- linkPosMap = new HashMap(tmpMap);
- }
-
- /**
- * set explicit annotation tab order if missing
- */
- private void doAnnoTabOrder() {
- if (page.getAsName(new PdfName("Tabs")) == null) {
- page.put(new PdfName("Tabs"), PdfName.S); // set explicit annotation TAB order
- stamperImp.markUsed(page);
- }
- }
-
- private void checkTagging() {
- PdfDictionary markDict = stamper.getReader().getCatalog().getAsDict(PdfName.MARKINFO);
- if (markDict != null) {
- isTagged = markDict.getAsBoolean(PdfName.MARKED).booleanValue();
- }
- if (!isTagged) {
- logger.debug("input document is not tagged. no structure/wai information is written");
- }
- logger.debug("Input is tagged. Writing structure/WAI data.");
- }
-
-
-
- private PdfIndirectReference createLinkAnnot(PdfNumber structParentNr, ActualTablePos atp) throws IOException {
- PdfDictionary linkAnnot = new PdfDictionary();
-
- PdfDictionary a = new PdfDictionary();
- a.put(PdfName.S, new PdfName("URI"));
- a.put(PdfName.TYPE, PdfName.ACTION);
- a.put(PdfName.URI, new PdfString(this.linkUrlString));
- linkAnnot.put(PdfName.A, a);
-
- PdfDictionary bs = new PdfDictionary();
- bs.put(PdfName.W, new PdfNumber(0));
- linkAnnot.put(PdfName.BS, bs);
- linkAnnot.put(PdfName.F, new PdfNumber(4));
-
- // iText "converts" 0.0f to an integer, therefore we cannot use 0, not nice...
- //linkAnnot.put(PdfName.RECT, new PdfArray(new float[] {0.01f, 0.01f, 0.01f, 0.01f}));
- // take cell pos as link pos
- linkAnnot.put(PdfName.RECT, new PdfArray(calcLinkPos(atp)));
-
- linkAnnot.put(PdfName.STRUCTPARENT, structParentNr);
- linkAnnot.put(PdfName.SUBTYPE, PdfName.LINK);
-
- return stamper.getWriter().addToBody(linkAnnot).getIndirectReference();
- }
-
-
- private PdfArray calcLinkPos(ActualTablePos atp) {
- PdfArray res = new PdfArray();
-
- float downY = atp.y - atp.height;
-
- float startX = atp.x + this.verifyLinkCellPos.getLeft();
- float yLine = getPosMapVal("yLine");
- float lineHigh = getPosMapVal("maxSize");
- float lineWidth = getPosMapVal("lineWidth");
- UrlInTextFinder finder = (UrlInTextFinder) this.linkPosMap.get("urlFinder");
-
- // maybe one could calc the link pos even more exactly with char width counting
- // but this should be close enough (see BidiLine.processLine and chunk.getcharwith)
- float lineCorr = -2;
- float xCorr = 5;
- res.add(new PdfNumber(1 + startX + finder.calcLinkPosXStart(lineWidth)));
- res.add(new PdfNumber(downY + yLine + lineHigh + lineCorr));
- res.add(new PdfNumber(xCorr + startX + finder.calcLinkPosXEnd(lineWidth)));
- res.add(new PdfNumber(downY + yLine + lineCorr));
-
- return res;
- }
-
- private float getPosMapVal(String key) {
- return ((Float) this.linkPosMap.get(key)).floatValue();
- }
-
- protected static PdfArray createPdfArrayFromTablePos(ActualTablePos pos) {
- return new PdfArray( new float[] {pos.x, pos.y, pos.x + pos.width, pos.y - pos.height});
- }
-
- private PdfArray obrainAnnotsFromPage() throws IOException {
- PdfArray annots = this.page.getAsArray(PdfName.ANNOTS);
- if (annots == null) {
- annots = new PdfArray();
- page.put(PdfName.ANNOTS, annots);
- stamperImp.markUsed(this.page);
- stamper.getWriter().addToBody(annots);
- }
- return annots;
- }
-
- private PdfArray obtainStructTreeRootKids(PdfDictionary structTreeRoot) {
- PdfArray rk = null;
- PdfObject root_k = structTreeRoot.getDirectObject(PdfName.K);
- stamperImp.markUsed(root_k);
- if (root_k instanceof PdfDictionary) {
- rk = new PdfArray();
- stamperImp.markUsed(structTreeRootKids);
- rk.add(root_k.getIndRef());
- structTreeRoot.put(PdfName.K, structTreeRootKids);
-
- } else if(root_k != null) { // has to be array
- rk = (PdfArray) root_k;
- }
- return rk;
- }
-
- private PdfArray obtainParentTreeEntry(PdfDictionary structTreeRoot, PdfArray parentTreeNums,
- PdfNumber structParentsNr, PdfTemplate sigBlockObj) {
- int numsIdx = -1;
- PdfArray parentTreeEntry = null;
-
- if (structParentsNr == null) { // no StructParents entry yet, make new one and add new parenttree entry
- PdfNumber parentTreeKey = null;
- parentTreeNextKey = structTreeRoot.getAsNumber(PARENTTREENEXTKEY); // read next proposed key
- if (parentTreeNextKey == null) { // this can be null if a non-perfect pdf creator was at work
- // find the next key by counting
- int nextI = ((int) parentTreeNums.size() / 2); // know the "Number Trees" data structure from pdf-ref
- this.parentTreeNextKey = new PdfNumber(nextI);
- structTreeRoot.put(PARENTTREENEXTKEY, this.parentTreeNextKey); // write ParentTreeNextKey entry
- }
-
- parentTreeKey = new PdfNumber(parentTreeNextKey.intValue());
- parentTreeNextKey.increment();
- page.put(PdfName.STRUCTPARENTS, parentTreeKey); // write /StructParents entry to page
- structParentsNr = parentTreeKey;
-
- stamperImp.markUsed(page);
- // create new entry in ParentTree
- parentTreeNums.add(parentTreeKey);
- parentTreeEntry = new PdfArray();
- numsIdx = parentTreeNums.size() - 1;
-
- } else { // structparents entry already available, find parenttree entry
- //parentTreeKey = structParentsNr;
- parentTreeNextKey = structTreeRoot.getAsNumber(PARENTTREENEXTKEY); // read next proposed key
- if (parentTreeNextKey == null) { // this can be null if a non-perfact pdf creator was at work
- // find the next key by counting
- int nextI = 0;
- if (parentTreeNums != null) {
- nextI = ((int) parentTreeNums.size() / 2);
- }
- this.parentTreeNextKey = new PdfNumber(nextI);
- structTreeRoot.put(PARENTTREENEXTKEY, this.parentTreeNextKey);
- }
- }
-
- // add Structparents entry to xobject content stream
- sigBlockObj.addAttribute(PdfName.STRUCTPARENTS, structParentsNr);
-
- // find my structParentEntry
- if (numsIdx < 0) {
- // it's a weird data structure: "number tree", see pdf reference if you really want to understand
-
- // if the array has no gaps it is easy:
- numsIdx = structParentsNr.intValue() * 2;
- if (parentTreeNums.getAsNumber(numsIdx).intValue() != structParentsNr.intValue()) { // there seem to be gaps
- for (numsIdx = 0; numsIdx < parentTreeNums.size(); numsIdx += 2) { // search manually
- if (parentTreeNums.getAsNumber(numsIdx).intValue() == structParentsNr.intValue()) {
- break;
- }
- }
- }
- numsIdx += 1;
- }
- if (parentTreeEntry == null) {
- parentTreeEntry = parentTreeNums.getAsArray(numsIdx);
- }
- return parentTreeEntry;
- }
-
-// private PdfIndirectReference createStructElem(String structType, PdfObject kid) throws IOException {
-// return createStructElem(structType, kid, null);
-// }
-
- private PdfIndirectReference createStructElem(String structType, PdfObject kid, PdfIndirectReference parentRef) throws IOException {
- return createStructElem(structType, kid, null, parentRef);
- }
-
- private PdfIndirectReference createStructElem(String structType, PdfObject kid, String altText,
- PdfIndirectReference parentRef) throws IOException {
-
- PdfDictionary newStruct = new PdfDictionary();
- newStruct.put(PdfName.S, new PdfName(structType));
- //newStruct.put(PdfName.T, new PdfString("PDF-AS Signaturblock"));// eher nicht
- if (parentRef != null) {
- newStruct.put(PdfName.P, parentRef);
- }
- newStruct.put(PdfName.TYPE, new PdfName("StructElem"));
-
- newStruct.put(PdfName.PG, page.getIndRef());
- if (altText != null) {
- newStruct.put(PdfName.ALT, new PdfString(altText));
- }
- // newStruct.put(PdfName.ALT, new PdfString(getAltText(so.getSignatureTypeDefinition().getType())));
- //newStruct.put(PdfName.K, new PdfNumber(nextMcid));
- newStruct.put(PdfName.K, kid);
-
- return stamper.getWriter().addToBody(newStruct).getIndirectReference();
- }
-
- private boolean isFigureMarked() {
- return this.figureMcid > -1;
- }
-
- private boolean isLinkMarked() {
- return this.linkMcid > -1;
- }
-
-
- private PdfNumber getNewParentTreeKey() {
- // new parent tree entry
- if (parentTreeNextKey == null) {
- parentTreeNextKey = getStructTreeRoot().getAsNumber(PARENTTREENEXTKEY); // read next proposed key
- }
- PdfNumber res = new PdfNumber(parentTreeNextKey.intValue());
- parentTreeNextKey.increment();
- return res;
- }
-
-
- private PdfIndirectReference createObjrStructElem(PdfIndirectReference objRef) throws IOException {
- PdfDictionary objr = new PdfDictionary();
- objr.put(PdfName.TYPE, new PdfName("OBJR"));
- objr.put(PdfName.PG, page.getIndRef());
- objr.put(new PdfName("Obj"), objRef);
-
- return stamper.getWriter().addToBody(objr).getIndirectReference();
- }
-
- private PdfIndirectReference createMcrStructElem(int mcid, PdfIndirectReference streamRef) throws IOException {
- PdfDictionary objr = new PdfDictionary();
- objr.put(PdfName.TYPE, new PdfName("MCR"));
- objr.put(PdfName.PG, page.getIndRef());
- objr.put(PdfName.MCID, new PdfNumber(mcid));
- objr.put(new PdfName("Stm"), streamRef);
-
- return stamper.getWriter().addToBody(objr).getIndirectReference();
- }
-
- private PdfArray getParentTreeNums() {
- return getStructTreeRoot().getAsDict(PdfName.PARENTTREE).getAsArray(PdfName.NUMS);
- }
-
- private PdfDictionary getStructTreeRoot() {
- return stamper.getReader().getCatalog().getAsDict(PdfName.STRUCTTREEROOT);
- }
-
- private static String getAltText(String sigProfile) {
- return AdobeSignatureHelper.getDefaultableConfigProperty(sigProfile, ALT_TEXT_CONF_KEY, ALT_TEXT_DEFAULT);
- }
-
-}