Skip to content

Instantly share code, notes, and snippets.

@JoelGeraci-Datalogics
Created June 16, 2016 18:09
Show Gist options
  • Save JoelGeraci-Datalogics/fc4170b11492b7de4e972e7623a3db43 to your computer and use it in GitHub Desktop.
Save JoelGeraci-Datalogics/fc4170b11492b7de4e972e7623a3db43 to your computer and use it in GitHub Desktop.
This sample draws two stars on a PDF Page using two different techniques.
/*
* Copyright Datalogics, Inc. 2015
*/
package pdfjt.cookbook.document;
import com.adobe.fontengine.font.Font;
import com.adobe.internal.io.ByteReader;
import com.adobe.internal.io.InputStreamByteReader;
import com.adobe.pdfjt.core.types.ASName;
import com.adobe.pdfjt.pdf.content.Content;
import com.adobe.pdfjt.pdf.content.InstructionFactory;
import com.adobe.pdfjt.pdf.contentmodify.ContentWriter;
import com.adobe.pdfjt.pdf.contentmodify.ModifiableContent;
import com.adobe.pdfjt.pdf.document.PDFContents;
import com.adobe.pdfjt.pdf.document.PDFDocument;
import com.adobe.pdfjt.pdf.document.PDFOpenOptions;
import com.adobe.pdfjt.pdf.document.PDFResources;
import com.adobe.pdfjt.pdf.graphics.font.PDFFont;
import com.adobe.pdfjt.pdf.interactive.annotation.PDFAnnotationEnum;
import com.adobe.pdfjt.pdf.interactive.annotation.PDFAnnotationPolygon;
import com.adobe.pdfjt.pdf.interactive.annotation.PDFBorder;
import com.adobe.pdfjt.pdf.page.PDFPage;
import com.adobe.pdfjt.services.ap.AppearanceService;
import com.adobe.pdfjt.services.ap.spi.APContext;
import com.adobe.pdfjt.services.ap.spi.APResources;
import com.datalogics.pdf.document.DocumentHelper;
import java.awt.Point;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.EnumSet;
import java.util.HashMap;
/**
* This sample draws two stars on a PDF Page using two different techniques.
*/
public class DrawingPolygons {
private static final String inputPDFURL = "http://dev.datalogics.com/cookbook/annotations/Polygons.pdf";
private static final String outputDir = "cookbook/Annotations/output/";
private static final double red[] = { 1.0, 0, 0 }; // RGB Red
static public void main(String[] args) throws Exception {
// First read in the PDF file
URLConnection connection = new URL(inputPDFURL).openConnection();
connection.setRequestProperty("User-Agent",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");
connection.connect();
InputStream fis = connection.getInputStream();
ByteReader byteReader = new InputStreamByteReader(fis);
PDFDocument pdfDocument = PDFDocument.newInstance(byteReader, PDFOpenOptions.newInstance());
/*
* Then get the first (and only) page in the file. We'll need this
* object in order to add content and annotations to it.
*/
PDFPage pdfPageOne = pdfDocument.requirePages().getPage(0);
int numArms = 5;
Double contentCenterX = pdfPageOne.getMediaBox().width() / 4;
Double contentCenterY = pdfPageOne.getMediaBox().height() / 4 * 3;
Point contentCenter = new Point(contentCenterX.intValue(), contentCenterY.intValue());
Shape starContent = createStar(numArms, contentCenter, 72, 36);
/*
* Now create a ContentWriter so we can write new page content to the PDF
*/
PDFContents pdfContents = PDFContents.newInstance(pdfPageOne.getPDFDocument());
PDFResources pdfResources = PDFResources.newInstance(pdfPageOne.getPDFDocument());
ContentWriter contentWriter = ContentWriter.newInstance(ModifiableContent.newInstance(pdfContents, pdfResources));
// Set the thickness of any lines drawn after this instruction
contentWriter.write(InstructionFactory.newLineWidth(.5));
// Use the coordinates of the shape to create the PDF drawing Instructions
double[] contentCoordinates = new double[6];
for (PathIterator pathIterator = starContent.getPathIterator(null); !pathIterator.isDone(); pathIterator.next()) {
int type = pathIterator.currentSegment(contentCoordinates);
if (type == PathIterator.SEG_MOVETO) {
contentWriter.write(InstructionFactory.newMoveTo(contentCoordinates[0], contentCoordinates[1]));
}
if (type == PathIterator.SEG_LINETO) {
contentWriter.write(InstructionFactory.newLineTo(contentCoordinates[0], contentCoordinates[1]));
}
if (type == PathIterator.SEG_CLOSE) {
contentWriter.write(InstructionFactory.newCloseAndStrokePath());
}
}
Content content = contentWriter.close();
// Add the new content to the existing page content
pdfPageOne.getContents().addContents(content.getContentStream());
// Create a new shape next to the first one
Double annotCenterX = pdfPageOne.getMediaBox().width() / 4 * 3;
Double annotCenterY = pdfPageOne.getMediaBox().height() / 4 * 3;
Point annotCenter = new Point(annotCenterX.intValue(), annotCenterY.intValue());
Shape starAnnot = createStar(numArms, annotCenter, 72, 36);
/*
* Create an array to hold the vertices. The length of the array equals
* the number of arms times two, one for each inner vertex and outer
* vertex of the star, plus one to return to the origin, then double
* that number since we need the x and y coordinates to be in the same array.
*/
double[] vertices = new double[((numArms * 2) + 1) * 2];
/*
* Now use the coordinates of the Shape to create the array that we'll use in the annotation Vertices dictionary.
*/
double[] coordinates = new double[6];
int i = 0;
for (PathIterator pathIterator = starAnnot.getPathIterator(null); !pathIterator.isDone(); pathIterator.next()) {
pathIterator.currentSegment(coordinates);
vertices[i] = coordinates[0];
vertices[i + 1] = coordinates[1];
i += 2;
}
// Now add the annotation to the page.
PDFAnnotationPolygon pdfAnnotationPolygon = PDFAnnotationPolygon.newInstance(pdfDocument);
pdfAnnotationPolygon.setDictionaryArrayValue(ASName.k_Vertices, vertices);
pdfAnnotationPolygon.setColor(red);
PDFBorder pdfBorder = PDFBorder.newInstance(pdfDocument);
pdfBorder.setWidth(.5);
pdfAnnotationPolygon.setBorder(pdfBorder);
pdfPageOne.addAnnotation(pdfAnnotationPolygon);
// Now create the appearances of the Polygon annotations
APResources apResources = new APResources(pdfDocument.getCosDocument().getOptions().getFontSet(),
pdfDocument.getCosDocument().getOptions().getDocLocale(), new HashMap<Font, PDFFont>());
APContext apContext = new APContext(apResources, true, null);
apContext.setAnnotationsToBeProcessed(EnumSet.of(PDFAnnotationEnum.Polygon));
AppearanceService.generateAppearances(pdfDocument, apContext, null);
// Save and close
DocumentHelper.saveFullAndClose(pdfDocument, outputDir + "Polygons.pdf");
// Save the file.
System.out.println("Done!");
}
/*
* From:
* http://stackoverflow.com/questions/2710065/drawing-star-shapes-with-
* variable-parameters By Peter Walser -
* http://stackoverflow.com/users/63293/peter-walser
*/
public static Shape createStar(int arms, Point center, double rOuter, double rInner) {
double angle = Math.PI / arms;
GeneralPath path = new GeneralPath();
for (int i = 0; i < 2 * arms; i++) {
double r = (i & 1) == 0 ? rOuter : rInner;
Point2D.Double p = new Point2D.Double(center.x + Math.cos(i * angle) * r, center.y + Math.sin(i * angle) * r);
if (i == 0)
path.moveTo(p.getX(), p.getY());
else
path.lineTo(p.getX(), p.getY());
}
path.closePath();
return path;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment