package it.stefanochizzolini.clown.samples; import it.stefanochizzolini.clown.documents.Document; import it.stefanochizzolini.clown.documents.Page; import it.stefanochizzolini.clown.documents.contents.composition.AlignmentXEnum; import it.stefanochizzolini.clown.documents.contents.composition.AlignmentYEnum; import it.stefanochizzolini.clown.documents.contents.composition.BlockFilter; import it.stefanochizzolini.clown.documents.contents.composition.PrimitiveFilter; import it.stefanochizzolini.clown.documents.contents.fonts.StandardType1Font; import it.stefanochizzolini.clown.documents.contents.xObjects.XObject; import it.stefanochizzolini.clown.files.File; import java.awt.Dimension; import java.awt.geom.Dimension2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; /** This sample demonstrates how to reuse a page as a form (precisely: form XObject [PDF:1.6:4.9]).

Remarks

Form XObjects are a convenient way to represent contents multiple times on multiple pages as templates.

@author Stefano Chizzolini (http://www.stefanochizzolini.it) @version 0.0.6 @since 0.0.5 */ public class PageToFormSample implements ISample { // // // // public void run( PDFClownSampleLoader loader ) { File formFile; { // (boilerplate user choice -- ignore it) String filePath = loader.getPdfFileChoice("Please select a PDF file to use as form"); // 1. Instantiate the form source file! try{formFile = new File(filePath);} catch(Exception e){throw new RuntimeException(filePath + " file access error.",e);} } // 2. Instantiate a new PDF file! /* NOTE: a File object is the low-level (syntactic) representation of a PDF file. */ File file = new File(); // Get its corresponding document! /* NOTE: a Document object is the high-level (semantic) representation of a PDF file. */ Document document = file.getDocument(); // 3. Convert the first page of the source file into a form inside the new document! XObject form = formFile.getDocument().getPages().get(0).toXObject(document); // 4. Insert the contents into the new document! populate(document,form); // (boilerplate metadata insertion -- ignore it) loader.buildAccessories(document,this.getClass(),"Page-to-form","converting a page to a reusable form"); // 5. Serialize the PDF file (again, boilerplate code -- see the PDFClownSampleLoader class source code)! loader.serialize(file,this.getClass().getSimpleName(),false); } // // // /** Populates a PDF file with contents. */ private void populate( Document document, XObject form ) { // 1. Add a page to the document! Page page = new Page(document); // Instantiates the page inside the document context. document.getPages().add(page); // Puts the page in the pages collection. // 2. Create a content builder for the content stream! PrimitiveFilter builder = new PrimitiveFilter(page); // 3. Inserting contents... Dimension2D pageSize = page.getSize(); // 3.1. Showing the form on the page... { // Form 1. builder.showXObject( form, new Point2D.Double(pageSize.getWidth()/2,pageSize.getHeight()/2), new Dimension(300,0), AlignmentXEnum.Center, AlignmentYEnum.Middle, 45 ); // Form 2. builder.showXObject( form, new Point2D.Double(0,pageSize.getHeight()), new Dimension(0,300), AlignmentXEnum.Left, AlignmentYEnum.Bottom, 0 ); // Form 3. builder.showXObject( form, new Point2D.Double(pageSize.getWidth(),pageSize.getHeight()), new Dimension(80,200), AlignmentXEnum.Right, AlignmentYEnum.Bottom, 0 ); } // 3.2. Showing the comments on the page... { BlockFilter blockFilter = new BlockFilter(builder); blockFilter.begin( new Rectangle2D.Double( 18, 18, pageSize.getWidth() * .5, pageSize.getHeight() * .5 ), AlignmentXEnum.Justify, AlignmentYEnum.Top ); StandardType1Font bodyFont = new StandardType1Font( document, StandardType1Font.FamilyNameEnum.Courier, true, false ); builder.setFont(bodyFont,24); blockFilter.showText("Page-to-form sample"); Dimension2D breakSize = new Dimension(0,8); blockFilter.showBreak(breakSize); builder.setFont(bodyFont,8); blockFilter.showText("This sample shows how to convert a page to a reusable form that can be placed multiple times on other pages scaling, rotating, anchoring and aligning it."); blockFilter.showBreak(breakSize); blockFilter.showText("On this page you can see some of the above-mentioned transformations:"); breakSize.setSize(8,8); blockFilter.showBreak(breakSize); blockFilter.showText("1. anchored to the center of the page, rotated by 45 degrees counterclockwise, 300 point wide (preserved proportions);"); blockFilter.showBreak(breakSize); blockFilter.showText("2. anchored to the bottom-left corner of the page, 300 point high (preserved proportions);"); blockFilter.showBreak(breakSize); blockFilter.showText("3. anchored to the bottom-right corner of the page, 80 point wide and 200 point high (altered proportions)."); blockFilter.end(); } // 4. Flush the contents into the content stream! builder.flush(); } // // // }