diff options
Diffstat (limited to 'pdf-as-lib')
5 files changed, 872 insertions, 33 deletions
| diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java index 93c19fe5..651c2e49 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java @@ -111,7 +111,16 @@ public class PADESPDFBOXSigner implements IPdfSigner {              PDFAsVisualSignatureProperties properties = new PDFAsVisualSignatureProperties(              		pdfObject.getStatus().getSettings(), pdfObject);              properties.buildSignature(); -            options.setVisualSignature(properties.getVisibleSignature()); +             +            ByteArrayOutputStream sigbos = new ByteArrayOutputStream(); +            sigbos.write(StreamUtils.inputStreamToByteArray(properties.getVisibleSignature())); +            sigbos.close(); +             +            FileOutputStream fos2 = new FileOutputStream("/tmp/apsig.pdf"); +            fos2.write(sigbos.toByteArray()); +            fos2.close(); +             +            options.setVisualSignature(new ByteArrayInputStream(sigbos.toByteArray()));              doc.addSignature(signature, signer, options); diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsTemplateCreator.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsTemplateCreator.java new file mode 100644 index 00000000..e952ea73 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsTemplateCreator.java @@ -0,0 +1,140 @@ +package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; + +import java.awt.geom.AffineTransform; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.pdfbox.exceptions.COSVisitorException; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDResources; +import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.apache.pdfbox.pdmodel.common.PDStream; +import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectForm; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDFTemplateBuilder; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDFTemplateCreator; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDFTemplateStructure; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSignDesigner; +import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; +import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PDFAsTemplateCreator extends PDFTemplateCreator { + +	PDFAsVisualSignatureBuilder pdfBuilder; +    private static final Logger logger = LoggerFactory.getLogger(PDFAsTemplateCreator.class); +	 +	public PDFAsTemplateCreator(PDFAsVisualSignatureBuilder bookBuilder) { +		super(bookBuilder); +		this.pdfBuilder = bookBuilder; +	} + +	 +	public InputStream buildPDF(PDFAsVisualSignatureDesigner properties) +			throws IOException { +		logger.info("pdf building has been started"); +        PDFTemplateStructure pdfStructure = pdfBuilder.getStructure(); + +        // we create array of [Text, ImageB, ImageC, ImageI] +        this.pdfBuilder.createProcSetArray(); +         +        //create page +        this.pdfBuilder.createPage(properties); +        PDPage page = pdfStructure.getPage(); + +        //create template +        this.pdfBuilder.createTemplate(page); +        PDDocument template = pdfStructure.getTemplate(); +         +        //create /AcroForm +        this.pdfBuilder.createAcroForm(template); +        PDAcroForm acroForm = pdfStructure.getAcroForm(); + +        // AcroForm contains singature fields +        this.pdfBuilder.createSignatureField(acroForm); +        PDSignatureField pdSignatureField = pdfStructure.getSignatureField(); +         +        // create signature +        this.pdfBuilder.createSignature(pdSignatureField, page, properties.getSignatureFieldName()); +        +        // that is /AcroForm/DR entry +        this.pdfBuilder.createAcroFormDictionary(acroForm, pdSignatureField); +         +        // create AffineTransform +        this.pdfBuilder.createAffineTransform(properties.getAffineTransformParams()); +        AffineTransform transform = pdfStructure.getAffineTransform(); +        +        // rectangle, formatter, image. /AcroForm/DR/XObject contains that form +        this.pdfBuilder.createSignatureRectangle(pdSignatureField, properties); +        this.pdfBuilder.createFormaterRectangle(properties.getFormaterRectangleParams()); +        PDRectangle formater = pdfStructure.getFormaterRectangle(); +         +        //this.pdfBuilder.createSignatureImage(template, properties.getImageStream()); + +        // create form stream, form and  resource.  +        this.pdfBuilder.createHolderFormStream(template); +        PDStream holderFormStream = pdfStructure.getHolderFormStream(); +        this.pdfBuilder.createHolderFormResources(); +        PDResources holderFormResources = pdfStructure.getHolderFormResources(); +        this.pdfBuilder.createHolderForm(holderFormResources, holderFormStream, formater); +         +        // that is /AP entry the appearance dictionary. +        this.pdfBuilder.createAppearanceDictionary(pdfStructure.getHolderForm(), pdSignatureField); +         +        // inner formstream, form and resource (hlder form containts inner form) +        this.pdfBuilder.createInnerFormStream(template); +        this.pdfBuilder.createInnerFormResource(); +        PDResources innerFormResource = pdfStructure.getInnerFormResources(); +        this.pdfBuilder.createInnerForm(innerFormResource, pdfStructure.getInnterFormStream(), formater); +        PDXObjectForm innerForm = pdfStructure.getInnerForm(); +        +        // inner form must be in the holder form as we wrote +        this.pdfBuilder.insertInnerFormToHolerResources(innerForm, holderFormResources); +         +        //  Image form is in this structure: /AcroForm/DR/FRM0/Resources/XObject/n0 +        //this.pdfBuilder.createImageFormStream(template); +        //PDStream imageFormStream = pdfStructure.getImageFormStream(); +        //this.pdfBuilder.createImageFormResources(); +        //PDResources imageFormResources = pdfStructure.getImageFormResources(); +        //this.pdfBuilder.createImageForm(imageFormResources, innerFormResource, imageFormStream, formater, transform, +        //        pdfStructure.getJpedImage()); +        +        // now inject procSetArray +        /*this.pdfBuilder.injectProcSetArray(innerForm, page, innerFormResource, imageFormResources, holderFormResources, +                pdfStructure.getProcSet());*/ +        this.pdfBuilder.injectProcSetArray(innerForm, page, innerFormResource, null, holderFormResources, +                pdfStructure.getProcSet()); +         + +        /*String imgFormName = pdfStructure.getImageFormName(); +        String imgName = pdfStructure.getImageName();*/ +        String innerFormName = pdfStructure.getInnerFormName(); + +        // now create Streams of AP +        /*this.pdfBuilder.injectAppearanceStreams(holderFormStream, imageFormStream, imageFormStream, imgFormName, +                imgName, innerFormName, properties);*/ +        this.pdfBuilder.injectAppearanceStreams(holderFormStream, null, null, null, +        		null, innerFormName, properties); +        this.pdfBuilder.createVisualSignature(template); +        this.pdfBuilder.createWidgetDictionary(pdSignatureField, holderFormResources); +         +        ByteArrayInputStream in = null; +        try +        { +            in = pdfStructure.getTemplateAppearanceStream(); +        } +        catch (COSVisitorException e) +        { +            logger.error("COSVisitorException: can't get apereance stream ", e); +        } +        logger.info("stream returning started, size= " + in.available()); +         +        // we must close the document +        template.close(); +         +        // return result of the stream  +        return in; +	} +} 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 496bc0d8..cd4abdf9 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 @@ -1,16 +1,33 @@  package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; +import java.awt.geom.AffineTransform;  import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream;  import java.util.ArrayList; +import java.util.List; +import org.apache.pdfbox.cos.COSArray; +import org.apache.pdfbox.cos.COSDictionary;  import org.apache.pdfbox.cos.COSName;  import org.apache.pdfbox.pdmodel.PDDocument;  import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDResources; +import org.apache.pdfbox.pdmodel.common.PDRectangle;  import org.apache.pdfbox.pdmodel.common.PDStream;  import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;  import org.apache.pdfbox.pdmodel.font.PDType1Font; +import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg; +import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectForm; +import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary; +import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDFTemplateStructure;  import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSigBuilder;  import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSignDesigner; +import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; +import org.apache.pdfbox.pdmodel.interactive.form.PDField; +import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory; @@ -120,6 +137,15 @@ public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder {  	}  	@Override +	public void createProcSetArray() { +		COSArray procSetArr = new COSArray(); +		procSetArr.add(COSName.getPDFName("PDF")); +		procSetArr.add(COSName.getPDFName("Text")); +		getStructure().setProcSet(procSetArr); +		logger.info("ProcSet array has been created"); +	} + +	@Override  	public void createTemplate(PDPage page) throws IOException {  		PDDocument template = new PDDocument(); @@ -144,30 +170,299 @@ public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder {  			e.printStackTrace();  		}  	} + +	@Override +	public void injectProcSetArray(PDXObjectForm innerForm, PDPage page, +			PDResources innerFormResources, PDResources imageFormResources, +			PDResources holderFormResources, COSArray procSet) { +		innerForm.getResources().getCOSDictionary() +				.setItem(COSName.PROC_SET, procSet); // +		page.getCOSDictionary().setItem(COSName.PROC_SET, procSet); +		innerFormResources.getCOSDictionary() +				.setItem(COSName.PROC_SET, procSet); +		/*imageFormResources.getCOSDictionary() +				.setItem(COSName.PROC_SET, procSet);*/ +		holderFormResources.getCOSDictionary().setItem(COSName.PROC_SET, +				procSet); +		logger.info("inserted ProcSet to PDF"); +	} + +	public void injectAppearanceStreams(PDStream holderFormStream, +			PDStream innterFormStream, PDStream imageFormStream, +			String imageObjectName, String imageName, String innerFormName, +			PDFAsVisualSignatureDesigner properties) throws IOException { + +		// 100 means that document width is 100% via the rectangle. if rectangle +		// is 500px, images 100% is 500px. +		// String imgFormComment = "q "+imageWidthSize+ " 0 0 50 0 0 cm /" + +		// imageName + " Do Q\n" + builder.toString(); +		/*String imgFormComment = "q " + 100 + " 0 0 50 0 0 cm /" + imageName +				+ " Do Q\n";*/ +		String holderFormComment = "q 1 0 0 1 0 0 cm /" + innerFormName +				+ " Do Q \n"; +		// String innerFormComment = "q 1 0 0 1 0 0 cm /" + imageObjectName + +		// " Do Q\n"; +		String innerFormComment = getStructure().getInnterFormStream() +				.getInputStreamAsString(); + +		logger.info("Inner Form Stream: " + innerFormComment); + +		// appendRawCommands(getStructure().getInnterFormStream().createOutputStream(), +		// getStructure().getInnterFormStream().getInputStreamAsString()); + +		appendRawCommands(getStructure().getHolderFormStream() +				.createOutputStream(), holderFormComment); +		appendRawCommands(getStructure().getInnterFormStream() +				.createOutputStream(), innerFormComment); +		// appendRawCommands(getStructure().getImageFormStream().createOutputStream(), +		// imgFormComment); +		logger.info("Injected apereance stream to pdf"); + +	} +	 +	public void createPage(PDFAsVisualSignatureDesigner properties) +    { +        PDPage page = new PDPage(); +        page.setMediaBox(new PDRectangle(properties.getPageWidth(), properties.getPageHeight())); +        getStructure().setPage(page); +        logger.info("PDF page has been created"); +    } + +    public void createAcroForm(PDDocument template) +    { +        PDAcroForm theAcroForm = new PDAcroForm(template); +        template.getDocumentCatalog().setAcroForm(theAcroForm); +        getStructure().setAcroForm(theAcroForm); +        logger.info("Acro form page has been created"); + +    } + +    public void createSignatureField(PDAcroForm acroForm) throws IOException +    { +        PDSignatureField sf = new PDSignatureField(acroForm); +        getStructure().setSignatureField(sf); +        logger.info("Signature field has been created"); +    } + +    public void createSignature(PDSignatureField pdSignatureField, PDPage page, String signatureName) +            throws IOException +    { +        PDSignature pdSignature = new PDSignature(); +        pdSignatureField.setSignature(pdSignature); +        pdSignatureField.getWidget().setPage(page); +        page.getAnnotations().add(pdSignatureField.getWidget()); +        pdSignature.setName(signatureName); +        pdSignature.setByteRange(new int[] { 0, 0, 0, 0 }); +        pdSignature.setContents(new byte[4096]); +        getStructure().setPdSignature(pdSignature); +        logger.info("PDSignatur has been created"); +    } + +    public void createAcroFormDictionary(PDAcroForm acroForm, PDSignatureField signatureField) throws IOException +    { +        @SuppressWarnings("unchecked") +        List<PDField> acroFormFields = acroForm.getFields(); +        COSDictionary acroFormDict = acroForm.getDictionary(); +        acroFormDict.setDirect(true); +        acroFormDict.setInt(COSName.SIG_FLAGS, 3); +        acroFormFields.add(signatureField); +        acroFormDict.setString(COSName.DA, "/sylfaen 0 Tf 0 g"); +        getStructure().setAcroFormFields(acroFormFields); +        getStructure().setAcroFormDictionary(acroFormDict); +        logger.info("AcroForm dictionary has been created"); +    } + +    public void createSignatureRectangle(PDSignatureField signatureField, PDFAsVisualSignatureDesigner properties) +            throws IOException +    { + +        PDRectangle rect = new PDRectangle(); +        rect.setUpperRightX(properties.getxAxis() + properties.getWidth()); +        rect.setUpperRightY(properties.getPageHeight() - properties.getyAxis()); +        rect.setLowerLeftY(properties.getPageHeight() - properties.getyAxis() - properties.getHeight()); +        rect.setLowerLeftX(properties.getxAxis()); +        signatureField.getWidget().setRectangle(rect); +        getStructure().setSignatureRectangle(rect); +        logger.info("rectangle of signature has been created"); +    } + +    public void createAffineTransform(byte[] params) +    { +        AffineTransform transform = new AffineTransform(params[0], params[1], params[2], params[3], params[4], +                params[5]); +        getStructure().setAffineTransform(transform); +        logger.info("Matrix has been added"); +    } + +    public void createSignatureImage(PDDocument template, InputStream inputStream) throws IOException +    { +        PDJpeg img = new PDJpeg(template, inputStream); +        getStructure().setJpedImage(img); +        logger.info("Visible Signature Image has been created"); +        // pdfStructure.setTemplate(template); +        inputStream.close(); + +    } + +    public void createFormaterRectangle(byte[] params) +    { + +        PDRectangle formrect = new PDRectangle(); +        formrect.setUpperRightX(params[0]); +        formrect.setUpperRightY(params[1]); +        formrect.setLowerLeftX(params[2]); +        formrect.setLowerLeftY(params[3]); + +        getStructure().setFormaterRectangle(formrect); +        logger.info("Formater rectangle has been created"); + +    } + +    public void createHolderFormStream(PDDocument template) +    { +        PDStream holderForm = new PDStream(template); +        getStructure().setHolderFormStream(holderForm); +        logger.info("Holder form Stream has been created"); +    } + +    public void createHolderFormResources() +    { +        PDResources holderFormResources = new PDResources(); +        getStructure().setHolderFormResources(holderFormResources); +        logger.info("Holder form resources have been created"); + +    } + +    public void createHolderForm(PDResources holderFormResources, PDStream holderFormStream, PDRectangle formrect) +    { + +        PDXObjectForm holderForm = new PDXObjectForm(holderFormStream); +        holderForm.setResources(holderFormResources); +        holderForm.setBBox(formrect); +        holderForm.setFormType(1); +        getStructure().setHolderForm(holderForm); +        logger.info("Holder form has been created"); + +    } + +    public void createAppearanceDictionary(PDXObjectForm holderForml, PDSignatureField signatureField) +            throws IOException +    { + +        PDAppearanceDictionary appearance = new PDAppearanceDictionary(); +        appearance.getCOSObject().setDirect(true); + +        PDAppearanceStream appearanceStream = new PDAppearanceStream(holderForml.getCOSStream()); + +        appearance.setNormalAppearance(appearanceStream); +        signatureField.getWidget().setAppearance(appearance); + +        getStructure().setAppearanceDictionary(appearance); +        logger.info("PDF appereance Dictionary has been created"); + +    } + +    public void createInnerFormResource() +    { +        PDResources innerFormResources = new PDResources(); +        getStructure().setInnerFormResources(innerFormResources); +        logger.info("Resources of another form (inner form - it would be inside holder form) have been created"); +    } + +    public void createInnerForm(PDResources innerFormResources, PDStream innerFormStream, PDRectangle formrect) +    { +        PDXObjectForm innerForm = new PDXObjectForm(innerFormStream); +        innerForm.setResources(innerFormResources); +        innerForm.setBBox(formrect); +        innerForm.setFormType(1); +        getStructure().setInnerForm(innerForm); +        logger.info("Another form (inner form - it would be inside holder form) have been created"); + +    } + +    public void insertInnerFormToHolerResources(PDXObjectForm innerForm, PDResources holderFormResources) +    { +        String name = holderFormResources.addXObject(innerForm, "FRM"); +        getStructure().setInnerFormName(name); +        logger.info("Alerady inserted inner form  inside holder form"); +    } + +    public void createImageFormStream(PDDocument template) +    { +        PDStream imageFormStream = new PDStream(template); +        getStructure().setImageFormStream(imageFormStream); +        logger.info("Created image form Stream"); + +    } + +    public void createImageFormResources() +    { +        PDResources imageFormResources = new PDResources(); +        getStructure().setImageFormResources(imageFormResources); +        logger.info("Created image form Resources"); +    } + +    public void createImageForm(PDResources imageFormResources, PDResources innerFormResource, +            PDStream imageFormStream, PDRectangle formrect, AffineTransform affineTransform, PDJpeg img) +            throws IOException +    { + +        /* +         * if you need text on the visible signature  +         *  +         * PDFont font = PDTrueTypeFont.loadTTF(this.pdfStructure.getTemplate(), new File("D:\\arial.ttf"));  +         * font.setFontEncoding(new WinAnsiEncoding()); +         *  +         * Map<String, PDFont> fonts = new HashMap<String, PDFont>(); fonts.put("arial", font); +         */ +        PDXObjectForm imageForm = new PDXObjectForm(imageFormStream); +        imageForm.setBBox(formrect); +        imageForm.setMatrix(affineTransform); +        imageForm.setResources(imageFormResources); +        imageForm.setFormType(1); +        /* +         * imageForm.getResources().addFont(font);  +         * imageForm.getResources().setFonts(fonts); +         */ + +        imageFormResources.getCOSObject().setDirect(true); +        String imageFormName = innerFormResource.addXObject(imageForm, "n"); +        String imageName = imageFormResources.addXObject(img, "img"); +        this.getStructure().setImageForm(imageForm); +        this.getStructure().setImageFormName(imageFormName); +        this.getStructure().setImageName(imageName); +        logger.info("Created image form"); +    } + +    public void appendRawCommands(OutputStream os, String commands) throws IOException +    { +        os.write(commands.getBytes("UTF-8")); +        os.close(); +    } + +    public void createVisualSignature(PDDocument template) +    { +        this.getStructure().setVisualSignature(template.getDocument()); +        logger.info("Visible signature has been created"); + +    } + +    public void createWidgetDictionary(PDSignatureField signatureField, PDResources holderFormResources) +            throws IOException +    { + +        COSDictionary widgetDict = signatureField.getWidget().getDictionary(); +        widgetDict.setNeedToBeUpdate(true); +        widgetDict.setItem(COSName.DR, holderFormResources.getCOSObject()); + +        getStructure().setWidgetDictionary(widgetDict); +        logger.info("WidgetDictionary has been crated"); +    } + +    public void closeTemplate(PDDocument template) throws IOException +    { +        template.close(); +        this.getStructure().getTemplate().close(); +    } -	   @Override -	    public void injectAppearanceStreams(PDStream holderFormStream, PDStream innterFormStream, PDStream imageFormStream, -	            String imageObjectName, String imageName, String innerFormName, PDVisibleSignDesigner properties) -	            throws IOException -	    { - -	        // 100 means that document width is 100% via the rectangle. if rectangle -	        // is 500px, images 100% is 500px. -	        // String imgFormComment = "q "+imageWidthSize+ " 0 0 50 0 0 cm /" + -	        // imageName + " Do Q\n" + builder.toString(); -	        String imgFormComment = "q " + 100 + " 0 0 50 0 0 cm /" + imageName + " Do Q\n"; -	        String holderFormComment = "q 1 0 0 1 0 0 cm /" + innerFormName + " Do Q \n"; -	        String innerFormComment = "q 1 0 0 1 0 0 cm /" + imageObjectName + " Do Q\n"; - -	        logger.info("Holder Stream: " + getStructure().getInnterFormStream().getInputStreamAsString()); -	         -	        //appendRawCommands(getStructure().getInnterFormStream().createOutputStream(),  -	        //		getStructure().getInnterFormStream().getInputStreamAsString()); -	         -	        appendRawCommands(getStructure().getHolderFormStream().createOutputStream(), holderFormComment); -	        appendRawCommands(getStructure().getInnterFormStream().createOutputStream(), getStructure().getInnterFormStream().getInputStreamAsString()); -	        appendRawCommands(getStructure().getImageFormStream().createOutputStream(), imgFormComment); -	        logger.info("Injected apereance stream to pdf"); - -	    }  } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureDesigner.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureDesigner.java new file mode 100644 index 00000000..5ad36c62 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureDesigner.java @@ -0,0 +1,392 @@ +package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; + +import javax.imageio.ImageIO; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSignDesigner; + +public class PDFAsVisualSignatureDesigner { + +	private Float sigImgWidth; +	private Float sigImgHeight; +	private float xAxis; +	private float yAxis; +	private float pageHeight; +	private float pageWidth; +	private InputStream imgageStream; +	private String signatureFieldName = "sig"; // default +	private byte[] formaterRectangleParams = { 0, 0, 100, 50 }; // default +	private byte[] AffineTransformParams = { 1, 0, 0, 1, 0, 0 }; // default +	private float imageSizeInPercents; +	private PDDocument document = null; + +	/** +	 *  +	 * @param doc +	 *            - Already created PDDocument of your PDF document +	 * @param imageStream +	 * @param page +	 * @throws IOException +	 *             - If we can't read, flush, or can't close stream +	 */ +	public PDFAsVisualSignatureDesigner(PDDocument doc,  +			int page) throws IOException { +		calculatePageSize(doc, page); +	} + +	/** +	 * Each page of document can be different sizes. +	 *  +	 * @param document +	 * @param page +	 */ +	private void calculatePageSize(PDDocument document, int page) { + +		if (page < 1) { +			throw new IllegalArgumentException("First page of pdf is 1, not " +					+ page); +		} + +		List<?> pages = document.getDocumentCatalog().getAllPages(); +		PDPage firstPage = (PDPage) pages.get(page - 1); +		PDRectangle mediaBox = firstPage.findMediaBox(); +		this.pageHeight(mediaBox.getHeight()); +		this.pageWidth = mediaBox.getWidth(); + +		float x = this.pageWidth; +		float y = 0; +		this.pageWidth = this.pageWidth + y; +		float tPercent = (100 * y / (x + y)); +		this.imageSizeInPercents = 100 - tPercent; + +	} + +	/** +	 *  +	 * @param path +	 *            of image location +	 * @return image Stream +	 * @throws IOException +	 */ +	public PDFAsVisualSignatureDesigner signatureImage(String path) throws IOException { +		InputStream fin = new FileInputStream(path); +		return signatureImageStream(fin); +	} + +	/** +	 * zoom signature image with some percent. +	 *  +	 * @param percent +	 *            - x % increase image with x percent. +	 * @return Visible Signature Configuration Object +	 */ +	public PDFAsVisualSignatureDesigner zoom(float percent) { +		sigImgHeight = sigImgHeight + (sigImgHeight * percent) / 100; +		sigImgWidth = sigImgWidth + (sigImgWidth * percent) / 100; +		return this; +	} + +	/** +	 *  +	 * @param xAxis +	 *            - x coordinate +	 * @param yAxis +	 *            - y coordinate +	 * @return Visible Signature Configuration Object +	 */ +	public PDFAsVisualSignatureDesigner coordinates(float x, float y) { +		xAxis(x); +		yAxis(y); +		return this; +	} + +	/** +	 *  +	 * @return xAxis - gets x coordinates +	 */ +	public float getxAxis() { +		return xAxis; +	} + +	/** +	 *  +	 * @param xAxis +	 *            - x coordinate +	 * @return Visible Signature Configuration Object +	 */ +	public PDFAsVisualSignatureDesigner xAxis(float xAxis) { +		this.xAxis = xAxis; +		return this; +	} + +	/** +	 *  +	 * @return yAxis +	 */ +	public float getyAxis() { +		return yAxis; +	} + +	/** +	 *  +	 * @param yAxis +	 * @return Visible Signature Configuration Object +	 */ +	public PDFAsVisualSignatureDesigner yAxis(float yAxis) { +		this.yAxis = yAxis; +		return this; +	} + +	/** +	 *  +	 * @return signature image width +	 */ +	public float getWidth() { +		return 400; +	} + +	/** +	 *  +	 * @param sets +	 *            signature image width +	 * @return Visible Signature Configuration Object +	 */ +	public PDFAsVisualSignatureDesigner width(float signatureImgWidth) { +		this.sigImgWidth = signatureImgWidth; +		return this; +	} + +	/** +	 *  +	 * @return signature image height +	 */ +	public float getHeight() { +		return 300; +	} + +	/** +	 *  +	 * @param set +	 *            signature image Height +	 * @return Visible Signature Configuration Object +	 */ +	public PDFAsVisualSignatureDesigner height(float signatureImgHeight) { +		this.sigImgHeight = signatureImgHeight; +		return this; +	} + +	/** +	 *  +	 * @return template height +	 */ +	protected float getTemplateHeight() { +		return getPageHeight(); +	} + +	/** +	 *  +	 * @param templateHeight +	 * @return Visible Signature Configuration Object +	 */ +	private PDFAsVisualSignatureDesigner pageHeight(float templateHeight) { +		this.pageHeight = templateHeight; +		return this; +	} + +	/** +	 *  +	 * @return signature field name +	 */ +	public String getSignatureFieldName() { +		return signatureFieldName; +	} + +	/** +	 *  +	 * @param signatureFieldName +	 * @return Visible Signature Configuration Object +	 */ +	public PDFAsVisualSignatureDesigner signatureFieldName(String signatureFieldName) { +		this.signatureFieldName = signatureFieldName; +		return this; +	} + +	/** +	 *  +	 * @return image Stream +	 */ +	public InputStream getImageStream() { +		return imgageStream; +	} + +	/** +	 *  +	 * @param imgageStream +	 *            - stream of your visible signature image +	 * @return Visible Signature Configuration Object +	 * @throws IOException +	 *             - If we can't read, flush, or close stream of image +	 */ +	private PDFAsVisualSignatureDesigner signatureImageStream(InputStream imageStream) +			throws IOException { + +		ByteArrayOutputStream baos = new ByteArrayOutputStream(); +		byte[] buffer = new byte[1024]; +		int len; +		while ((len = imageStream.read(buffer)) > -1) { +			baos.write(buffer, 0, len); +		} +		baos.flush(); +		baos.close(); + +		byte[] byteArray = baos.toByteArray(); +		byte[] byteArraySecond = byteArray.clone(); + +		InputStream inputForBufferedImage = new ByteArrayInputStream(byteArray); +		InputStream revertInputStream = new ByteArrayInputStream( +				byteArraySecond); + +		if (sigImgHeight == null || sigImgWidth == null) { +			calcualteImageSize(inputForBufferedImage); +		} + +		this.imgageStream = revertInputStream; + +		return this; +	} + +	/** +	 * calculates image width and height. sported formats: all +	 *  +	 * @param fis +	 *            - input stream of image +	 * @throws IOException +	 *             - if can't read input stream +	 */ +	private void calcualteImageSize(InputStream fis) throws IOException { + +		BufferedImage bimg = ImageIO.read(fis); +		int width = bimg.getWidth(); +		int height = bimg.getHeight(); + +		sigImgHeight = (float) height; +		sigImgWidth = (float) width; + +	} + +	/** +	 *  +	 * @return Affine Transform parameters of for PDF Matrix +	 */ +	public byte[] getAffineTransformParams() { +		return AffineTransformParams; +	} + +	/** +	 *  +	 * @param affineTransformParams +	 * @return Visible Signature Configuration Object +	 */ +	public PDFAsVisualSignatureDesigner affineTransformParams( +			byte[] affineTransformParams) { +		AffineTransformParams = affineTransformParams; +		return this; +	} + +	/** +	 *  +	 * @return formatter PDRectanle parameters +	 */ +	public byte[] getFormaterRectangleParams() { +		return formaterRectangleParams; +	} + +	/** +	 * sets formatter PDRectangle; +	 *  +	 * @param formaterRectangleParams +	 * @return Visible Signature Configuration Object +	 */ +	public PDFAsVisualSignatureDesigner formaterRectangleParams( +			byte[] formaterRectangleParams) { +		this.formaterRectangleParams = formaterRectangleParams; +		return this; +	} + +	/** +	 *  +	 * @return page width +	 */ +	public float getPageWidth() { +		return pageWidth; +	} + +	/** +	 *  +	 * @param sets +	 *            pageWidth +	 * @return Visible Signature Configuration Object +	 */ +	public PDFAsVisualSignatureDesigner pageWidth(float pageWidth) { +		this.pageWidth = pageWidth; +		return this; +	} + +	/** +	 *  +	 * @return page height +	 */ +	public float getPageHeight() { +		return pageHeight; +	} + +	/** +	 * get image size in percents +	 *  +	 * @return +	 */ +	public float getImageSizeInPercents() { +		return imageSizeInPercents; +	} + +	/** +	 *  +	 * @param imageSizeInPercents +	 */ +	public void imageSizeInPercents(float imageSizeInPercents) { +		this.imageSizeInPercents = imageSizeInPercents; +	} + +	/** +	 * returns visible signature text +	 *  +	 * @return +	 */ +	public String getSignatureText() { +		throw new UnsupportedOperationException( +				"That method is not yet implemented"); +	} + +	/** +	 *  +	 * @param signatureText +	 *            - adds the text on visible signature +	 * @return +	 */ +	public PDFAsVisualSignatureDesigner signatureText(String signatureText) { +		throw new UnsupportedOperationException( +				"That method is not yet implemented"); +	} + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java index a3d02db2..055f035d 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java @@ -24,6 +24,8 @@ public class PDFAsVisualSignatureProperties extends PDVisibleSigProperties {  	private ISettings settings;  	private Table main; +	 +	private PDFAsVisualSignatureDesigner designer;  	public PDFAsVisualSignatureProperties(ISettings settings, PDFObject object) {  		this.settings = settings; @@ -32,7 +34,7 @@ public class PDFAsVisualSignatureProperties extends PDVisibleSigProperties {  					.createProfile("SIGNATURBLOCK_DE", settings);  			X509Certificate cert = new X509Certificate(new FileInputStream( -					"/home/afitzek/qualified.cer")); +					"/home/andy/certificates/test.crt"));  			CertificateHolderRequest request = new CertificateHolderRequest(  					cert); @@ -47,10 +49,10 @@ public class PDFAsVisualSignatureProperties extends PDVisibleSigProperties {  		try {  			PDDocument origDoc = PDDocument.load(new ByteArrayInputStream(  					object.getStampedDocument())); -			PDVisibleSignDesigner designer = new PDVisibleSignDesigner(origDoc, -					new FileInputStream("/home/afitzek/.pdfas/images/signatur-logo_de.png"), 1); -			this.setPdVisibleSignature(designer); +			designer = new PDFAsVisualSignatureDesigner(origDoc, 1); +			 +			//this.setPdVisibleSignature(designer);  		} catch (Throwable e) {  			e.printStackTrace();  		} @@ -58,13 +60,14 @@ public class PDFAsVisualSignatureProperties extends PDVisibleSigProperties {  	@Override  	public void buildSignature() throws IOException { -		PDFTemplateBuilder builder = new PDFAsVisualSignatureBuilder(this); -		PDFTemplateCreator creator = new PDFTemplateCreator(builder); -		setVisibleSignature(creator.buildPDF(getPdVisibleSignature())); +		PDFAsVisualSignatureBuilder builder = new PDFAsVisualSignatureBuilder(this); +		PDFAsTemplateCreator creator = new PDFAsTemplateCreator(builder); +		setVisibleSignature(creator.buildPDF(designer));  	}  	public Table getMainTable() {  		return main;  	} +	  } | 
