package it.stefanochizzolini.clown.samples; import it.stefanochizzolini.clown.documents.Document; import it.stefanochizzolini.clown.documents.Page; import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceRGBColor; import it.stefanochizzolini.clown.documents.contents.composition.AlignmentXEnum; import it.stefanochizzolini.clown.documents.contents.composition.AlignmentYEnum; import it.stefanochizzolini.clown.documents.contents.composition.PrimitiveFilter; import it.stefanochizzolini.clown.documents.contents.fonts.StandardType1Font; import it.stefanochizzolini.clown.documents.contents.xObjects.FormXObject; import it.stefanochizzolini.clown.files.File; import it.stefanochizzolini.clown.tools.PageStamper; import java.awt.geom.Dimension2D; import java.awt.geom.Point2D; /** This sample demonstrates how to insert watermark text into an existing document.
This implementation uses a Form XObject [PDF:1.6:4.9] to conveniently achieve a consistent page background. Form XObjects provide context independence encapsulating their contents (and resources) in a single stream: such an approach allows content reuse.
The watermark is seamlessly inserted under each page content using the PageStamper class.
@author Stefano Chizzolini (http://www.stefanochizzolini.it) @version 0.0.6 */ public class WatermarkSample implements ISample { public void run( PDFClownSampleLoader loader ) { File file; { // (boilerplate user choice -- ignore it) String filePath = loader.getPdfFileChoice("Please select a PDF file"); // 1. Open the PDF file! try{file = new File(filePath);} catch(Exception e){throw new RuntimeException(filePath + " file access error.",e);} } // Get the PDF document! Document document = file.getDocument(); // 2. Create a watermark (form)! FormXObject watermark = createWatermark(document); // 3. Apply the watermark to the pages of the document! applyWatermark(watermark); // (boilerplate metadata insertion -- ignore it) loader.buildAccessories(document,this.getClass(),"Watermark","how to place some content behind existing pages"); // 4. Serialize the PDF file (again, boilerplate code -- see the PDFClownSampleLoader class source code)! loader.serialize(file,this.getClass().getSimpleName()); } private void applyWatermark( FormXObject watermark ) { // 1. Instantiate the stamper! /* NOTE: The PageStamper is optimized for dealing with pages. */ PageStamper stamper = new PageStamper(); // 2. Inserting the watermark into each page of the document... for(Page page : watermark.getDocument().getPages()) { // 2.1. Associate the page to the stamper! stamper.setPage(page); // 2.2. Stamping the watermark on the background... // Get the background 'layer' of the page! PrimitiveFilter background = stamper.getBackground(); // Show the watermark into the page background! background.showXObject(watermark); // 2.3. End the stamping! stamper.flush(); } } private FormXObject createWatermark( Document document ) { // 1. Create a new external form object to represent the watermark! FormXObject watermark = new FormXObject(document); // Size. Dimension2D size = document.getSize(); watermark.setSize(size); // 2. Inserting the contents of the watermark... // 2.1. Create a content builder for the watermark! PrimitiveFilter builder = new PrimitiveFilter(watermark); // 2.2. Inserting the contents... // Set the font to use! builder.setFont( new StandardType1Font( document, StandardType1Font.FamilyNameEnum.Courier, true, false ), 120 ); // Set the color to fill the text characters! builder.setFillColor( new DeviceRGBColor(115f/255, 164f/255, 232f/255) ); // Show the text! builder.showText( "PDFClown", // Text to show. new Point2D.Double(size.getWidth()/2d,size.getHeight()/2d), // Anchor location: page center. AlignmentXEnum.Center, // Horizontal placement (relative to the anchor): center. AlignmentYEnum.Middle, // Vertical placement (relative to the anchor): middle. 50 // Rotation: 50-degree-counterclockwise. ); // 2.3. Flush the contents into the watermark! builder.flush(); return watermark; } }