From 535a04fa05f739ec16dd81666e3b0f82dfbd442d Mon Sep 17 00:00:00 2001 From: tknall Date: Wed, 9 Jan 2013 15:41:29 +0000 Subject: 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 --- .../wag/egov/egiz/pdf/StructContentHelper.java | 716 --------------------- 1 file changed, 716 deletions(-) delete mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/pdf/StructContentHelper.java (limited to 'src/main/java/at/knowcenter/wag/egov/egiz/pdf/StructContentHelper.java') 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 2006 by Know-Center, Graz, Austria - * 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.
- * See pdf spec "Logical Structure" for details.
- * 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 StructTreeRoot - */ - 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.
- * 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(" <> 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 <> 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 <> 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); - } - -} -- cgit v1.2.3