PDFWriterLowLevelTest.java 0000644 0001750 0001750 00000013037 11343262371 015073 0 ustar user03 user03 package org.freehep.graphicsio.pdf.test; import java.io.*; import java.util.*; import org.freehep.graphicsio.pdf.*; /** * This class tests the lower-level PDF Writer interfaces. * It simply writes a document with several pages, including * some text and graphics. *
* @author Mark Donszelmann * @version $Id: PDFWriterLowLevelTest.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFWriterLowLevelTest { public static void main(String[] args) throws Exception { FileOutputStream out = new FileOutputStream("PDFWriterLowLevelTest.pdf"); // PDF file PDFWriter pdf = new PDFWriter(out, "1.3"); pdf.comment("PDFGraphicsTest file generated by PDFWriterLowLevelTest, Freehep lib"); // info PDFDictionary info = pdf.openDictionary("DocInfo"); info.entry("Title", "PDFWriter LowLevel Test Output"); info.entry("Author", "Mark Donszelmann"); info.entry("Subject", "LowLevel Test File of the PDFWriter of the FreeHEP library"); info.entry("Keywords", "PDFWriter; FreeHEP"); info.entry("Creator", "org.freehep.util.pdf.PDFWriter"); info.entry("CreationDate", Calendar.getInstance()); pdf.close(info); // catalog PDFDictionary catalog = pdf.openDictionary("Catalog"); catalog.entry("Type", pdf.name("Catalog")); catalog.entry("Outlines", pdf.ref("Outlines")); catalog.entry("Pages", pdf.ref("RootPage")); catalog.entry("PageMode", pdf.name("UseOutlines")); catalog.entry("ViewerPreferences", pdf.ref("Preferences")); pdf.close(catalog); // preferences PDFDictionary prefs = pdf.openDictionary("Preferences"); prefs.entry("FitWindow", false); prefs.entry("CenterWindow", false); pdf.close(prefs); // outlines PDFDictionary outlines = pdf.openDictionary("Outlines"); outlines.entry("Type", pdf.name("Outlines")); outlines.entry("Count", 0); pdf.close(outlines); // pages PDFDictionary pages = pdf.openDictionary("RootPage"); pages.entry("Type", pdf.name("Pages")); pages.entry("Kids", new Object[] {pdf.ref("FirstPage"), pdf.ref("SecondPage")}); pages.entry("Count", 2); pages.entry("MediaBox", new int[] {0, 0, 612, 792}); PDFDictionary resources = pages.openDictionary("Resources"); resources.entry("ProcSet", pdf.ref("OurPageProcSet")); PDFDictionary fontList = resources.openDictionary("Font"); fontList.entry("F1", pdf.ref("Helvetica")); resources.close(fontList); pages.close(resources); pdf.close(pages); // first page PDFDictionary firstPage = pdf.openDictionary("FirstPage"); firstPage.entry("Type", pdf.name("Page")); firstPage.entry("Parent", pdf.ref("RootPage")); firstPage.entry("Contents", pdf.ref("FirstPageContent")); pdf.close(firstPage); // first page content PDFStream first = pdf.openStream("FirstPageContent"); first.beginText(); first.font(pdf.name("F1"), 24); first.text(100, 100); first.show("Hello"); first.show(" World"); first.endText(); pdf.close(first); // second page PDFDictionary secondPage = pdf.openDictionary("SecondPage"); secondPage.entry("Type", pdf.name("Page")); secondPage.entry("Parent", pdf.ref("RootPage")); secondPage.entry("Contents", pdf.ref("SecondPageContent")); pdf.close(secondPage); // second page content PDFStream second = pdf.openStream("SecondPageContent"); second.comment("Draw a black line segment, using the default line width."); second.move(150, 250); second.line(150, 350); second.stroke(); second.comment("Draw a thicker, dashed line segment."); second.width(4); second.comment("Set line width to 4 points"); second.dash(new int[] {4,6}, 0); second.comment("Set dash pattern to 4 units on, 6 units off"); second.move(150, 250); second.line(400, 250); second.stroke(); second.dash(new int[0], 0); second.comment("Reset dash pattern to a solid line"); second.width(1); second.comment("Reset line width to 1 unit"); second.comment("Draw a rectangle with a 1 unit red border, filled with light blue."); second.colorSpaceStroke(1.0, 0.0, 0.0); second.comment("Red for stroke color"); second.colorSpace(0.5, 0.75, 1.0); second.comment("Light blue for fill color"); second.rectangle(200, 300, 50, 75); second.fillAndStroke(); second.comment("Draw a curve filled with gray and with a colored border."); second.colorSpaceStroke(0.5, 0.1, 0.2); second.colorSpace(0.7); second.move(300, 300); second.cubic(300, 400, 400, 400, 400, 300); second.closeFillAndStroke(); pdf.close(second); // our page proc set pdf.object("OurPageProcSet", new Object[] {pdf.name("PDF"), pdf.name("Text")}); // font PDFDictionary font = pdf.openDictionary("Helvetica"); font.entry("Type", pdf.name("Font")); font.entry("Subtype", pdf.name("Type1")); font.entry("Name", pdf.name("F1")); font.entry("BaseFont", pdf.name("Helvetica")); pdf.close(font); // write xref table and trailer pdf.close("Catalog", "DocInfo"); out.close(); } } PDFWriterTest.java 0000644 0001750 0001750 00000017207 11343262374 013427 0 ustar user03 user03 package org.freehep.graphicsio.pdf.test; import java.awt.*; import java.io.*; import java.util.*; import org.freehep.graphicsio.pdf.*; import org.freehep.graphicsio.ImageConstants; import org.freehep.util.images.*; /** * This class tests the user-level PDF Writer interfaces. * It simply writes a document with several pages, including * some text and graphics. *
* @author Mark Donszelmann
* @version $Id: PDFWriterTest.java 10270 2007-01-09 18:18:57Z duns $
*/
public class PDFWriterTest {
public static void main(String[] args) throws Exception {
FileOutputStream out = new FileOutputStream("PDFWriterUserTest.pdf");
// PDF file
PDFWriter pdf = new PDFWriter(out, "1.3");
pdf.comment("PDFGraphicsTest file generated by PDFWriterTest, Freehep lib");
// info
PDFDocInfo info = pdf.openDocInfo("DocInfo");
info.setTitle("PDFWriter Test Output");
info.setAuthor("Mark Donszelmann");
info.setSubject("Test File of the PDFWriter of the FreeHEP library");
info.setKeywords("PDFWriter; FreeHEP");
info.setCreator("org.freehep.util.pdf.PDFWriter");
info.setCreationDate(Calendar.getInstance());
pdf.close(info);
// catalog
PDFCatalog catalog = pdf.openCatalog("Catalog", "RootPage");
catalog.setOutlines("Outlines");
catalog.setPageMode("UseOutlines");
catalog.setViewerPreferences("Preferences");
catalog.setOpenAction(new Object[] { pdf.ref("FirstPage"), pdf.name("Fit")});
pdf.close(catalog);
// preferences
PDFViewerPreferences prefs = pdf.openViewerPreferences("Preferences");
prefs.setFitWindow(true);
prefs.setCenterWindow(false);
pdf.close(prefs);
// outlines
PDFOutlineList outlines = pdf.openOutlineList("Outlines", "FirstOutline", "LastOutline");
pdf.close(outlines);
// outline FIXME: need to connect still
PDFOutline firstOutline = pdf.openOutline("FirstOutline", "Text Page",
"Outlines", null, "SecondOutline");
firstOutline.setDest(new Object[] { pdf.ref("FirstPage"), pdf.name("Fit")});
pdf.close(firstOutline);
PDFOutline secondOutline = pdf.openOutline("SecondOutline", "Graphics Page",
"Outlines", "FirstOutline", "LastOutline");
secondOutline.setDest(new Object[] { pdf.ref("SecondPage"), pdf.name("Fit")});
pdf.close(secondOutline);
PDFOutline lastOutline = pdf.openOutline("LastOutline", "Image Page",
"Outlines", "SecondOutline", null);
lastOutline.setDest(new Object[] { pdf.ref("ThirdPage"), pdf.name("Fit")});
pdf.close(lastOutline);
// pages
PDFPageTree pages = pdf.openPageTree("RootPage", null);
pages.addPage("FirstPage");
pages.addPage("SecondPage");
pages.addPage("ThirdPage");
pages.setMediaBox(0, 0, 612, 792);
pages.setResources("Resources");
pdf.close(pages);
// resources
PDFDictionary resources = pdf.openDictionary("Resources");
resources.entry("ProcSet", pdf.ref("OurPageProcSet"));
PDFDictionary fontList = resources.openDictionary("Font");
fontList.entry("F1", pdf.ref("Helvetica"));
resources.close(fontList);
pdf.close(resources);
// first page
PDFPage firstPage = pdf.openPage("FirstPage", "RootPage");
firstPage.setContents("FirstPageContent");
pdf.close(firstPage);
// first page content
pdf.comment("hello word");
PDFStream first = pdf.openStream("FirstPageContent", new String[] { "Flate", "ASCIIHex" });
first.beginText();
first.font(pdf.name("F1"), 24);
first.text(100, 100);
first.show("Hello");
first.show(" World");
first.endText();
pdf.close(first);
// second page
PDFPage secondPage = pdf.openPage("SecondPage", "RootPage");
secondPage.setContents("SecondPageContent");
secondPage.setThumb("SecondPageThumbnail");
pdf.close(secondPage);
// second page thumbnail
PDFStream secondThumb = pdf.openStream("SecondPageThumbnail");
MediaTracker tracker = new MediaTracker(new Panel());
Image image1 = ImageHandler.getImage("../../test/images/BrokenCursor.gif", PDFWriterTest.class);
Image image2 = ImageHandler.getImage("../../test/images/transparent-image.gif", PDFWriterTest.class);
tracker.addImage(image1,0);
tracker.addImage(image2,1);
try {
tracker.waitForAll();
} catch (Exception e) {
e.printStackTrace();
}
secondThumb.image(
ImageUtilities.createRenderedImage(
image2, null, Color.BLACK),
Color.BLACK,
ImageConstants.ZLIB);
pdf.close(secondThumb);
// second page content
PDFStream second = pdf.openStream(
"SecondPageContent",
new String[] {
ImageConstants.ENCODING_FLATE,
ImageConstants.ENCODING_ASCII85 });
second.comment("Draw a black line segment, using the default line width.");
second.move(150, 250);
second.line(150, 350);
second.stroke();
second.comment("Draw a thicker, dashed line segment.");
second.width(4);
second.comment("Set line width to 4 points");
second.dash(new int[] {4,6}, 0);
second.comment("Set dash pattern to 4 units on, 6 units off");
second.move(150, 250);
second.line(400, 250);
second.stroke();
second.dash(new int[0], 0);
second.comment("Reset dash pattern to a solid line");
second.width(1);
second.comment("Reset line width to 1 unit");
second.comment("Draw a rectangle with a 1 unit red border, filled with light blue.");
second.colorSpaceStroke(1.0, 0.0, 0.0);
second.comment("Red for stroke color");
second.colorSpace(0.5, 0.75, 1.0);
second.comment("Light blue for fill color");
second.rectangle(200, 300, 50, 75);
second.fillAndStroke();
second.comment("Draw a curve filled with gray and with a colored border.");
second.colorSpaceStroke(0.5, 0.1, 0.2);
second.colorSpace(0.7);
second.move(300, 300);
second.cubic(300, 400, 400, 400, 400, 300);
second.closeFillAndStroke();
pdf.close(second);
// third page
PDFPage thirdPage = pdf.openPage("ThirdPage", "RootPage");
thirdPage.setContents("ThirdPageContent");
pdf.close(thirdPage);
// third page content
PDFStream third = pdf.openStream("ThirdPageContent");
third.save();
third.matrix(32, 0, 0, 32, 298, 388);
third.inlineImage(
ImageUtilities.createRenderedImage(image1, null, Color.BLACK),
Color.BLACK,
ImageConstants.ZLIB);
third.restore();
pdf.close(third);
// our page proc set
pdf.object("OurPageProcSet", new Object[] {pdf.name("PDF"),
pdf.name("Text"),
pdf.name("ImageC") });
// font
PDFDictionary font = pdf.openDictionary("Helvetica");
font.entry("Type", pdf.name("Font"));
font.entry("Subtype", pdf.name("Type1"));
font.entry("Name", pdf.name("F1"));
font.entry("BaseFont", pdf.name("Helvetica"));
pdf.close(font);
// close pdf
pdf.close();
out.close();
System.exit(0);
}
}
pom.xml 0000644 0001750 0001750 00000002273 11344042422 011417 0 ustar user03 user03
*
* @author Mark Donszelmann
* @version $Id: PDFPageBase.java 8584 2006-08-10 23:06:37Z duns $
*/
public abstract class PDFPageBase extends PDFDictionary {
protected PDFPageBase(PDF pdf, PDFByteWriter writer, PDFObject object,
PDFRef parent) throws IOException {
super(pdf, writer, object);
entry("Parent", parent);
}
//
// Inheritable items go here
//
public void setResources(String resources) throws IOException {
entry("Resources", pdf.ref(resources));
}
public void setMediaBox(double x, double y, double w, double h)
throws IOException {
double[] rectangle = { x, y, w, h };
entry("MediaBox", rectangle);
}
public void setCropBox(double x, double y, double w, double h)
throws IOException {
double[] rectangle = { x, y, w, h };
entry("CropBox", rectangle);
}
public void setRotate(int rotate) throws IOException {
entry("Rotate", rotate);
}
}
src/main/java/org/freehep/graphicsio/pdf/PDFPaintDelayQueue.java 0000644 0001750 0001750 00000022462 11343262370 024107 0 ustar user03 user03 // Copyright 2001 freehep
package org.freehep.graphicsio.pdf;
import java.awt.GradientPaint;
import java.awt.Paint;
import java.awt.TexturePaint;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
/**
* Delay Paint objects (gradient/texture, not color) for writing
* pattern/shading/function dictionaries to the pdf file when the pageStream is
* complete.
* TODO: - reuse pattern dictionaries if possible - cyclic function not working
* yet (ps calculation)
*
* @author Simon Fischer
* @version $Id: PDFPaintDelayQueue.java 10270 2007-01-09 18:18:57Z duns $
*/
public class PDFPaintDelayQueue {
private static int currentNumber = 0;
private class Entry {
private Paint paint;
private String name;
private AffineTransform trafo;
private String writeAs;
private boolean written;
private Entry(Paint paint, AffineTransform trafo, String writeAs) {
this.paint = paint;
this.trafo = trafo;
this.writeAs = writeAs;
this.name = "Paint" + (currentNumber++);
this.written = false;
}
}
private List paintList;
private PDFWriter pdf;
// private PDFImageDelayQueue imageDelayQueue;
private AffineTransform pageMatrix;
/** Don't forget to call setPageMatrix(). */
public PDFPaintDelayQueue(PDFWriter pdf, PDFImageDelayQueue imageDelayQueue) {
this.pdf = pdf;
this.paintList = new LinkedList();
// this.imageDelayQueue = imageDelayQueue;
this.pageMatrix = new AffineTransform();
}
/**
* Call this method in order to inform this class about the transformation
* that is necessary to map the pattern's coordinate space to the default
* coordinate system of the parent's content stream (in our case the
* flipping of the page).
*/
public void setPageMatrix(AffineTransform t) {
pageMatrix = new AffineTransform(t);
}
public PDFName delayPaint(Paint paint, AffineTransform transform,
String writeAs) {
Entry e = new Entry(paint, transform, writeAs);
paintList.add(e);
return pdf.name(e.name);
}
/** Creates a stream for every delayed image. */
public void processAll() throws IOException {
ListIterator i = paintList.listIterator();
while (i.hasNext()) {
Entry e = (Entry) i.next();
if (!e.written) {
e.written = true;
if (e.paint instanceof GradientPaint) {
addGradientPaint(e);
} else if (e.paint instanceof TexturePaint) {
addTexturePaint(e);
} else {
System.err.println("PDFWriter: Paint of class '"
+ e.paint.getClass() + "' not supported.");
// FIXME, we could write a color here, to keep the file
// valid.
}
}
}
}
/**
* Adds all names to the dictionary which should be the value of the
* resources dicionrary's /Pattern entry.
*/
public int addPatterns() throws IOException {
if (paintList.size() > 0) {
PDFDictionary patterns = pdf.openDictionary("Pattern");
ListIterator i = paintList.listIterator();
while (i.hasNext()) {
Entry e = (Entry) i.next();
patterns.entry(e.name, pdf.ref(e.name));
}
pdf.close(patterns);
}
return paintList.size();
}
private void addGradientPaint(Entry e) throws IOException {
GradientPaint gp = (GradientPaint) e.paint;
// open the pattern dictionary
PDFDictionary pattern = pdf.openDictionary(e.name);
pattern.entry("Type", pdf.name("Pattern"));
pattern.entry("PatternType", 2);
setMatrix(pattern, e, 0, 0);
// the shading subdictionary
PDFDictionary shading = pattern.openDictionary("Shading");
shading.entry("ShadingType", 2);
shading.entry("ColorSpace", pdf.name("DeviceRGB"));
Point2D p1 = gp.getPoint1();
Point2D p2 = gp.getPoint2();
shading.entry("Coords", new double[] { p1.getX(), p1.getY(), p2.getX(),
p2.getY() });
double[] domain = new double[] { 0, 1 };
shading.entry("Domain", domain);
// the function subdictionary (necessarily by reference, because
// the type 4 function is a stream)
String functionRef = e.name + "Function";
shading.entry("Function", pdf.ref(functionRef));
shading.entry("Extend", new boolean[] { true, true });
pattern.close(shading);
pdf.close(pattern);
// get color components and generate the functions
float[] col0 = new float[3];
gp.getColor1().getRGBColorComponents(col0);
double c0[] = new double[] { col0[0], col0[1], col0[2] };
float[] col1 = new float[3];
gp.getColor2().getRGBColorComponents(col1);
double c1[] = new double[] { col1[0], col1[1], col1[2] };
if (gp.isCyclic()) {
// FIXME: cyclic function only eveluated between 0 and 1 for short
// range, not repetitive.
// addCyclicFunction(functionRef, c0, c1, domain);
addLinearFunction(functionRef, c0, c1, domain);
} else {
addLinearFunction(functionRef, c0, c1, domain);
}
}
/** Writes a type 2 (exponential) function (exponent N=1) to the pdf file. */
private void addLinearFunction(String functionRef, double[] c0,
double[] c1, double[] dom) throws IOException {
PDFDictionary function = pdf.openDictionary(functionRef);
function.entry("FunctionType", 2);
function.entry("Domain", dom);
function.entry("Range", new double[] { 0., 1., 0., 1., 0., 1. });
function.entry("C0", c0);
function.entry("C1", c1);
function.entry("N", 1);
pdf.close(function);
}
/**
* Writes a type 4 (PostScript calculator) function that describes a
* triangle function to the pdf file.
*/
// NOT USED
protected void addCyclicFunction(String functionRef, double[] c0,
double[] c1, double[] dom) throws IOException {
// PDFStream function = pdf.openStream(functionRef, new String[] {
// "Flate", "ASCII85" });
PDFStream function = pdf.openStream(functionRef);
function.entry("FunctionType", 4);
// function.entry("Domain", new double[] {-1000.0, 1000.0} );
function.entry("Domain", dom);
function.entry("Range", new double[] { 0., 1., 0., 1., 0., 1. });
function.println("{");
/*
* function.println("2 mod"); function.println("1 sub");
* function.println("abs"); function.println("1 exch sub");
*/
// function.println("sin");
for (int i = 0; i < 3; i++) {
if (i < 2)
function.println("dup");
function.println((c1[i] - c0[i]) + " mul");
function.println(c0[i] + " add");
if (i < 2)
function.println("exch");
}
// function.println("pop 0.8 0.0 0.0");
function.println("}");
pdf.close(function);
}
private void addTexturePaint(Entry e) throws IOException {
TexturePaint tp = (TexturePaint) e.paint;
// open the pattern stream that also holds the inlined picture
PDFStream pattern = pdf.openStream(e.name, null); // image is encoded.
pattern.entry("Type", pdf.name("Pattern"));
pattern.entry("PatternType", 1);
pattern.entry("PaintType", 1);
BufferedImage image = tp.getImage();
pattern.entry("TilingType", 1);
double width = tp.getAnchorRect().getWidth();
double height = tp.getAnchorRect().getHeight();
double offsX = tp.getAnchorRect().getX();
double offsY = tp.getAnchorRect().getY();
pattern.entry("BBox", new double[] { 0, 0, width, height });
pattern.entry("XStep", width);
pattern.entry("YStep", height);
PDFDictionary resources = pattern.openDictionary("Resources");
resources.entry("ProcSet", new Object[] { pdf.name("PDF"),
pdf.name("ImageC") });
pattern.close(resources);
setMatrix(pattern, e, offsX, offsY);
// scale the tiling image to the correct size
pattern.matrix(width, 0, 0, -height, 0, height);
pattern.inlineImage(image, null, e.writeAs);
pdf.close(pattern);
}
/**
* Sets both the page (flip) matrix and the actual transformation matrix
* plus a translation offset (which may of course be be 0).
*/
private void setMatrix(PDFDictionary dict, Entry e, double translX,
double translY) throws IOException {
// concatenate the page matrix and the actual transformation matrix
AffineTransform trafo = new AffineTransform(pageMatrix);
trafo.concatenate(e.trafo);
trafo.translate(translX, translY);
double[] matrix = new double[6];
trafo.getMatrix(matrix);
dict.entry("Matrix", new double[] { matrix[0], matrix[1], matrix[2],
matrix[3], matrix[4], matrix[5] });
}
}
src/main/java/org/freehep/graphicsio/pdf/PDFCharTableWriter.java 0000644 0001750 0001750 00000002171 11343262370 024065 0 ustar user03 user03 // Copyright 2001-2005 freehep
package org.freehep.graphicsio.pdf;
import java.io.IOException;
import org.freehep.graphics2d.font.CharTable;
import org.freehep.graphicsio.font.FontEmbedder;
public class PDFCharTableWriter implements PDFRedundanceTracker.Writer {
private static PDFCharTableWriter ctw;
public static PDFCharTableWriter getInstance() {
if (ctw == null)
ctw = new PDFCharTableWriter();
return ctw;
}
public void writeObject(Object object, PDFRef ref, PDFWriter pdf)
throws IOException {
CharTable charTable = (CharTable) object;
PDFDictionary encoding = pdf.openDictionary(ref.getName());
encoding.entry("Type", pdf.name("Encoding"));
Object[] differences = new Object[257];
differences[0] = new Integer(0);
for (int i = 0; i < 256; i++) {
String charName = charTable.toName(i);
differences[i + 1] = (charName != null) ? pdf.name(charName) : pdf
.name(FontEmbedder.NOTDEF);
}
encoding.entry("Differences", differences);
pdf.close(encoding);
}
}
src/main/java/org/freehep/graphicsio/pdf/package.html 0000644 0001750 0001750 00000002274 11343262370 022133 0 ustar user03 user03
PDF (Portable Document File) Output Format.
It is based on the "PDF Reference: Second Edition, version 1.4", July 2001 by "Addison-Wesley".
It currently contains all classes for all PDF objects available in PDF. These are lower level classes such as PDFName, PDFObject, PDFRef, PDFDictionary and PDFStream. For the classes PDFString and PDFArray one should use the java String class and the java array respectively.
The user typically interacts with the PDFWriter class to create a PDF file. He can then create pages, open streams and use the latter to create the actual content of the page. The PDFWriter in combination with the PDFByteWriter takes care of keeping "logical" object references, building the cross-reference table and do some error checking.
An implementation of VectorGraphics also exist:
The following Limitations exist:
* * @author Mark Donszelmann * @version $Id: PDFByteWriter.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFByteWriter extends CountedByteOutputStream implements PDFConstants { private int indent; private String indentString = " "; PDFByteWriter(OutputStream out) { super(out); indent = 0; } public void write(String s) throws IOException { write(s.getBytes("ISO-8859-1")); } public void close() throws IOException { out.close(); super.close(); } public void print(String string) throws IOException { for (int i = 0; i < indent; i++) { write(indentString); } printPlain(string); } public void printPlain(String string) throws IOException { write(string); } public void println() throws IOException { write(EOL); } public void indent() { indent++; } public void outdent() { if (indent > 0) { indent--; } } // Convenience methods public void println(String string) throws IOException { print(string); println(); } public void print(int number) throws IOException { print(Integer.toString(number)); } public void println(int number) throws IOException { print(number); println(); } public void printPlain(int number) throws IOException { printPlain(Integer.toString(number)); } public void print(double number) throws IOException { print(Double.toString(number)); } public void println(double number) throws IOException { print(number); println(); } public void printPlain(double number) throws IOException { printPlain(Double.toString(number)); } public void print(Object object) throws IOException { print(object.toString()); } public void println(Object object) throws IOException { print(object); println(); } public void printPlain(Object object) throws IOException { printPlain(object.toString()); } } src/main/java/org/freehep/graphicsio/pdf/PDFCatalog.java 0000644 0001750 0001750 00000004075 11343262370 022422 0 ustar user03 user03 package org.freehep.graphicsio.pdf; import java.io.IOException; /** * Implements the Catalog Dictionary (see Table 3.15). *
* * @author Mark Donszelmann * @version $Id: PDFCatalog.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFCatalog extends PDFDictionary { PDFCatalog(PDF pdf, PDFByteWriter writer, PDFObject parent, PDFRef pageTree) throws IOException { super(pdf, writer, parent); entry("Type", pdf.name("Catalog")); entry("Pages", pageTree); } /* * public void setPageLabels(PDFNumberTree pageLabels) { entry("PageLabels", * pageLabels); } */ public void setNames(String names) throws IOException { entry("Names", pdf.ref(names)); } public void setDests(String dests) throws IOException { entry("Dests", pdf.ref(dests)); } public void setViewerPreferences(String viewerPreferences) throws IOException { entry("ViewerPreferences", pdf.ref(viewerPreferences)); } public void setPageLayout(String pageLayout) throws IOException { entry("PageLayout", pdf.name(pageLayout)); } public void setPageMode(String pageMode) throws IOException { entry("PageMode", pdf.name(pageMode)); } public void setOutlines(String outlines) throws IOException { entry("Outlines", pdf.ref(outlines)); } public void setThreads(String threads) throws IOException { entry("Threads", pdf.ref(threads)); } public void setOpenAction(Object[] openAction) throws IOException { entry("OpenAction", openAction); } public void setURI(String uri) throws IOException { entry("URI", pdf.ref(uri)); } public void setAcroForm(String acroForm) throws IOException { entry("AcroForm", pdf.ref(acroForm)); } public void setStructTreeRoot(String structTreeRoot) throws IOException { entry("StructTreeRoot", pdf.ref(structTreeRoot)); } public void setSpiderInfo(String spiderInfo) throws IOException { entry("SpiderInfo", pdf.ref(spiderInfo)); } } src/main/java/org/freehep/graphicsio/pdf/PDFName.java 0000644 0001750 0001750 00000000571 11343262370 021725 0 ustar user03 user03 package org.freehep.graphicsio.pdf; /** * Specifies a PDFName object. *
*
* @author Mark Donszelmann
* @version $Id: PDFName.java 8584 2006-08-10 23:06:37Z duns $
*/
public class PDFName implements PDFConstants {
private String name;
PDFName(String name) {
this.name = name;
}
public String toString() {
return "/" + name;
}
} src/main/java/org/freehep/graphicsio/pdf/PDFRedundanceTracker.java 0000644 0001750 0001750 00000007432 11343262370 024434 0 ustar user03 user03 // Copyright 2001 freehep
package org.freehep.graphicsio.pdf;
import java.io.IOException;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Vector;
/**
* This class keeps track of all kinds of objects written to a pdf file and
* avoids to write them several times instead of referencing the same object
* several times. Right now only encoding tables are supported.
*
* An implementation for images and paint would be possible.
*
* @author Simon Fischer
* @version $Id: PDFRedundanceTracker.java 8584 2006-08-10 23:06:37Z duns $
*/
public class PDFRedundanceTracker {
/**
* To be implemented by Writers which write objects that may already have
* been written.
*/
public interface Writer {
public void writeObject(Object o, PDFRef reference, PDFWriter pdf)
throws IOException;
}
private class Entry {
private static final String REF_PREFIX = "PDF_RTObj";
private Object object;
private Writer writer;
private boolean written;
private PDFRef reference;
private Object groupID;
private Entry(Object o, Object groupID, Writer w) {
this.object = o;
this.groupID = groupID;
this.writer = w;
this.written = false;
this.reference = pdf.ref(REF_PREFIX + (refCount++));
}
}
private static int refCount = 1;
private PDFWriter pdf;
private Map objects;
private Vector orderedObjects; // to keep order
public PDFRedundanceTracker(PDFWriter pdf) {
this.pdf = pdf;
objects = new Hashtable();
orderedObjects = new Vector();
}
/**
* Returns a reference that points to object. When this method
* is called several times for the same object (according to its hash code)
* the same reference is returned. When writeAll() is called the
* writer's writeObject() method will be called once with
* object as argument.
* The groupID is only used for getGroup()
*/
public PDFRef getReference(Object object, Object groupID, Writer writer) {
Object o = objects.get(object);
if (o != null) {
return ((Entry) o).reference;
} else {
Entry entry = new Entry(object, groupID, writer);
objects.put(object, entry);
orderedObjects.add(entry);
return entry.reference;
}
}
public PDFRef getReference(Object object, Writer writer) {
return getReference(object, null, writer);
}
/**
* Writes all objects that are not yet written. If the method is called
* several times then each times only the new objects are written.
*/
public void writeAll() {
Iterator i = orderedObjects.iterator();
while (i.hasNext()) {
Entry entry = (Entry) i.next();
if (!entry.written) {
try {
// System.out.println("PDFRT: Writing: " + entry.object);
entry.writer
.writeObject(entry.object, entry.reference, pdf);
entry.written = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/** Returns all objects belonging to a particular group. */
public Collection getGroup(Object groupID) {
Collection result = new LinkedList();
Iterator i = orderedObjects.iterator();
while (i.hasNext()) {
Entry entry = (Entry) i.next();
if (groupID.equals(entry.groupID)) {
result.add(entry.object);
}
}
return result;
}
}
src/main/java/org/freehep/graphicsio/pdf/PDFGraphics2D.java 0000644 0001750 0001750 00000072376 11343262370 023007 0 ustar user03 user03 // Copyright 2000-2007, FreeHEP
package org.freehep.graphicsio.pdf;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.Insets;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.TexturePaint;
import java.awt.font.LineMetrics;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.freehep.graphics2d.TagString;
import org.freehep.graphics2d.font.FontUtilities;
import org.freehep.graphics2d.font.Lookup;
import org.freehep.graphicsio.AbstractVectorGraphicsIO;
import org.freehep.graphicsio.FontConstants;
import org.freehep.graphicsio.ImageConstants;
import org.freehep.graphicsio.ImageGraphics2D;
import org.freehep.graphicsio.InfoConstants;
import org.freehep.graphicsio.MultiPageDocument;
import org.freehep.graphicsio.PageConstants;
import org.freehep.util.UserProperties;
/**
* Implementation of VectorGraphics that writes the output to a PDF
* file. Users of this class have to generate a PDFWriter and create
* an instance by invoking the factory method or the constructor. Document
* specific settings like page size can then be made by the appropriate setter
* methods. Before starting to draw, startExport() must be called.
* When drawing is finished, call endExport().
*
* @author Simon Fischer
* @author Mark Donszelmann
* @version $Id: PDFGraphics2D.java 10516 2007-02-06 21:11:19Z duns $
*/
public class PDFGraphics2D extends AbstractVectorGraphicsIO implements
MultiPageDocument, FontUtilities.ShowString {
/*
* ================================================================================
* Table of Contents: ------------------ 1. Constructors & Factory Methods
* 2. Document Settings 3. Header, Trailer, Multipage & Comments 3.1 Header &
* Trailer 3.2 MultipageDocument methods 4. Create & Dispose 5. Drawing
* Methods 5.1. shapes (draw/fill) 5.1.1. lines, rectangles, round
* rectangles 5.1.2. polylines, polygons 5.1.3. ovals, arcs 5.1.4. shapes
* 5.2. Images 5.3. Strings 6. Transformations 7. Clipping 8. Graphics State /
* Settings 8.1. stroke/linewidth 8.2. paint/color 8.3. font 8.4. rendering
* hints 9. Private/Utility Methods 9.1. drawing, shape creation 9.2. font,
* strings 9.3. images 9.4. transformations 10. Auxiliary
* ================================================================================
*/
private static final String rootKey = PDFGraphics2D.class.getName();
public static final String VERSION6 = "Acrobat Reader 6.x";
public static final String VERSION5 = "Acrobat Reader 5.x";
public static final String VERSION4 = "Acrobat Reader 4.x";
public static final String TRANSPARENT = rootKey + "."
+ PageConstants.TRANSPARENT;
public static final String BACKGROUND = rootKey + "."
+ PageConstants.BACKGROUND;
public static final String BACKGROUND_COLOR = rootKey + "."
+ PageConstants.BACKGROUND_COLOR;
public static final String PAGE_SIZE = rootKey + "."
+ PageConstants.PAGE_SIZE;
public static final String PAGE_MARGINS = rootKey + "."
+ PageConstants.PAGE_MARGINS;
public static final String ORIENTATION = rootKey + "."
+ PageConstants.ORIENTATION;
public static final String FIT_TO_PAGE = rootKey + "."
+ PageConstants.FIT_TO_PAGE;
public static final String EMBED_FONTS = rootKey + "."
+ FontConstants.EMBED_FONTS;
public static final String EMBED_FONTS_AS = rootKey + "."
+ FontConstants.EMBED_FONTS_AS;
public static final String THUMBNAILS = rootKey + ".Thumbnails";
public static final String THUMBNAIL_SIZE = rootKey + ".ThumbnailSize";
public static final String COMPRESS = rootKey + ".Compress";
public static final String VERSION = rootKey + ".Version";
public static final String WRITE_IMAGES_AS = rootKey + "."
+ ImageConstants.WRITE_IMAGES_AS;
public static final String AUTHOR = rootKey + "." + InfoConstants.AUTHOR;
public static final String TITLE = rootKey + "." + InfoConstants.TITLE;
public static final String SUBJECT = rootKey + "." + InfoConstants.SUBJECT;
public static final String KEYWORDS = rootKey + "."
+ InfoConstants.KEYWORDS;
private static final UserProperties defaultProperties = new UserProperties();
static {
defaultProperties.setProperty(TRANSPARENT, true);
defaultProperties.setProperty(BACKGROUND, false);
defaultProperties.setProperty(BACKGROUND_COLOR, Color.GRAY);
defaultProperties.setProperty(VERSION, VERSION5);
defaultProperties.setProperty(COMPRESS, false);
defaultProperties.setProperty(PAGE_SIZE, PageConstants.INTERNATIONAL);
defaultProperties.setProperty(PAGE_MARGINS, PageConstants
.getMargins(PageConstants.SMALL));
defaultProperties.setProperty(ORIENTATION, PageConstants.PORTRAIT);
defaultProperties.setProperty(FIT_TO_PAGE, true);
defaultProperties.setProperty(EMBED_FONTS, false);
defaultProperties.setProperty(EMBED_FONTS_AS,
FontConstants.EMBED_FONTS_TYPE3);
defaultProperties.setProperty(THUMBNAILS, defaultProperties
.getProperty(VERSION).equals(VERSION4));
defaultProperties.setProperty(THUMBNAIL_SIZE, new Dimension(128, 128));
defaultProperties.setProperty(WRITE_IMAGES_AS, ImageConstants.SMALLEST);
defaultProperties.setProperty(AUTHOR, "");
defaultProperties.setProperty(TITLE, "");
defaultProperties.setProperty(SUBJECT, "");
defaultProperties.setProperty(KEYWORDS, "");
defaultProperties.setProperty(CLIP, true);
defaultProperties.setProperty(TEXT_AS_SHAPES, true);
}
public static Properties getDefaultProperties() {
return defaultProperties;
}
public static void setDefaultProperties(Properties newProperties) {
defaultProperties.setProperties(newProperties);
}
public static final String version = "$Revision: 10516 $";
private static final String PDF_VERSION = "1.4";
private static final String[] COMPRESS_FILTERS = { ImageConstants.ENCODING_FLATE, ImageConstants.ENCODING_ASCII85};
private static final String[] NO_FILTERS = {};
private static final double FONTSIZE_CORRECTION = 1.0;
/*
* Not Used private static final CharTable STANDARD_CHAR_TABLES[] = {
* Lookup.getInstance().getTable("PDFLatin"),
* Lookup.getInstance().getTable("Symbol"),
* Lookup.getInstance().getTable("Zapfdingbats") };
*
* private static final Font STANDARD_FONT[] = { null, new Font("Symbol",
* Font.PLAIN, 10), new Font("ZapfDingbats", Font.PLAIN, 10), };
*/
// output
private OutputStream ros;
private PDFWriter os;
private PDFStream pageStream;
// remember some things to do
private PDFFontTable fontTable; // remember which standard fonts were used
private PDFImageDelayQueue delayImageQueue; // remember images XObjects to
// include in the file
private PDFPaintDelayQueue delayPaintQueue; // remember patterns to include
// in the file
// multipage
private int currentPage;
private boolean multiPage;
private TagString[] headerText;
private int headerUnderline;
private Font headerFont;
private TagString[] footerText;
private int footerUnderline;
private Font footerFont;
private List titles;
// extra pointers
int alphaIndex;
Map extGStates;
/*
* ================================================================================ |
* 1. Constructors & Factory Methods
* ================================================================================
*/
public PDFGraphics2D(File file, Dimension size)
throws FileNotFoundException {
this(new FileOutputStream(file), size);
}
public PDFGraphics2D(File file, Component component)
throws FileNotFoundException {
this(new FileOutputStream(file), component);
}
public PDFGraphics2D(OutputStream ros, Dimension size) {
super(size, false);
init(ros);
}
public PDFGraphics2D(OutputStream ros, Component component) {
super(component, false);
init(ros);
}
private void init(OutputStream ros) {
this.ros = new BufferedOutputStream(ros);
currentPage = 0;
multiPage = false;
titles = new ArrayList();
initProperties(defaultProperties);
}
/** Cloneconstructor */
protected PDFGraphics2D(PDFGraphics2D graphics, boolean doRestoreOnDispose) {
super(graphics, doRestoreOnDispose);
this.os = graphics.os;
this.pageStream = graphics.pageStream;
this.delayImageQueue = graphics.delayImageQueue;
this.delayPaintQueue = graphics.delayPaintQueue;
this.fontTable = graphics.fontTable;
this.currentPage = graphics.currentPage;
this.multiPage = graphics.multiPage;
this.titles = graphics.titles;
this.alphaIndex = graphics.alphaIndex;
this.extGStates = graphics.extGStates;
}
/*
* ================================================================================ |
* 2. Document Settings
* ================================================================================
*/
public void setMultiPage(boolean multiPage) {
this.multiPage = multiPage;
}
public boolean isMultiPage() {
return multiPage;
}
/**
* Set the clipping enabled flag. This will affect all output operations
* after this call completes. In some circumstances the clipping region is
* set incorrectly (not yet understood; AWT seems to not correctly dispose
* of graphic contexts). A workaround is to simply switch it off.
*/
public static void setClipEnabled(boolean enabled) {
defaultProperties.setProperty(CLIP, enabled);
}
/*
* ================================================================================ |
* 3. Header, Trailer, Multipage & Comments
* ================================================================================
*/
/* 3.1 Header & Trailer */
/**
* Writes the catalog, docinfo, preferences, and (as we use only single page
* output the page tree.
*/
public void writeHeader() throws IOException {
os = new PDFWriter(new BufferedOutputStream(ros), PDF_VERSION);
delayImageQueue = new PDFImageDelayQueue(os);
delayPaintQueue = new PDFPaintDelayQueue(os, delayImageQueue);
fontTable = new PDFFontTable(os);
String producer = getClass().getName();
if (!isDeviceIndependent()) {
producer += " " + version.substring(1, version.length() - 1);
}
PDFDocInfo info = os.openDocInfo("DocInfo");
info.setTitle(getProperty(TITLE));
info.setAuthor(getProperty(AUTHOR));
info.setSubject(getProperty(SUBJECT));
info.setKeywords(getProperty(KEYWORDS));
info.setCreator(getCreator());
info.setProducer(producer);
if (!isDeviceIndependent()) {
Calendar now = Calendar.getInstance();
info.setCreationDate(now);
info.setModificationDate(now);
}
info.setTrapped("False");
os.close(info);
// catalog
PDFCatalog catalog = os.openCatalog("Catalog", "RootPage");
catalog.setOutlines("Outlines");
catalog.setPageMode("UseOutlines");
catalog.setViewerPreferences("Preferences");
catalog.setOpenAction(new Object[] { os.ref("Page1"), os.name("Fit") });
os.close(catalog);
// preferences
PDFViewerPreferences prefs = os.openViewerPreferences("Preferences");
prefs.setFitWindow(true);
prefs.setCenterWindow(false);
os.close(prefs);
// extra stuff
alphaIndex = 1;
extGStates = new HashMap();
// hide the multipage functionality to the user in case of single page
// output by opening the first and only page immediately
if (!isMultiPage())
openPage(getSize(), null, getComponent());
}
public void writeBackground() {
if (isProperty(TRANSPARENT)) {
setBackground(null);
} else if (isProperty(BACKGROUND)) {
setBackground(getPropertyColor(BACKGROUND_COLOR));
clearRect(0.0, 0.0, getSize().width, getSize().height);
} else {
setBackground(getComponent() != null ? getComponent()
.getBackground() : Color.WHITE);
clearRect(0.0, 0.0, getSize().width, getSize().height);
}
}
public void writeTrailer() throws IOException {
if (!isMultiPage())
closePage();
// pages
PDFPageTree pages = os.openPageTree("RootPage", null);
for (int i = 1; i <= currentPage; i++) {
pages.addPage("Page" + i);
}
Dimension pageSize = PageConstants.getSize(getProperty(PAGE_SIZE),
getProperty(ORIENTATION));
pages.setMediaBox(0, 0, pageSize.getWidth(), pageSize.getHeight());
pages.setResources("Resources");
os.close(pages);
// ProcSet
os.object("PageProcSet", new Object[] { os.name("PDF"),
os.name("Text"), os.name("ImageC") });
// Font
int nFonts = fontTable.addFontDictionary();
// XObject
int nXObjects = delayImageQueue.addXObjects();
// Pattern
int nPatterns = delayPaintQueue.addPatterns();
// ExtGState
if (extGStates.size() > 0) {
PDFDictionary extGState = os.openDictionary("ExtGState");
for (Iterator i = extGStates.keySet().iterator(); i.hasNext();) {
Float alpha = (Float) i.next();
String alphaName = (String) extGStates.get(alpha);
PDFDictionary alphaDictionary = extGState
.openDictionary(alphaName);
alphaDictionary.entry("ca", alpha.floatValue());
alphaDictionary.entry("CA", alpha.floatValue());
alphaDictionary.entry("BM", os.name("Normal"));
alphaDictionary.entry("AIS", false);
extGState.close(alphaDictionary);
}
os.close(extGState);
}
// resources
PDFDictionary resources = os.openDictionary("Resources");
resources.entry("ProcSet", os.ref("PageProcSet"));
if (nFonts > 0)
resources.entry("Font", os.ref("FontList"));
if (nXObjects > 0)
resources.entry("XObject", os.ref("XObjects"));
if (nPatterns > 0)
resources.entry("Pattern", os.ref("Pattern"));
if (extGStates.size() > 0)
resources.entry("ExtGState", os.ref("ExtGState"));
os.close(resources);
// outlines
PDFOutlineList outlines = os.openOutlineList("Outlines", "Outline1",
"Outline" + currentPage);
os.close(outlines);
for (int i = 1; i <= currentPage; i++) {
String prev = i > 1 ? "Outline" + (i - 1) : null;
String next = i < currentPage ? "Outline" + (i + 1) : null;
PDFOutline outline = os.openOutline("Outline" + i, (String) titles
.get(i - 1), "Outlines", prev, next);
outline
.setDest(new Object[] { os.ref("Page" + i), os.name("Fit") });
os.close(outline);
}
// delayed objects (images, patterns, fonts)
processDelayed();
}
public void closeStream() throws IOException {
os.close();
}
private void processDelayed() throws IOException {
delayImageQueue.processAll();
delayPaintQueue.processAll();
fontTable.embedAll(getFontRenderContext(), isProperty(EMBED_FONTS),
getProperty(EMBED_FONTS_AS));
}
/* 3.2 MultipageDocument methods */
public void openPage(Component component) throws IOException {
openPage(component.getSize(), component.getName(), component);
}
public void openPage(Dimension size, String title) throws IOException {
openPage(size, title, null);
}
private void openPage(Dimension size, String title, Component component)
throws IOException {
if (size == null)
size = component.getSize();
resetClip(new Rectangle(0, 0, size.width, size.height));
if (pageStream != null) {
writeWarning("Page " + currentPage + " already open. "
+ "Call closePage() before starting a new one.");
return;
}
BufferedImage thumbnail = null;
// prepare thumbnail if possible
if ((component != null) && isProperty(PDFGraphics2D.THUMBNAILS)) {
thumbnail = ImageGraphics2D.generateThumbnail(component,
getPropertyDimension(PDFGraphics2D.THUMBNAIL_SIZE));
}
currentPage++;
if (title == null)
title = "Page " + currentPage + " (untitled)";
titles.add(title);
PDFPage page = os.openPage("Page" + currentPage, "RootPage");
page.setContents("PageContents" + currentPage);
if (thumbnail != null)
page.setThumb("Thumb" + currentPage);
os.close(page);
if (thumbnail != null) {
PDFStream thumbnailStream = os.openStream("Thumb" + currentPage);
thumbnailStream.image(thumbnail, Color.black, ImageConstants.ZLIB);
os.close(thumbnailStream);
}
pageStream = os.openStream("PageContents" + currentPage,
isProperty(COMPRESS) ? COMPRESS_FILTERS : NO_FILTERS);
// transform the coordinate system as necessary
// 1. flip the coordinate system down and translate it upwards again
// so that the origin is the upper left corner of the page.
AffineTransform pageTrafo = new AffineTransform();
pageTrafo.scale(1, -1);
Dimension pageSize = PageConstants.getSize(getProperty(PAGE_SIZE),
getProperty(ORIENTATION));
Insets margins = PageConstants.getMargins(
getPropertyInsets(PAGE_MARGINS), getProperty(ORIENTATION));
pageTrafo
.translate(margins.left, -(pageSize.getHeight() - margins.top));
// in between write the header and footer (which should not be scaled!)
writeHeadline(pageTrafo);
writeFootline(pageTrafo);
// 2. check whether we have to rescale the image to fit onto the page
double scaleFactor = Math.min(getWidth() / size.width, getHeight()
/ size.height);
if ((scaleFactor < 1) || isProperty(FIT_TO_PAGE)) {
pageTrafo.scale(scaleFactor, scaleFactor);
} else {
scaleFactor = 1;
}
// 3. center the image on the page
double dx = (getWidth() - size.width * scaleFactor) / 2 / scaleFactor;
double dy = (getHeight() - size.height * scaleFactor) / 2 / scaleFactor;
pageTrafo.translate(dx, dy);
writeTransform(pageTrafo);
// save the graphics context resets before setClip
writeGraphicsSave();
clipRect(0, 0, size.width, size.height);
// save the graphics context resets before setClip
writeGraphicsSave();
delayPaintQueue.setPageMatrix(pageTrafo);
writeGraphicsState();
writeBackground();
}
public void closePage() throws IOException {
if (pageStream == null) {
writeWarning("Page " + currentPage + " already closed. "
+ "Call openPage() to start a new one.");
return;
}
writeGraphicsRestore();
writeGraphicsRestore();
os.close(pageStream);
pageStream = null;
processDelayed(); // This does not work properly with acrobat reader
// 4!
}
public void setHeader(Font font, TagString left, TagString center,
TagString right, int underlineThickness) {
this.headerFont = font;
this.headerText = new TagString[3];
this.headerText[0] = left;
this.headerText[1] = center;
this.headerText[2] = right;
this.headerUnderline = underlineThickness;
}
public void setFooter(Font font, TagString left, TagString center,
TagString right, int underlineThickness) {
this.footerFont = font;
this.footerText = new TagString[3];
this.footerText[0] = left;
this.footerText[1] = center;
this.footerText[2] = right;
this.footerUnderline = underlineThickness;
}
private void writeHeadline(AffineTransform pageTrafo) throws IOException {
if (headerText != null) {
LineMetrics metrics = headerFont.getLineMetrics("mM",
getFontRenderContext());
writeLine(pageTrafo, headerFont, headerText, -metrics.getLeading()
- headerFont.getSize2D() / 2, TEXT_BOTTOM, -headerFont
.getSize2D() / 2, headerUnderline);
}
}
private void writeFootline(AffineTransform pageTrafo) throws IOException {
if (footerText != null) {
LineMetrics metrics = footerFont.getLineMetrics("mM",
getFontRenderContext());
double y = getHeight() + footerFont.getSize2D() / 2;
writeLine(pageTrafo, footerFont, footerText, y
+ metrics.getLeading(), TEXT_TOP, y, footerUnderline);
}
}
private void writeLine(AffineTransform trafo, Font font, TagString[] text,
double ty, int yAlign, double ly, int underline) throws IOException {
writeGraphicsSave();
setColor(Color.black);
setFont(font);
writeTransform(trafo);
if (text[0] != null)
drawString(text[0], 0, ty, TEXT_LEFT, yAlign);
if (text[1] != null)
drawString(text[1], getWidth() / 2, ty, TEXT_CENTER, yAlign);
if (text[2] != null)
drawString(text[2], getWidth(), ty, TEXT_RIGHT, yAlign);
if (underline >= 0) {
setLineWidth((double) underline);
drawLine(0, ly, getWidth(), ly);
}
writeGraphicsRestore();
}
/*
* ================================================================================ |
* 4. Create & Dispose
* ================================================================================
*/
public Graphics create() {
try {
writeGraphicsSave();
} catch (IOException e) {
handleException(e);
}
return new PDFGraphics2D(this, true);
}
public Graphics create(double x, double y, double width, double height) {
try {
writeGraphicsSave();
} catch (IOException e) {
handleException(e);
}
PDFGraphics2D graphics = new PDFGraphics2D(this, true);
graphics.translate(x, y);
graphics.clipRect(0, 0, width, height);
return graphics;
}
protected void writeGraphicsSave() throws IOException {
pageStream.save();
}
protected void writeGraphicsRestore() throws IOException {
pageStream.restore();
}
/*
* ================================================================================ |
* 5. Drawing Methods
* ================================================================================ /*
* 5.1.4. shapes
*/
public void draw(Shape s) {
try {
if (getStroke() instanceof BasicStroke) {
// in this case we've already handled the stroke
pageStream.drawPath(s);
pageStream.stroke();
} else {
// otherwise handle it now
pageStream.drawPath(getStroke().createStrokedShape(s));
pageStream.fill();
}
} catch (IOException e) {
handleException(e);
}
}
public void fill(Shape s) {
try {
boolean eofill = pageStream.drawPath(s);
if (eofill) {
pageStream.fillEvenOdd();
} else {
pageStream.fill();
}
} catch (IOException e) {
handleException(e);
}
}
/* 5.2 Images */
public void copyArea(int x, int y, int width, int height, int dx, int dy) {
writeWarning(getClass()
+ ": copyArea(int, int, int, int, int, int) not implemented.");
}
protected void writeImage(RenderedImage image, AffineTransform xform,
Color bkg) throws IOException {
PDFName ref = delayImageQueue.delayImage(image, bkg,
getProperty(WRITE_IMAGES_AS));
AffineTransform imageTransform = new AffineTransform(image.getWidth(),
0.0, 0.0, -image.getHeight(), 0.0, image.getHeight());
xform.concatenate(imageTransform);
writeGraphicsSave();
pageStream.matrix(xform);
pageStream.xObject(ref);
writeGraphicsRestore();
}
/* 5.3. Strings */
protected void writeString(String str, double x, double y)
throws IOException {
// save the graphics context, especially the transformation matrix
writeGraphicsSave();
// translate the offset to x and y
AffineTransform at = new AffineTransform(1, 0, 0, 1, x, y);
// transform for font
at.concatenate(getFont().getTransform());
// mirror the matrix
at.scale(1, -1);
// write transform
writeTransform(at);
pageStream.beginText();
pageStream.text(0, 0);
showCharacterCodes(str);
pageStream.endText();
// restore the transformation matrix
writeGraphicsRestore();
}
/*
* ================================================================================ |
* 6. Transformations
* ================================================================================
*/
/** Write the given transformation matrix to the file. */
protected void writeTransform(AffineTransform t) throws IOException {
pageStream.matrix(t);
}
/*
* ================================================================================ |
* 7. Clipping
* ================================================================================
*/
protected void writeSetClip(Shape s) throws IOException {
// clear old clip
try {
AffineTransform at = getTransform();
Stroke stroke = getStroke();
writeGraphicsRestore();
writeGraphicsSave();
writeStroke(stroke);
writeTransform(at);
} catch (IOException e) {
handleException(e);
}
// write clip
writeClip(s);
}
protected void writeClip(Shape s) throws IOException {
if (s == null || !isProperty(CLIP)) {
return;
}
if (s instanceof Rectangle2D) {
pageStream.move(((Rectangle2D) s).getMinX(), ((Rectangle2D) s)
.getMinY());
pageStream.line(((Rectangle2D) s).getMaxX(), ((Rectangle2D) s)
.getMinY());
pageStream.line(((Rectangle2D) s).getMaxX(), ((Rectangle2D) s)
.getMaxY());
pageStream.line(((Rectangle2D) s).getMinX(), ((Rectangle2D) s)
.getMaxY());
pageStream.closePath();
pageStream.clip();
pageStream.endPath();
} else {
boolean eoclip = pageStream.drawPath(s);
if (eoclip) {
pageStream.clipEvenOdd();
} else {
pageStream.clip();
}
pageStream.endPath();
}
}
/*
* ================================================================================ |
* 8. Graphics State
* ================================================================================
*/
/* 8.1. stroke/linewidth */
protected void writeWidth(float width) throws IOException {
pageStream.width(width);
}
protected void writeCap(int cap) throws IOException {
switch (cap) {
default:
case BasicStroke.CAP_BUTT:
pageStream.cap(0);
break;
case BasicStroke.CAP_ROUND:
pageStream.cap(1);
break;
case BasicStroke.CAP_SQUARE:
pageStream.cap(2);
break;
}
}
protected void writeJoin(int join) throws IOException {
switch (join) {
default:
case BasicStroke.JOIN_MITER:
pageStream.join(0);
break;
case BasicStroke.JOIN_ROUND:
pageStream.join(1);
break;
case BasicStroke.JOIN_BEVEL:
pageStream.join(2);
break;
}
}
protected void writeMiterLimit(float limit) throws IOException {
pageStream.mitterLimit(limit);
}
protected void writeDash(float[] dash, float phase) throws IOException {
pageStream.dash(dash, phase);
}
/* 8.2. paint/color */
public void setPaintMode() {
writeWarning(getClass() + ": setPaintMode() not implemented.");
}
public void setXORMode(Color c1) {
writeWarning(getClass() + ": setXORMode(Color) not implemented.");
}
protected void writePaint(Color c) throws IOException {
float[] cc = c.getRGBComponents(null);
// System.out.println("alpha = "+cc[3]);
Float alpha = new Float(cc[3]);
String alphaName = (String) extGStates.get(alpha);
if (alphaName == null) {
alphaName = "Alpha" + alphaIndex;
alphaIndex++;
extGStates.put(alpha, alphaName);
}
pageStream.state(os.name(alphaName));
pageStream.colorSpace(cc[0], cc[1], cc[2]);
pageStream.colorSpaceStroke(cc[0], cc[1], cc[2]);
}
protected void writePaint(GradientPaint c) throws IOException {
writePaint((Paint) c);
}
protected void writePaint(TexturePaint c) throws IOException {
writePaint((Paint) c);
}
protected void writePaint(Paint paint) throws IOException {
pageStream.colorSpace(os.name("Pattern"));
pageStream.colorSpaceStroke(os.name("Pattern"));
PDFName shadingName = delayPaintQueue.delayPaint(paint, getTransform(),
getProperty(WRITE_IMAGES_AS));
pageStream.colorSpace(null, shadingName);
pageStream.colorSpaceStroke(new double[] {}, shadingName);
}
protected void setNonStrokeColor(Color c) throws IOException {
float[] cc = c.getRGBColorComponents(null);
pageStream.colorSpace(cc[0], cc[1], cc[2]);
}
protected void setStrokeColor(Color c) throws IOException {
float[] cc = c.getRGBColorComponents(null);
pageStream.colorSpaceStroke(cc[0], cc[1], cc[2]);
}
/* 8.3. font */
protected void writeFont(Font font) throws IOException {
// written when needed
}
/*
* ================================================================================ |
* 9. Auxiliary
* ================================================================================
*/
public GraphicsConfiguration getDeviceConfiguration() {
writeWarning(getClass() + ": getDeviceConfiguration() not implemented.");
return null;
}
public void writeComment(String comment) throws IOException {
// comments are ignored and disabled, because they confuse compressed
// streams
}
public String toString() {
return "PDFGraphics2D";
}
/*
* ================================================================================ |
* 10. Private/Utility
* ================================================================================
*/
public void showString(Font font, String str) throws IOException {
String fontRef = fontTable.fontReference(font, isProperty(EMBED_FONTS),
getProperty(EMBED_FONTS_AS));
pageStream.font(os.name(fontRef), font.getSize() * FONTSIZE_CORRECTION);
pageStream.show(str);
}
/**
* See the comment of VectorGraphicsUtitlies1.
*
* @see FontUtilities#showString(java.awt.Font, String,
* org.freehep.graphics2d.font.CharTable,
* org.freehep.graphics2d.font.FontUtilities.ShowString)
*/
private void showCharacterCodes(String str) throws IOException {
FontUtilities.showString(getFont(), str, Lookup.getInstance().getTable(
"PDFLatin"), this);
}
private double getWidth() {
Dimension pageSize = PageConstants.getSize(getProperty(PAGE_SIZE),
getProperty(ORIENTATION));
Insets margins = PageConstants.getMargins(
getPropertyInsets(PAGE_MARGINS), getProperty(ORIENTATION));
return pageSize.getWidth() - margins.left - margins.right;
}
private double getHeight() {
Dimension pageSize = PageConstants.getSize(getProperty(PAGE_SIZE),
getProperty(ORIENTATION));
Insets margins = PageConstants.getMargins(
getPropertyInsets(PAGE_MARGINS), getProperty(ORIENTATION));
return pageSize.getHeight() - margins.top - margins.bottom;
}
}
src/main/java/org/freehep/graphicsio/pdf/PDFUtil.java 0000644 0001750 0001750 00000003552 11343262370 021764 0 ustar user03 user03 // Copyright 2004, FreeHEP.
package org.freehep.graphicsio.pdf;
import java.text.DecimalFormat;
import java.util.Calendar;
import org.freehep.util.ScientificFormat;
/**
* Utility functions for the PDFWriter. This class handles escaping of strings,
* formatting of dates, ...
*
* * @author Mark Donszelmann * @version $Id: PDFUtil.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFUtil implements PDFConstants { // static class private PDFUtil() { } public static String escape(String string) { StringBuffer escape = new StringBuffer(); for (int i = 0; i < string.length(); i++) { char c = string.charAt(i); switch (c) { case '(': case ')': case '\\': escape.append('\\'); escape.append(c); break; default: escape.append(c); break; } } return escape.toString(); } public static String date(Calendar date) { int offset = date.get(Calendar.ZONE_OFFSET) + date.get(Calendar.DST_OFFSET); String tz; if (offset == 0) { tz = "Z"; } else { DecimalFormat fmt = new DecimalFormat("00"); int tzh = Math.abs(offset / 3600000); int tzm = Math.abs(offset % 3600000); if (offset > 0) { tz = "+" + fmt.format(tzh) + "'" + fmt.format(tzm) + "'"; } else { tz = "-" + fmt.format(tzh) + "'" + fmt.format(tzm) + "'"; } } return "(D:" + dateFormat.format(date.getTime()) + tz + ")"; } private static final ScientificFormat scientific = new ScientificFormat(5, 100, false); public static String fixedPrecision(double v) { return scientific.format(v); } } src/main/java/org/freehep/graphicsio/pdf/PDFWriter.java 0000644 0001750 0001750 00000014616 11343262370 022326 0 ustar user03 user03 // Copyright 2000-2005 FreeHEP package org.freehep.graphicsio.pdf; import java.io.IOException; import java.io.OutputStream; /** * This class creates a PDF file/stream. It keeps track of all logical PDF * objects in the PDF file, will create a cross-reference table and do some * error checking while writing the file. *
* This class takes care of wrapping both PDFStreams and PDFDictionaries into * PDFObjects. *
* * @author Mark Donszelmann * @version $Id: PDFWriter.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFWriter extends PDF implements PDFConstants { private String open = null; public PDFWriter(OutputStream out) throws IOException { this(out, "1.3"); } public PDFWriter(OutputStream writer, String version) throws IOException { super(new PDFByteWriter(writer)); // PDF version out.println("%PDF-" + version); // Make sure intelligent readers understand that binary may be included out.print("%"); out.write(0xE2); out.write(0xE3); out.write(0xCF); out.write(0xD3); out.println(); out.println(); } public void close(String catalogName, String docInfoName) throws IOException { // FIXME, check for dangling references xref(); trailer(catalogName, docInfoName); startxref(); out.printPlain("%%EOF"); out.println(); out.close(); } public void comment(String comment) throws IOException { out.println("% " + comment); } public void object(String name, Object[] objs) throws IOException { PDFObject object = openObject(name); object.entry(objs); close(object); } public void object(String name, int number) throws IOException { PDFObject object = openObject(name); object.entry(number); close(object); } // public void object(String name, String string) throws IOException { // PDFObject object = openObject(name); // object.entry(string); // close(object); // } public PDFObject openObject(String name) throws IOException { // FIXME: check if name was already written! if (open != null) System.err .println("PDFWriter error: '" + open + "' was not closed"); open = "PDFObject: " + name; PDFRef ref = ref(name); int objectNumber = ref.getObjectNumber(); setXRef(objectNumber, out.getCount()); PDFObject obj = new PDFObject(this, out, objectNumber, ref .getGenerationNumber()); return obj; } public void close(PDFObject object) throws IOException { object.close(); open = null; } public PDFDictionary openDictionary(String name) throws IOException { PDFObject object = openObject(name); PDFDictionary dictionary = object.openDictionary(); return dictionary; } public void close(PDFDictionary dictionary) throws IOException { dictionary.close(); open = null; } private static final String lengthSuffix = "-length"; public PDFStream openStream(String name) throws IOException { return openStream(name, null); } public PDFStream openStream(String name, String[] encode) throws IOException { PDFObject object = openObject(name); PDFStream stream = object.openStream(name, encode); stream.entry("Length", ref(name + lengthSuffix)); return stream; } public void close(PDFStream stream) throws IOException { stream.close(); open = null; object(stream.getName() + lengthSuffix, stream.getLength()); } // // high level interface // private String catalogName; private String docInfoName; public void close() throws IOException { close(catalogName, docInfoName); } public PDFDocInfo openDocInfo(String name) throws IOException { docInfoName = name; PDFObject object = openObject(name); PDFDocInfo info = object.openDocInfo(this); return info; } public void close(PDFDocInfo info) throws IOException { info.close(); open = null; } public PDFCatalog openCatalog(String name, String pageTree) throws IOException { catalogName = name; PDFObject object = openObject(name); PDFCatalog catalog = object.openCatalog(this, ref(pageTree)); return catalog; } public void close(PDFCatalog catalog) throws IOException { catalog.close(); open = null; } public PDFPageTree openPageTree(String name, String parent) throws IOException { PDFObject object = openObject(name); PDFPageTree tree = object.openPageTree(this, ref(parent)); return tree; } public void close(PDFPageTree tree) throws IOException { tree.close(); open = null; } public PDFPage openPage(String name, String parent) throws IOException { PDFObject object = openObject(name); PDFPage page = object.openPage(this, ref(parent)); return page; } public void close(PDFPage page) throws IOException { page.close(); open = null; } public PDFViewerPreferences openViewerPreferences(String name) throws IOException { PDFObject object = openObject(name); PDFViewerPreferences prefs = object.openViewerPreferences(this); return prefs; } public void close(PDFViewerPreferences prefs) throws IOException { prefs.close(); open = null; } public PDFOutlineList openOutlineList(String name, String first, String next) throws IOException { PDFObject object = openObject(name); PDFOutlineList list = object.openOutlineList(this, ref(first), ref(next)); return list; } public void close(PDFOutlineList list) throws IOException { list.close(); open = null; } public PDFOutline openOutline(String name, String title, String parent, String prev, String next) throws IOException { PDFObject object = openObject(name); PDFOutline outline = object.openOutline(this, ref(parent), title, ref(prev), ref(next)); return outline; } public void close(PDFOutline outline) throws IOException { outline.close(); open = null; } } src/main/java/org/freehep/graphicsio/pdf/PDFExportFileType.java 0000644 0001750 0001750 00000010512 11343262370 023764 0 ustar user03 user03 // Copyright 2001-2007, FreeHEP. package org.freehep.graphicsio.pdf; import java.awt.Component; import java.awt.Dimension; import java.io.IOException; import java.io.OutputStream; import java.util.Properties; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; import org.freehep.graphics2d.VectorGraphics; import org.freehep.graphicsio.ImageConstants; import org.freehep.graphicsio.InfoConstants; import org.freehep.graphicsio.AbstractVectorGraphicsIO; import org.freehep.graphicsio.exportchooser.AbstractExportFileType; import org.freehep.graphicsio.exportchooser.BackgroundPanel; import org.freehep.graphicsio.exportchooser.FontPanel; import org.freehep.graphicsio.exportchooser.ImageTypePanel; import org.freehep.graphicsio.exportchooser.InfoPanel; import org.freehep.graphicsio.exportchooser.OptionCheckBox; import org.freehep.graphicsio.exportchooser.OptionComboBox; import org.freehep.graphicsio.exportchooser.OptionPanel; import org.freehep.graphicsio.exportchooser.PageLayoutPanel; import org.freehep.graphicsio.exportchooser.PageMarginPanel; import org.freehep.swing.layout.TableLayout; import org.freehep.util.UserProperties; /** * * @author Simon Fischer * @version $Id: PDFExportFileType.java 12753 2007-06-12 22:32:31Z duns $ */ public class PDFExportFileType extends AbstractExportFileType { final private static String[] versionList = { PDFGraphics2D.VERSION4, PDFGraphics2D.VERSION5 }; public String getDescription() { return "Portable Document Format"; } public String[] getExtensions() { return new String[] { "pdf" }; } public String[] getMIMETypes() { return new String[] { "application/pdf" }; } public boolean isMultipageCapable() { return true; } public boolean hasOptionPanel() { return true; } public JPanel createOptionPanel(Properties user) { UserProperties options = new UserProperties(user, PDFGraphics2D .getDefaultProperties()); OptionPanel format = new OptionPanel("Format"); OptionComboBox version = new OptionComboBox(options, PDFGraphics2D.VERSION, versionList); format.add(TableLayout.LEFT, new JLabel("PDF Version")); format.add(TableLayout.RIGHT, version); format.add(TableLayout.FULL, new OptionCheckBox(options, PDFGraphics2D.COMPRESS, "Compress")); JPanel preview = new OptionPanel("Preview"); JCheckBox thumbnails = new OptionCheckBox(options, PDFGraphics2D.THUMBNAILS, "Include Thumbnail"); thumbnails.setToolTipText("Thumbnails are automatically generated by " + "Acrobat Reader 5"); preview.add(TableLayout.FULL, thumbnails); version.selects(PDFGraphics2D.VERSION4, thumbnails); // rootKeys for FontProperties String rootKey = PDFGraphics2D.class.getName(); String abstractRootKey = AbstractVectorGraphicsIO.class.getName(); JPanel infoPanel = new InfoPanel(options, rootKey, new String[] { InfoConstants.AUTHOR, InfoConstants.TITLE, InfoConstants.SUBJECT, InfoConstants.KEYWORDS }); // TableLayout.LEFT Panel JPanel leftPanel = new OptionPanel(); leftPanel .add(TableLayout.COLUMN, new PageLayoutPanel(options, rootKey)); leftPanel .add(TableLayout.COLUMN, new PageMarginPanel(options, rootKey)); leftPanel.add(TableLayout.COLUMN_FILL, new JLabel()); // TableLayout.RIGHT Panel JPanel rightPanel = new OptionPanel(); rightPanel.add(TableLayout.COLUMN, format); rightPanel.add(TableLayout.COLUMN, preview); rightPanel.add(TableLayout.COLUMN, new BackgroundPanel(options, rootKey, true)); rightPanel.add(TableLayout.COLUMN, new ImageTypePanel(options, rootKey, new String[] { ImageConstants.SMALLEST, ImageConstants.ZLIB, ImageConstants.JPG })); rightPanel.add(TableLayout.COLUMN, new FontPanel(options, rootKey, abstractRootKey)); rightPanel.add(TableLayout.COLUMN_FILL, new JLabel()); // Make the full panel. OptionPanel optionsPanel = new OptionPanel(); optionsPanel.add("0 0 [5 5 5 5] wt", leftPanel); optionsPanel.add("1 0 [5 5 5 5] wt", rightPanel); optionsPanel.add("0 1 2 1 [5 5 5 5] wt", infoPanel); optionsPanel.add(TableLayout.COLUMN_FILL, new JLabel()); return optionsPanel; } public VectorGraphics getGraphics(OutputStream os, Component target) throws IOException { return new PDFGraphics2D(os, target); } public VectorGraphics getGraphics(OutputStream os, Dimension dimension) throws IOException { return new PDFGraphics2D(os, dimension); } } src/main/java/org/freehep/graphicsio/pdf/PDFFontEmbedder.java 0000644 0001750 0001750 00000007431 11343262370 023405 0 ustar user03 user03 // Copyright 2001-2005 freehep package org.freehep.graphicsio.pdf; import java.awt.font.FontRenderContext; import java.io.IOException; import org.freehep.graphics2d.font.CharTable; import org.freehep.graphicsio.font.FontEmbedder; /** * Superclass of all FontEmbedders for PDF documents. Subclasses must implement * all abstract methods which are called in the following order: *
* * @author Mark Donszelmann * @version $Id: PDF.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDF { private int generationNumber = 0; private Hashtable refsByName = new Hashtable(); // of PDFRefs stored by name private Vector refsByNumber = new Vector(); // of PDFRefs stored by number private Vector xrefsByNumber = new Vector(); // of offsets stored by // refnumber private int startXref = 0; protected PDFByteWriter out; PDF(PDFByteWriter out) { this.out = out; // add dummy element to refsByNumber and xrefsByNumber refsByNumber.addElement(new PDFRef("Dummy", 0, 0)); xrefsByNumber.addElement(new Integer(999999)); } public PDFName name(String name) { return new PDFName(name); } public PDFRef ref(String name) { if (name == null) return null; PDFRef ref = (PDFRef) refsByName.get(name); if (ref == null) { int refNumber = refsByNumber.size(); ref = new PDFRef(name, refNumber, generationNumber); refsByName.put(name, ref); refsByNumber.add(ref); xrefsByNumber.add(null); } return ref; } public PDFRef[] ref(String[] names) { PDFRef[] refs = new PDFRef[names.length]; for (int i = 0; i < names.length; i++) { refs[i] = ref(names[i]); } return refs; } protected void setXRef(int objectNumber, int offset) { xrefsByNumber.set(objectNumber, new Integer(offset)); } protected void xref() throws IOException { DecimalFormat offsetFormat = new DecimalFormat("0000000000"); DecimalFormat linkFormat = new DecimalFormat("00000"); startXref = out.getCount(); out.printPlain("xref"); out.println(); out.printPlain(0 + " " + xrefsByNumber.size()); out.println(); // the free list header out.printPlain(offsetFormat.format(0) + " " + linkFormat.format(65535) + " f\r\n"); // the used list for (int i = 1; i < xrefsByNumber.size(); i++) { Integer offsetObject = (Integer) xrefsByNumber.get(i); if (offsetObject != null) { int offset = offsetObject.intValue(); out.printPlain(offsetFormat.format(offset) + " " + linkFormat.format(0) + " n\r\n"); } else { PDFRef ref = (PDFRef) refsByNumber.get(i); System.err.println("PDFWriter: PDFRef '" + ref.getName() + "' is used but not defined."); } } out.println(); } protected void trailer(String rootName, String docInfoName) throws IOException { out.println("trailer"); PDFDictionary dictionary = new PDFDictionary(this, out); dictionary.entry("Size", refsByName.size()); dictionary.entry("Root", ref(rootName)); if (docInfoName != null) dictionary.entry("Info", ref(docInfoName)); dictionary.close(); out.println(); } protected void startxref() throws IOException { out.println("startxref"); out.println(startXref); out.println(); } } src/main/java/org/freehep/graphicsio/pdf/PDFConstants.java 0000644 0001750 0001750 00000002514 11343262370 023020 0 ustar user03 user03 package org.freehep.graphicsio.pdf; import java.text.SimpleDateFormat; /** * Specifies constants for use with the PDFWriter, PDFStream and PDFUtil. *
* * @author Mark Donszelmann * @version $Id: PDFConstants.java 8584 2006-08-10 23:06:37Z duns $ */ public interface PDFConstants { public final static String EOL = System.getProperty("line.separator"); // // Constants for PDFStream // // Line Cap Styles (see Table 4.4) public static final int CAP_BUTT = 0; public static final int CAP_ROUND = 1; public static final int CAP_SQUARE = 2; // Line Join Styles (see Table 4.5) public static final int JOIN_MITTER = 0; public static final int JOIN_ROUND = 1; public static final int JOIN_BEVEL = 2; // Rendering Modes (see Table 5.3) public static final int MODE_FILL = 0; public static final int MODE_STROKE = 1; public static final int MODE_FILL_STROKE = 2; public static final int MODE_INVISIBLE = 3; public static final int MODE_FILL_CLIP = 4; public static final int MODE_STROKE_CLIP = 5; public static final int MODE_FILL_STROKE_CLIP = 6; public static final int MODE_CLIP = 7; // Date Format for PDF: (D:YYYYMMDDHHmmSSOHH'mm') public static final SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyyMMddHHmmss"); } src/main/java/org/freehep/graphicsio/pdf/PDFFontEmbedderType1.java 0000644 0001750 0001750 00000011422 11343262370 024323 0 ustar user03 user03 // Copyright 2001-2005 freehep package org.freehep.graphicsio.pdf; import java.awt.font.FontRenderContext; import java.awt.font.LineMetrics; import java.awt.geom.Rectangle2D; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.freehep.graphicsio.font.FontEmbedderType1; /** * Font embedder for type one fonts in pdf documents. * * @author Simon Fischer * @version $Id: PDFFontEmbedderType1.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFFontEmbedderType1 extends FontEmbedderType1 { private ByteArrayOutputStream byteBuffer; private String reference; private PDFWriter pdf; private PDFStream fontFile; private PDFRedundanceTracker redundanceTracker; public static PDFFontEmbedderType1 create(FontRenderContext context, PDFWriter pdf, String reference, PDFRedundanceTracker tracker) { return new PDFFontEmbedderType1(context, pdf, reference, new ByteArrayOutputStream(), tracker); } private PDFFontEmbedderType1(FontRenderContext context, PDFWriter pdf, String reference, ByteArrayOutputStream byteOut, PDFRedundanceTracker tracker) { super(context, byteOut, false); this.byteBuffer = byteOut; this.pdf = pdf; this.reference = reference; this.redundanceTracker = tracker; } private String getReference() { return reference; } // FIXME: The StemV entry is missing in the FontDescriptor dictionary, but // it // does not cause the Acrobat Reader to crash. protected void openIncludeFont() throws IOException { super.openIncludeFont(); PDFDictionary fontDict = pdf.openDictionary(reference); fontDict.entry("Type", pdf.name("Font")); fontDict.entry("Subtype", pdf.name("Type1")); fontDict.entry("Name", pdf.name(getFontName())); fontDict.entry("FirstChar", 0); fontDict.entry("LastChar", 255); // fontDict.entry("Encoding", pdf.ref(reference+"Encoding")); fontDict.entry("Encoding", redundanceTracker.getReference( getEncodingTable(), PDFCharTableWriter.getInstance())); fontDict.entry("Widths", pdf.ref(reference + "Widths")); fontDict.entry("BaseFont", pdf.name(getFontName())); // = FontName in // font program fontDict.entry("FontDescriptor", pdf.ref(getReference() + "FontDescriptor")); pdf.close(fontDict); PDFDictionary fontDescriptor = pdf.openDictionary(getReference() + "FontDescriptor"); fontDescriptor.entry("Type", pdf.name("FontDescriptor")); LineMetrics metrics = getFont().getLineMetrics("mM", getContext()); fontDescriptor.entry("Ascent", metrics.getAscent()); fontDescriptor.entry("Descent", metrics.getDescent()); fontDescriptor.entry("FontName", pdf.name(getFontName())); fontDescriptor.entry("Flags", 32); fontDescriptor.entry("CapHeight", metrics.getAscent()); fontDescriptor.entry("ItalicAngle", getFont().getItalicAngle()); // fontDescriptor.entry("StemV", 0); Rectangle2D boundingBox = getFontBBox(); double llx = boundingBox.getX(); double lly = boundingBox.getY(); double urx = boundingBox.getX() + boundingBox.getWidth(); double ury = boundingBox.getY() + boundingBox.getHeight(); fontDescriptor.entry("FontBBox", new double[] { llx, lly, urx, ury }); fontDescriptor.entry("FontFile", pdf.ref(getReference() + "FontFile")); pdf.close(fontDescriptor); } protected void writeWidths(double[] widths) throws IOException { super.writeWidths(widths); Object[] widthsObj = new Object[256]; for (int i = 0; i < widthsObj.length; i++) widthsObj[i] = new Integer((int) Math.round(widths[i])); pdf.object(reference + "Widths", widthsObj); } // protected void writeEncoding(CharTable charTable) throws IOException { // super.writeEncoding(charTable); // FontEmbedderPDF.writeEncoding(pdf, getReference()+"Encoding", charTable); // } protected void openGlyphs() throws IOException { super.openGlyphs(); } protected void closeEmbedFont() throws IOException { super.closeEmbedFont(); fontFile = pdf.openStream(getReference() + "FontFile", new String[] { "Flate", "ASCII85" }); fontFile.entry("Length1", getAsciiLength()); fontFile.entry("Length2", getEncryptedLength()); fontFile.entry("Length3", 0); // leave it to the viewer application to // add the 512 zeros String file = byteBuffer.toString("US-ASCII"); fontFile.print(file); pdf.close(fontFile); } } src/main/java/org/freehep/graphicsio/pdf/PDFObject.java 0000644 0001750 0001750 00000013130 11343262370 022246 0 ustar user03 user03 package org.freehep.graphicsio.pdf; import java.io.IOException; /** * Implements a numbered PDFObject. *
* * @author Mark Donszelmann * @version $Id: PDFObject.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFObject implements PDFConstants { protected PDF pdf; private PDFByteWriter out; private String open; private boolean ok; PDFObject(PDF pdf, PDFByteWriter writer, int objectNumber, int generationNumber) throws IOException { this.pdf = pdf; out = writer; out.println(objectNumber + " " + generationNumber + " obj"); out.indent(); ok = true; } void close() throws IOException { out.outdent(); out.println("endobj"); out.println(); ok = false; } public void entry(int number) throws IOException { if (!ok) System.err.println("PDFWriter: 'PDFObject' was closed"); out.println(number); } public void entry(Object[] objs) throws IOException { if (!ok) System.err.println("PDFWriter: 'PDFObject' was closed"); out.print("["); for (int i = 0; i < objs.length; i++) { if (i != 0) out.printPlain(" "); out.printPlain(objs[i]); } out.printPlain("]"); out.println(); } // public void entry(String string) throws IOException { // if (!ok) System.err.println("PDFWriter: 'PDFObject' was closed"); // out.println("("+PDFUtil.escape(string)+")"); // } PDFDictionary openDictionary() throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFDictionary' was closed"); if (open != null) System.err .println("PDFWriter error: '" + open + "' was not closed"); open = "PDFDictionary"; PDFDictionary dictionary = new PDFDictionary(pdf, out, this); return dictionary; } void close(PDFDictionary dictionary) throws IOException { dictionary.close(); open = null; } PDFStream openStream(String name, String[] encode) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFStream' was closed"); if (open != null) System.err .println("PDFWriter error: '" + open + "' was not closed"); open = "PDFStream"; PDFStream stream = new PDFStream(pdf, out, name, this, encode); return stream; } void close(PDFStream stream) throws IOException { stream.close(); open = null; } PDFDocInfo openDocInfo(PDF pdf) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFDocInfo' was closed"); if (open != null) System.err .println("PDFWriter error: '" + open + "' was not closed"); open = "PDFDocInfo"; PDFDocInfo info = new PDFDocInfo(pdf, out, this); return info; } PDFCatalog openCatalog(PDF pdf, PDFRef pageTree) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFCatalog' was closed"); if (open != null) System.err .println("PDFWriter error: '" + open + "' was not closed"); open = "PDFCatalog"; PDFCatalog catalog = new PDFCatalog(pdf, out, this, pageTree); return catalog; } PDFPageTree openPageTree(PDF pdf, PDFRef parent) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFPageTree' was closed"); if (open != null) System.err .println("PDFWriter error: '" + open + "' was not closed"); open = "PDFPageTree"; PDFPageTree tree = new PDFPageTree(pdf, out, this, parent); return tree; } PDFPage openPage(PDF pdf, PDFRef parent) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFPage' was closed"); if (open != null) System.err .println("PDFWriter error: '" + open + "' was not closed"); open = "PDFPage"; PDFPage page = new PDFPage(pdf, out, this, parent); return page; } PDFViewerPreferences openViewerPreferences(PDF pdf) throws IOException { if (!ok) System.err .println("PDFWriter error: 'PDFViewerPreferences' was closed"); if (open != null) System.err .println("PDFWriter error: '" + open + "' was not closed"); open = "PDFViewerPreferences"; PDFViewerPreferences prefs = new PDFViewerPreferences(pdf, out, this); return prefs; } PDFOutlineList openOutlineList(PDF pdf, PDFRef first, PDFRef last) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFOutlineList' was closed"); if (open != null) System.err .println("PDFWriter error: '" + open + "' was not closed"); open = "PDFOutlineList"; PDFOutlineList list = new PDFOutlineList(pdf, out, this, first, last); return list; } PDFOutline openOutline(PDF pdf, PDFRef parent, String title, PDFRef prev, PDFRef next) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFOutline' was closed"); if (open != null) System.err .println("PDFWriter error: '" + open + "' was not closed"); open = "PDFOutline"; PDFOutline outline = new PDFOutline(pdf, out, this, parent, title, prev, next); return outline; } } src/main/java/org/freehep/graphicsio/pdf/PDFViewerPreferences.java 0000644 0001750 0001750 00000002356 11343262370 024473 0 ustar user03 user03 package org.freehep.graphicsio.pdf; import java.io.IOException; /** * Implements the Viewer Preferences (see Table 7.1). *
* * @author Mark Donszelmann * @version $Id: PDFViewerPreferences.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFViewerPreferences extends PDFDictionary { PDFViewerPreferences(PDF pdf, PDFByteWriter writer, PDFObject object) throws IOException { super(pdf, writer, object); } public void setHideToolbar(boolean hide) throws IOException { entry("HideToolbar", hide); } public void setHideMenubar(boolean hide) throws IOException { entry("HideMenubar", hide); } public void setHideWindowUI(boolean hide) throws IOException { entry("HideWindowUI", hide); } public void setFitWindow(boolean fit) throws IOException { entry("FitWindow", fit); } public void setCenterWindow(boolean center) throws IOException { entry("CenterWindow", center); } public void setNonFullScreenPageMode(String mode) throws IOException { entry("NonFullScreenPageMode", pdf.name(mode)); } public void setDirection(String direction) throws IOException { entry("Direction", pdf.name(direction)); } } src/main/java/org/freehep/graphicsio/pdf/PDFDictionary.java 0000644 0001750 0001750 00000012003 11343262370 023143 0 ustar user03 user03 package org.freehep.graphicsio.pdf; import java.io.IOException; import java.util.Calendar; /** * Implements a PDF Dictionary. All PDFObjects (including java Strings and * arrays) can be entered into the dictionary. *
* * @author Mark Donszelmann * @version $Id: PDFDictionary.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFDictionary implements PDFConstants { private String open = null; protected PDFByteWriter out; private boolean ok; private PDFObject object; protected PDF pdf; PDFDictionary(PDF pdf, PDFByteWriter writer) throws IOException { this(pdf, writer, null); } PDFDictionary(PDF pdf, PDFByteWriter writer, PDFObject parent) throws IOException { this.pdf = pdf; object = parent; out = writer; out.println("<< "); out.indent(); ok = true; } void close() throws IOException { if (open != null) System.err .println("PDFWriter error: '" + open + "' was not closed"); out.outdent(); out.println(">>"); if (object != null) object.close(); ok = false; } public void entry(String key, String string) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFDictionary' was closed"); out.println("/" + key + " (" + PDFUtil.escape(string) + ")"); } public void entry(String key, PDFName name) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFDictionary' was closed"); out.println("/" + key + " " + name); } public void entry(String key, int number) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFDictionary' was closed"); out.println("/" + key + " " + number); } public void entry(String key, double number) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFDictionary' was closed"); out.println("/" + key + " " + PDFUtil.fixedPrecision(number)); } public void entry(String key, boolean bool) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFDictionary' was closed"); out.println("/" + key + " " + (bool ? "true" : "false")); } public void entry(String key, PDFRef ref) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFDictionary' was closed"); out.println("/" + key + " " + ref); } public void entry(String key, Calendar date) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFDictionary' was closed"); out.println("/" + key + " " + PDFUtil.date(date)); } public void entry(String key, Object[] objs) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFDictionary' was closed"); out.print("/" + key + " ["); for (int i = 0; i < objs.length; i++) { if (i != 0) out.printPlain(" "); out.printPlain(objs[i]); } out.printPlain("]"); out.println(); } public void entry(String key, int[] numbers) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFDictionary' was closed"); out.print("/" + key + " ["); for (int i = 0; i < numbers.length; i++) { if (i != 0) out.printPlain(" "); out.printPlain(numbers[i]); } out.printPlain("]"); out.println(); } public void entry(String key, double[] numbers) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFDictionary' was closed"); out.print("/" + key + " ["); for (int i = 0; i < numbers.length; i++) { if (i != 0) out.printPlain(" "); out.printPlain(PDFUtil.fixedPrecision(numbers[i])); } out.printPlain("]"); out.println(); } public void entry(String key, boolean[] bool) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFDictionary' was closed"); out.print("/" + key + " ["); for (int i = 0; i < bool.length; i++) { if (i != 0) out.printPlain(" "); out.printPlain(bool[i] ? "true" : "false"); } out.printPlain("]"); out.println(); } public PDFDictionary openDictionary(String name) throws IOException { if (!ok) System.err.println("PDFWriter error: 'PDFDictionary' was closed"); if (open != null) System.err .println("PDFWriter error: '" + open + "' was not closed"); open = "PDFDictionary: " + name; out.println("/" + name); PDFDictionary dictionary = new PDFDictionary(pdf, out); return dictionary; } public void close(PDFDictionary dictionary) throws IOException { dictionary.close(); open = null; } } src/main/java/org/freehep/graphicsio/pdf/PDFOutline.java 0000644 0001750 0001750 00000002545 11343262370 022467 0 ustar user03 user03 package org.freehep.graphicsio.pdf; import java.io.IOException; /** * Implements the Outline Item Dictionary (see Table 7.4). *
* * @author Mark Donszelmann * @version $Id: PDFOutline.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFOutline extends PDFDictionary { PDFOutline(PDF pdf, PDFByteWriter writer, PDFObject object, PDFRef parent, String title, PDFRef prev, PDFRef next) throws IOException { super(pdf, writer, object); entry("Parent", parent); entry("Title", title); entry("Prev", prev); entry("Next", next); } public void setFirst(String first) throws IOException { entry("First", pdf.ref(first)); } public void setLast(String last) throws IOException { entry("Last", pdf.ref(last)); } public void setCount(int count) throws IOException { entry("Count", count); } public void setDest(PDFName dest) throws IOException { entry("Dest", dest); } public void setDest(String dest) throws IOException { entry("Dest", dest); } public void setDest(Object[] dest) throws IOException { entry("Dest", dest); } public void setA(String a) throws IOException { entry("A", pdf.ref(a)); } public void setSE(String se) throws IOException { entry("SE", pdf.ref(se)); } } src/main/java/org/freehep/graphicsio/pdf/PDFDocInfo.java 0000644 0001750 0001750 00000002624 11343262370 022367 0 ustar user03 user03 package org.freehep.graphicsio.pdf; import java.io.IOException; import java.util.Calendar; /** * Implements the Document Information Dictionary (see Table 8.2). *
* * @author Mark Donszelmann * @version $Id: PDFDocInfo.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFDocInfo extends PDFDictionary { PDFDocInfo(PDF pdf, PDFByteWriter writer, PDFObject parent) throws IOException { super(pdf, writer, parent); } public void setTitle(String title) throws IOException { entry("Title", title); } public void setAuthor(String author) throws IOException { entry("Author", author); } public void setSubject(String subject) throws IOException { entry("Subject", subject); } public void setKeywords(String keywords) throws IOException { entry("Keywords", keywords); } public void setCreator(String creator) throws IOException { entry("Creator", creator); } public void setProducer(String producer) throws IOException { entry("Producer", producer); } public void setCreationDate(Calendar date) throws IOException { entry("CreationDate", date); } public void setModificationDate(Calendar date) throws IOException { entry("ModDate", date); } public void setTrapped(String name) throws IOException { entry("Trapped", pdf.name(name)); } } src/main/java/org/freehep/graphicsio/pdf/PDFFontIncluder.java 0000644 0001750 0001750 00000007723 11343262370 023447 0 ustar user03 user03 // Copyright 2001-2005 freehep package org.freehep.graphicsio.pdf; import java.awt.Font; import java.awt.font.FontRenderContext; import java.io.IOException; import org.freehep.graphics2d.font.CharTable; import org.freehep.graphicsio.font.FontIncluder; /** * Includes one of the 14 Type1 fonts in PDF documents * * @author Simon Fischer * @version $id$ */ public class PDFFontIncluder extends FontIncluder { private static final int PLAIN = 0; private static final int BOLD = 1; private static final int ITALIC = 2; private static final int BOLDITALIC = 3; private static final int COURIER = 0; private static final int HELVETICA = 1; private static final int TIMES = 2; private static final int SYMBOL = 3; private static final int DINGBATS = 4; private static final String[][] STANDARD_FONT = { { "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique" }, { "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique" }, { "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic" }, { "Symbol" }, { "ZapfDingbats" } }; private PDFWriter pdf; private String reference; private PDFRedundanceTracker redundanceTracker; public PDFFontIncluder(FontRenderContext context, PDFWriter pdf, String reference, PDFRedundanceTracker redundanceTracker) { super(context); this.pdf = pdf; this.reference = reference; this.redundanceTracker = redundanceTracker; } protected void openIncludeFont() throws IOException { int style = getFontStyle(getFont()); int fontBaseIndex = getFontBaseIndex(getFont()); PDFDictionary font = pdf.openDictionary(reference); font.entry("Type", pdf.name("Font")); font.entry("Subtype", pdf.name("Type1")); font.entry("Name", pdf.name(reference)); font.entry("BaseFont", pdf.name(STANDARD_FONT[fontBaseIndex][style])); // font.entry("Encoding", pdf.ref(reference+"Encoding")); font.entry("Encoding", redundanceTracker.getReference( getEncodingTable(), PDFCharTableWriter.getInstance())); pdf.close(font); } protected void writeEncoding(CharTable charTable) throws IOException { } public static boolean isStandardFont(Font font) { String fontName = font.getName().toLowerCase(); return (fontName.indexOf("helvetica") >= 0) || (fontName.indexOf("times") >= 0) || (fontName.indexOf("courier") >= 0) || (fontName.indexOf("symbol") >= 0) || (fontName.indexOf("dingbats") >= 0); } /** Returns the index of the standard font according to STANDARD_FONT. */ private static int getFontBaseIndex(Font font) { String fontName = font.getName().toLowerCase(); if (fontName.indexOf("helvetica") >= 0) { return HELVETICA; } else if (fontName.indexOf("times") >= 0) { return TIMES; } else if (fontName.indexOf("courier") >= 0) { return COURIER; } else if (fontName.indexOf("symbol") >= 0) { return SYMBOL; } else if (fontName.indexOf("dingbats") >= 0) { return DINGBATS; } else { // use HELVETICA as default return HELVETICA; } } /** Returns the index of the respective entry in STANDARD_FONT[fontIndex]. */ private static int getFontStyle(Font font) { int fontBase = getFontBaseIndex(font); if ((fontBase >= 0) && (STANDARD_FONT[fontBase].length == 1)) return PLAIN; if (fontBase < 0) return -1; if (font.isBold()) { if (font.isItalic()) { return BOLDITALIC; } else { return BOLD; } } else { if (font.isItalic()) return ITALIC; } return PLAIN; } } src/main/java/org/freehep/graphicsio/pdf/PDFOutlineList.java 0000644 0001750 0001750 00000001226 11343262370 023316 0 ustar user03 user03 package org.freehep.graphicsio.pdf; import java.io.IOException; /** * Implements the Outline Dictionary (see Table 7.3). *
* * @author Mark Donszelmann * @version $Id: PDFOutlineList.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFOutlineList extends PDFDictionary { PDFOutlineList(PDF pdf, PDFByteWriter writer, PDFObject object, PDFRef first, PDFRef last) throws IOException { super(pdf, writer, object); entry("Type", pdf.name("Outlines")); entry("First", first); entry("Last", last); } public void setCount(int count) throws IOException { entry("Count", count); } } src/main/java/org/freehep/graphicsio/pdf/ImageBytes.java 0000644 0001750 0001750 00000007327 11343262370 022552 0 ustar user03 user03 // Copyright 2000-2007 FreeHEP package org.freehep.graphicsio.pdf; import org.freehep.graphicsio.ImageConstants; import org.freehep.graphicsio.ImageGraphics2D; import java.awt.image.RenderedImage; import java.awt.Color; import java.io.IOException; /** * PDF writes images as ZLIB or JPEG. This class converts an image to a * byte[]. If neither {@link ImageConstants#ZLIB} nor * {@link ImageConstants#JPEG} is passed the smallest size is stored * for {@link #getBytes()}. The method {@link #getFormat()} returns the * used format. * * @author Steffen Greiffenberg * @version $Revision$ */ class ImageBytes { /** * Used format during creation of bytes */ private String format; /** * Bytes in given format */ private byte[] bytes; /** * Encodes the passed image * * @param image image to convert * @param bkg background color * @param format format could be {@link ImageConstants#ZLIB} or {@link ImageConstants#JPEG} * @param colorModel e.g. {@link org.freehep.graphicsio.ImageConstants#COLOR_MODEL_RGB} * @throws IOException thrown by {@link org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, String, String, java.util.Properties)} */ public ImageBytes(RenderedImage image, Color bkg, String format, String colorModel) throws IOException { // ZLIB encoding, transparent images allways require ZLIB if (ImageConstants.ZLIB.equals(format) || (image.getColorModel().hasAlpha() && (bkg == null))) { bytes = toZLIB(image, bkg, colorModel); this.format = ImageConstants.ZLIB; } // JPG encoding else if (ImageConstants.JPEG.equals(format)) { bytes = toJPG(image); this.format = ImageConstants.JPG; } else { // calculate both byte arrays byte[] jpgBytes = toJPG(image); byte[] zlibBytes = toZLIB(image, bkg, colorModel); // compare sizes to determine smalles format if (jpgBytes.length < 0.5 * zlibBytes.length) { bytes = jpgBytes; this.format = ImageConstants.JPG; } else { bytes = zlibBytes; this.format = ImageConstants.ZLIB; } } } /** * Creates the ZLIB Bytes for PDF images * * @param image image to convert * @param bkg background color * @param colorModel e.g. {@link org.freehep.graphicsio.ImageConstants#COLOR_MODEL_RGB} * @return bytes * @throws IOException thrown by {@link org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, String, String, java.util.Properties)} */ private byte[] toZLIB(RenderedImage image, Color bkg, String colorModel) throws IOException { return ImageGraphics2D.toByteArray( image, ImageConstants.RAW, ImageConstants.ENCODING_FLATE_ASCII85, ImageGraphics2D.getRAWProperties(bkg, colorModel)); } /** * Creates the JPG bytes for PDF images * * @param image image to convert * @return bytes * @throws IOException thrown by {@link org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, String, String, java.util.Properties)} */ private byte[] toJPG(RenderedImage image) throws IOException { return ImageGraphics2D.toByteArray( image, ImageConstants.JPG, ImageConstants.ENCODING_ASCII85, null); } /** * @return bytes */ public byte[] getBytes() { return bytes; } /** * @return used encoding format */ public String getFormat() { return format; } } /** * $Log$ */ src/main/java/org/freehep/graphicsio/pdf/PDFPageTree.java 0000644 0001750 0001750 00000001507 11343262370 022541 0 ustar user03 user03 package org.freehep.graphicsio.pdf; import java.io.IOException; import java.util.Vector; /** * Implements the Page Tree Node (see Table 3.16). *
* * @author Mark Donszelmann * @version $Id: PDFPageTree.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFPageTree extends PDFPageBase { Vector pages = new Vector(); PDFPageTree(PDF pdf, PDFByteWriter writer, PDFObject object, PDFRef parent) throws IOException { super(pdf, writer, object, parent); entry("Type", pdf.name("Pages")); } public void addPage(String name) { pages.add(pdf.ref(name)); } void close() throws IOException { Object[] kids = new Object[pages.size()]; pages.copyInto(kids); entry("Kids", kids); entry("Count", kids.length); super.close(); } } src/main/java/org/freehep/graphicsio/pdf/PDFRef.java 0000644 0001750 0001750 00000002014 11343262370 021553 0 ustar user03 user03 package org.freehep.graphicsio.pdf; /** * This class implements a numbered reference to a PDFObject. Internally the * class keeps track of the numbers. The user only sees its logical name. Only * generation 0 is used in this PDFWriter, since we do not allow for updates of * the PDF file. *
* * @author Mark Donszelmann * @version $Id: PDFRef.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFRef implements PDFConstants { private String name; private int objectNumber; private int generationNumber; PDFRef(String name, int objectNumber, int generationNumber) { this.name = name; this.objectNumber = objectNumber; this.generationNumber = generationNumber; } public String getName() { return name; } public int getObjectNumber() { return objectNumber; } public int getGenerationNumber() { return generationNumber; } public String toString() { return objectNumber + " " + generationNumber + " R"; } } src/main/java/org/freehep/graphicsio/pdf/PDFFontEmbedderType3.java 0000644 0001750 0001750 00000006015 11343262370 024327 0 ustar user03 user03 // Copyright 2001-2005 freehep package org.freehep.graphicsio.pdf; import java.awt.Shape; import java.awt.font.FontRenderContext; import java.awt.font.GlyphMetrics; import java.awt.geom.Rectangle2D; import java.io.IOException; /** * @author Simon Fischer * @version $Id: PDFFontEmbedderType3.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFFontEmbedderType3 extends PDFFontEmbedder { public PDFFontEmbedderType3(FontRenderContext context, PDFWriter pdf, String reference, PDFRedundanceTracker tracker) { super(context, pdf, reference, tracker); } protected String getSubtype() { return "Type3"; } protected void addAdditionalEntries(PDFDictionary fontDict) throws IOException { Rectangle2D boundingBox = getFontBBox(); double llx = boundingBox.getX(); double lly = boundingBox.getY(); double urx = boundingBox.getX() + boundingBox.getWidth(); double ury = boundingBox.getY() + boundingBox.getHeight(); fontDict.entry("FontBBox", new double[] { llx, lly, urx, ury }); fontDict.entry("FontMatrix", new double[] { 1 / FONT_SIZE, 0, 0, 1 / FONT_SIZE, 0, 0 }); fontDict.entry("CharProcs", pdf.ref(getReference() + "CharProcs")); PDFDictionary resources = fontDict.openDictionary("Resources"); resources.entry("ProcSet", new Object[] { pdf.name("PDF") }); fontDict.close(resources); } protected void addAdditionalInitDicts() throws IOException { // CharProcs PDFDictionary charProcs = pdf.openDictionary(getReference() + "CharProcs"); // boolean undefined = false; for (int i = 0; i < 256; i++) { String charName = getEncodingTable().toName(i); if (charName != null) { charProcs.entry(charName, pdf .ref(createCharacterReference(charName))); } else { // undefined = true; } } // if (undefined) charProcs.entry(NOTDEF, pdf.ref(createCharacterReference(NOTDEF))); pdf.close(charProcs); } protected void writeGlyph(String characterName, Shape glyph, GlyphMetrics glyphMetrics) throws IOException { PDFStream glyphStream = pdf.openStream( createCharacterReference(characterName), new String[] { "Flate", "ASCII85" }); Rectangle2D bounds = glyphMetrics != null ? glyphMetrics.getBounds2D() : glyph.getBounds2D(); double advance = glyphMetrics != null ? glyphMetrics.getAdvance() : getUndefinedWidth(); glyphStream.glyph(advance, 0, bounds.getX(), bounds.getY(), bounds .getX() + bounds.getWidth(), bounds.getY() + bounds.getHeight()); boolean windingRule = glyphStream.drawPath(glyph); if (windingRule) { glyphStream.fillEvenOdd(); } else { glyphStream.fill(); } pdf.close(glyphStream); } } src/main/java/org/freehep/graphicsio/pdf/PDFPage.java 0000644 0001750 0001750 00000004722 11343262370 021723 0 ustar user03 user03 package org.freehep.graphicsio.pdf; import java.io.IOException; import java.util.Calendar; /** * Implements the Page Object (see Table 3.17). Inheritable Page Attributes are * in PDFPageBase. *
* * @author Mark Donszelmann * @version $Id: PDFPage.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFPage extends PDFPageBase { PDFPage(PDF pdf, PDFByteWriter writer, PDFObject object, PDFRef parent) throws IOException { super(pdf, writer, object, parent); entry("Type", pdf.name("Page")); } public void setBleedBox(double x, double y, double w, double h) throws IOException { double[] rectangle = { x, y, w, h }; entry("BleedBox", rectangle); } public void setTrimBox(double x, double y, double w, double h) throws IOException { double[] rectangle = { x, y, w, h }; entry("TrimBox", rectangle); } public void setArtBox(double x, double y, double w, double h) throws IOException { double[] rectangle = { x, y, w, h }; entry("ArtBox", rectangle); } public void setContents(String content) throws IOException { entry("Contents", pdf.ref(content)); } public void setThumb(String thumb) throws IOException { entry("Thumb", pdf.ref(thumb)); } public void setB(String[] b) throws IOException { entry("B", pdf.ref(b)); } public void setDur(double dur) throws IOException { entry("Dur", dur); } public void setTrans(String trans) throws IOException { entry("Trans", pdf.ref(trans)); } public void setAnnots(String[] annots) throws IOException { entry("Annots", pdf.ref(annots)); } public void setAA(String aa) throws IOException { entry("AA", pdf.ref(aa)); } public void setPieceInfo(String pieceInfo) throws IOException { entry("PieceInfo", pdf.ref(pieceInfo)); } public void setLastModified(Calendar date) throws IOException { entry("LastModified", date); } public void setStructParents(int structParents) throws IOException { entry("StructParents", structParents); } public void setID(String id) throws IOException { entry("ID", id); } public void setPZ(double pz) throws IOException { entry("PZ", pz); } public void setSeparationInfo(String separationInfo) throws IOException { entry("SeparationInfo", pdf.ref(separationInfo)); } } src/main/java/org/freehep/graphicsio/pdf/PDFFontTable.java 0000644 0001750 0001750 00000010344 11343262370 022722 0 ustar user03 user03 // Copyright 2001-2003, FreeHEP. package org.freehep.graphicsio.pdf; import java.awt.Font; import java.awt.font.FontRenderContext; import java.io.IOException; import java.util.Collection; import java.util.Iterator; import java.util.Properties; import org.freehep.graphics2d.font.CharTable; import org.freehep.graphics2d.font.Lookup; import org.freehep.graphicsio.FontConstants; import org.freehep.graphicsio.font.FontIncluder; import org.freehep.graphicsio.font.FontTable; /** * A table to remember which fonts were used while writing a pdf document. * Entries to resource dictionaries and embedding of fonts can be done when the * drawing is finished by calling addAll(). * * @author Simon Fischer * @version $Id: PDFFontTable.java 9329 2006-11-14 22:29:00Z duns $ */ public class PDFFontTable extends FontTable { private int currentFontIndex = 1; private PDFWriter pdf; private PDFRedundanceTracker tracker; public PDFFontTable(PDFWriter pdf) { super(); this.pdf = pdf; this.tracker = new PDFRedundanceTracker(pdf); } /** Adds all fonts to a dictionary named "FontList". */ public int addFontDictionary() throws IOException { Collection fonts = getEntries(); if (fonts.size() > 0) { PDFDictionary fontList = pdf.openDictionary("FontList"); for (Iterator i = fonts.iterator(); i.hasNext();) { Entry e = (Entry) i.next(); fontList.entry(e.getReference(), pdf.ref(e.getReference())); } pdf.close(fontList); } return fonts.size(); } /** Embeds all not yet embedded fonts to the file. */ public void embedAll(FontRenderContext context, boolean embed, String embedAs) throws IOException { Collection col = getEntries(); Iterator i = col.iterator(); while (i.hasNext()) { Entry e = (Entry) i.next(); if (!e.isWritten()) { e.setWritten(true); FontIncluder fontIncluder = null; if (PDFFontIncluder.isStandardFont(e.getFont())) { embed = false; } if (embed) { if (embedAs.equals(FontConstants.EMBED_FONTS_TYPE3)) { fontIncluder = new PDFFontEmbedderType3(context, pdf, e .getReference(), tracker); } else if (embedAs.equals(FontConstants.EMBED_FONTS_TYPE1)) { fontIncluder = PDFFontEmbedderType1.create(context, pdf, e.getReference(), tracker); } else { System.out .println("PDFFontTable: invalid value for embedAs: " + embedAs); } } else { fontIncluder = new PDFFontIncluder(context, pdf, e .getReference(), tracker); } fontIncluder.includeFont(e.getFont(), e.getEncoding(), e .getReference()); } } tracker.writeAll(); } public CharTable getEncodingTable() { return Lookup.getInstance().getTable("PDFLatin"); } public void firstRequest(Entry e, boolean embed, String embedAs) { } private static final Properties replaceFonts = new Properties(); static { replaceFonts.setProperty("Dialog", "Helvetica"); replaceFonts.setProperty("DialogInput", "Courier"); replaceFonts.setProperty("Serif", "TimesRoman"); replaceFonts.setProperty("SansSerif", "Helvetica"); replaceFonts.setProperty("Monospaced", "Courier"); } protected Font substituteFont(Font font) { String fontName = replaceFonts.getProperty(font.getName(), null); if (fontName != null) { Font newFont = new Font(fontName, font.getSize(), font.getStyle()); font = newFont.deriveFont(font.getSize2D()); } return font; } /** * Creates the reference by numbering them. * * @return "F"+currentFontIndex */ protected String createFontReference(Font f) { return "F" + (currentFontIndex++); } } src/main/java/org/freehep/graphicsio/pdf/PDFPathConstructor.java 0000644 0001750 0001750 00000002053 11343262370 024204 0 ustar user03 user03 // Copyright 2002 FreeHEP. package org.freehep.graphicsio.pdf; import java.io.IOException; import org.freehep.graphicsio.QuadToCubicPathConstructor; /** * @author Mark Donszelmann * @version $Id: PDFPathConstructor.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFPathConstructor extends QuadToCubicPathConstructor { private PDFStream stream; public PDFPathConstructor(PDFStream stream) { super(); this.stream = stream; } public void move(double x, double y) throws IOException { stream.move(x, y); super.move(x, y); } public void line(double x, double y) throws IOException { stream.line(x, y); super.line(x, y); } public void cubic(double x1, double y1, double x2, double y2, double x3, double y3) throws IOException { stream.cubic(x1, y1, x2, y2, x3, y3); super.cubic(x1, y1, x2, y2, x3, y3); } public void closePath(double x0, double y0) throws IOException { stream.closePath(); super.closePath(x0, y0); } } src/main/java/org/freehep/graphicsio/pdf/PDFStream.java 0000644 0001750 0001750 00000057203 11343262370 022304 0 ustar user03 user03 // Copyright 2000-2007, FreeHEP package org.freehep.graphicsio.pdf; import java.awt.Color; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.image.RenderedImage; import java.io.IOException; import java.io.OutputStream; import org.freehep.graphicsio.ImageConstants; import org.freehep.util.io.ASCII85OutputStream; import org.freehep.util.io.ASCIIHexOutputStream; import org.freehep.util.io.CountedByteOutputStream; import org.freehep.util.io.FinishableOutputStream; import org.freehep.util.io.FlateOutputStream; /** * This class allows you to write/print into a PDFStream. Several methods are * available to specify the content of a page, image. This class performs some * error checking, while writing the stream. *
* The stream allows to write dictionary entries. The /Length entry is written * automatically, referencing an object which will also be written just after * the stream is closed and the length is calculated. *
*
* @author Mark Donszelmann
* @version $Id: PDFStream.java 12626 2007-06-08 22:23:13Z duns $
*/
public class PDFStream extends PDFDictionary implements PDFConstants {
private String name;
private PDFObject object;
private boolean dictionaryOpen;
private OutputStream[] stream;
private CountedByteOutputStream byteCountStream;
private String[] encode;
PDFStream(PDF pdf, PDFByteWriter writer, String name, PDFObject parent,
String[] encode) throws IOException {
super(pdf, writer);
this.name = name;
object = parent;
if (object == null)
System.err
.println("PDFWriter: 'PDFStream' cannot have a null parent");
// first write the dictionary
dictionaryOpen = true;
this.encode = encode;
}
/**
* Starts the stream, writes out the filters using the preset encoding, and
* encodes the stream.
*/
private void startStream() throws IOException {
startStream(encode);
}
/**
* Starts the stream, writes out the filters using the given encoding, and
* encodes the stream.
*/
private void startStream(String[] encode) throws IOException {
if (dictionaryOpen) {
PDFName[] filters = decodeFilters(encode);
if (filters != null)
entry("Filter", filters);
super.close();
dictionaryOpen = false;
out.printPlain("stream\n");
byteCountStream = new CountedByteOutputStream(out);
stream = openFilters(byteCountStream, encode);
}
}
private void write(int b) throws IOException {
startStream();
stream[0].write(b);
}
private void write(byte[] b) throws IOException {
for (int i = 0; i < b.length; i++) {
write((int) b[i]);
}
}
private static PDFName[] decodeFilters(String[] encode) {
PDFName[] filters = null;
if ((encode != null) && (encode.length != 0)) {
filters = new PDFName[encode.length];
for (int i = 0; i < filters.length; i++) {
filters[i] = new PDFName(encode[encode.length - i - 1]
+ "Decode");
}
}
return filters;
}
// open new stream using Standard Filters (see table 3.5)
// stream[0] is the one to write to, the last one is s
private static OutputStream[] openFilters(OutputStream s, String[] filters) {
OutputStream[] os;
if ((filters != null) && (filters.length != 0)) {
os = new OutputStream[filters.length + 1];
os[os.length - 1] = s;
for (int i = os.length - 2; i >= 0; i--) {
if (filters[i].equals("ASCIIHex")) {
os[i] = new ASCIIHexOutputStream(os[i + 1]);
} else if (filters[i].equals("ASCII85")) {
os[i] = new ASCII85OutputStream(os[i + 1]);
} else if (filters[i].equals("Flate")) {
os[i] = new FlateOutputStream(os[i + 1]);
} else if (filters[i].equals("DCT")) {
os[i] = os[i + 1];
} else {
System.err.println("PDFWriter: unknown stream format: "
+ filters[i]);
}
}
} else {
os = new OutputStream[1];
os[0] = s;
}
return os;
}
// stream[0] is the first one to finish, the last one is not finished
private static void closeFilters(OutputStream[] s) throws IOException {
for (int i = 0; i < s.length - 1; i++) {
s[i].flush();
if (s[i] instanceof FinishableOutputStream) {
((FinishableOutputStream) s[i]).finish();
}
}
s[s.length - 1].flush();
}
private void write(String s) throws IOException {
byte[] b = s.getBytes("ISO-8859-1");
for (int i = 0; i < b.length; i++) {
write(b[i]);
}
}
void close() throws IOException {
closeFilters(stream);
stream = null;
out.printPlain("\nendstream");
out.println();
object.close();
if (gStates > 0) {
System.err.println("PDFStream: unbalanced saves()/restores(), too many saves: "+gStates);
}
}
String getName() {
return name;
}
public int getLength() {
return byteCountStream.getCount();
}
public void print(String s) throws IOException {
write(s);
}
public void println(String s) throws IOException {
write(s);
write(EOL);
}
public void comment(String comment) throws IOException {
println("% " + comment);
}
// ==========================================================================
// PDFStream Operators according to Table 4.1
// ==========================================================================
//
// Graphics State operators (see Table 4.7)
//
private int gStates = 0;
public void save() throws IOException {
println("q");
gStates++;
}
public void restore() throws IOException {
if (gStates <= 0) {
System.err.println("PDFStream: unbalanced saves()/restores(), too many restores");
}
gStates--;
println("Q");
}
public void matrix(AffineTransform xform) throws IOException {
matrix(xform.getScaleX(), xform.getShearY(), xform.getShearX(), xform
.getScaleY(), xform.getTranslateX(), xform.getTranslateY());
}
public void matrix(double m00, double m10, double m01, double m11,
double m02, double m12) throws IOException {
println(PDFUtil.fixedPrecision(m00) + " " + PDFUtil.fixedPrecision(m10)
+ " " + PDFUtil.fixedPrecision(m01) + " "
+ PDFUtil.fixedPrecision(m11) + " "
+ PDFUtil.fixedPrecision(m02) + " "
+ PDFUtil.fixedPrecision(m12) + " cm");
}
public void width(double width) throws IOException {
println(PDFUtil.fixedPrecision(width) + " w");
}
public void cap(int capStyle) throws IOException {
println(capStyle + " J");
}
public void join(int joinStyle) throws IOException {
println(joinStyle + " j");
}
public void mitterLimit(double limit) throws IOException {
println(PDFUtil.fixedPrecision(limit) + " M");
}
public void dash(int[] dash, double phase) throws IOException {
print("[");
for (int i = 0; i < dash.length; i++) {
print(" " + PDFUtil.fixedPrecision(dash[i]));
}
println("] " + PDFUtil.fixedPrecision(phase) + " d");
}
public void dash(float[] dash, double phase) throws IOException {
print("[");
for (int i = 0; i < dash.length; i++) {
print(" " + PDFUtil.fixedPrecision(dash[i]));
}
println("] " + PDFUtil.fixedPrecision(phase) + " d");
}
public void flatness(double flatness) throws IOException {
println(PDFUtil.fixedPrecision(flatness) + " i");
}
public void state(PDFName stateDictionary) throws IOException {
println(stateDictionary + " gs");
}
//
// Path Construction operators (see Table 4.9)
//
public void cubic(double x1, double y1, double x2, double y2, double x3,
double y3) throws IOException {
println(PDFUtil.fixedPrecision(x1) + " " + PDFUtil.fixedPrecision(y1)
+ " " + PDFUtil.fixedPrecision(x2) + " "
+ PDFUtil.fixedPrecision(y2) + " " + PDFUtil.fixedPrecision(x3)
+ " " + PDFUtil.fixedPrecision(y3) + " c");
}
public void cubicV(double x2, double y2, double x3, double y3)
throws IOException {
println(PDFUtil.fixedPrecision(x2) + " " + PDFUtil.fixedPrecision(y2)
+ " " + PDFUtil.fixedPrecision(x3) + " "
+ PDFUtil.fixedPrecision(y3) + " v");
}
public void cubicY(double x1, double y1, double x3, double y3)
throws IOException {
println(PDFUtil.fixedPrecision(x1) + " " + PDFUtil.fixedPrecision(y1)
+ " " + PDFUtil.fixedPrecision(x3) + " "
+ PDFUtil.fixedPrecision(y3) + " y");
}
public void move(double x, double y) throws IOException {
println(PDFUtil.fixedPrecision(x) + " " + PDFUtil.fixedPrecision(y)
+ " m");
}
public void line(double x, double y) throws IOException {
println(PDFUtil.fixedPrecision(x) + " " + PDFUtil.fixedPrecision(y)
+ " l");
}
public void closePath() throws IOException {
println("h");
}
public void rectangle(double x, double y, double width, double height)
throws IOException {
println(PDFUtil.fixedPrecision(x) + " " + PDFUtil.fixedPrecision(y)
+ " " + PDFUtil.fixedPrecision(width) + " "
+ PDFUtil.fixedPrecision(height) + " re");
}
//
// Path Painting operators (see Table 4.10)
//
public void stroke() throws IOException {
println("S");
}
public void closeAndStroke() throws IOException {
println("s");
}
public void fill() throws IOException {
println("f");
}
public void fillEvenOdd() throws IOException {
println("f*");
}
public void fillAndStroke() throws IOException {
println("B");
}
public void fillEvenOddAndStroke() throws IOException {
println("B*");
}
public void closeFillAndStroke() throws IOException {
println("b");
}
public void closeFillEvenOddAndStroke() throws IOException {
println("b*");
}
public void endPath() throws IOException {
println("n");
}
//
// Clipping Path operators (see Table 4.11)
//
public void clip() throws IOException {
println("W");
}
public void clipEvenOdd() throws IOException {
println("W*");
}
//
// Text Object operators (see Table 5.4)
//
private boolean textOpen = false;
public void beginText() throws IOException {
if (textOpen)
System.err.println("PDFStream: nested beginText() not allowed.");
println("BT");
textOpen = true;
}
public void endText() throws IOException {
if (!textOpen)
System.err
.println("PDFStream: unbalanced use of beginText()/endText().");
println("ET");
textOpen = false;
}
//
// Text State operators (see Table 5.2)
//
public void charSpace(double charSpace) throws IOException {
println(PDFUtil.fixedPrecision(charSpace) + " Tc");
}
public void wordSpace(double wordSpace) throws IOException {
println(PDFUtil.fixedPrecision(wordSpace) + " Tw");
}
public void scale(double scale) throws IOException {
println(PDFUtil.fixedPrecision(scale) + " Tz");
}
public void leading(double leading) throws IOException {
println(PDFUtil.fixedPrecision(leading) + " TL");
}
private boolean fontWasSet = false;
public void font(PDFName fontName, double size) throws IOException {
println(fontName + " " + PDFUtil.fixedPrecision(size) + " Tf");
fontWasSet = true;
}
public void rendering(int mode) throws IOException {
println(mode + " Tr");
}
public void rise(double rise) throws IOException {
println(PDFUtil.fixedPrecision(rise) + " Ts");
}
//
// Text Positioning operators (see Table 5.5)
//
public void text(double x, double y) throws IOException {
println(PDFUtil.fixedPrecision(x) + " " + PDFUtil.fixedPrecision(y)
+ " Td");
}
public void textLeading(double x, double y) throws IOException {
println(PDFUtil.fixedPrecision(x) + " " + PDFUtil.fixedPrecision(y)
+ " TD");
}
public void textMatrix(double a, double b, double c, double d, double e,
double f) throws IOException {
println(PDFUtil.fixedPrecision(a) + " " + PDFUtil.fixedPrecision(b)
+ " " + PDFUtil.fixedPrecision(c) + " "
+ PDFUtil.fixedPrecision(d) + " " + PDFUtil.fixedPrecision(e)
+ " " + PDFUtil.fixedPrecision(f) + " Tm");
}
public void textLine() throws IOException {
println("T*");
}
//
// Text Showing operators (see Table 5.6)
//
public void show(String text) throws IOException {
if (!fontWasSet)
System.err
.println("PDFStream: cannot use Text Showing operator before font is set.");
if (!textOpen)
System.err
.println("PDFStream: Text Showing operator only allowed inside Text section.");
println("(" + PDFUtil.escape(text) + ") Tj");
}
public void showLine(String text) throws IOException {
if (!fontWasSet)
System.err
.println("PDFStream: cannot use Text Showing operator before font is set.");
if (!textOpen)
System.err
.println("PDFStream: Text Showing operator only allowed inside Text section.");
println("(" + PDFUtil.escape(text) + ") '");
}
public void showLine(double wordSpace, double charSpace, String text)
throws IOException {
if (!fontWasSet)
System.err
.println("PDFStream: cannot use Text Showing operator before font is set.");
if (!textOpen)
System.err
.println("PDFStream: Text Showing operator only allowed inside Text section.");
println(PDFUtil.fixedPrecision(wordSpace) + " "
+ PDFUtil.fixedPrecision(charSpace) + " ("
+ PDFUtil.escape(text) + ") \"");
}
public void show(Object[] array) throws IOException {
print("[");
for (int i = 0; i < array.length; i++) {
Object object = array[i];
if (object instanceof String) {
print(" (" + PDFUtil.escape(object.toString()) + ")");
} else if (object instanceof Integer) {
print(" " + ((Integer) object).intValue());
} else if (object instanceof Double) {
print(" " + ((Double) object).doubleValue());
} else {
System.err
.println("PDFStream: input array of operator TJ may only contain objects of type 'String', 'Integer' or 'Double'");
}
}
println("] TJ");
}
//
// Type 3 Font operators (see Table 5.10)
//
public void glyph(double wx, double wy) throws IOException {
println(PDFUtil.fixedPrecision(wx) + " " + PDFUtil.fixedPrecision(wy)
+ " d0");
}
public void glyph(double wx, double wy, double llx, double lly, double urx,
double ury) throws IOException {
println(PDFUtil.fixedPrecision(wx) + " " + PDFUtil.fixedPrecision(wy)
+ " " + PDFUtil.fixedPrecision(llx) + " "
+ PDFUtil.fixedPrecision(lly) + " "
+ PDFUtil.fixedPrecision(urx) + " "
+ PDFUtil.fixedPrecision(ury) + " d1");
}
//
// Color operators (see Table 4.21)
//
public void colorSpace(PDFName colorSpace) throws IOException {
println(colorSpace + " cs");
}
public void colorSpaceStroke(PDFName colorSpace) throws IOException {
println(colorSpace + " CS");
}
public void colorSpace(double[] color) throws IOException {
for (int i = 0; i < color.length; i++) {
print(" " + color[i]);
}
println(" scn");
}
public void colorSpaceStroke(double[] color) throws IOException {
for (int i = 0; i < color.length; i++) {
print(" " + color[i]);
}
println(" SCN");
}
public void colorSpace(double[] color, PDFName name) throws IOException {
if (color != null) {
for (int i = 0; i < color.length; i++) {
print(PDFUtil.fixedPrecision(color[i]) + " ");
}
}
println(name + " scn");
}
public void colorSpaceStroke(double[] color, PDFName name)
throws IOException {
if (color != null) {
for (int i = 0; i < color.length; i++) {
print(PDFUtil.fixedPrecision(color[i]) + " ");
}
}
println(name + " SCN");
}
public void colorSpace(double g) throws IOException {
println(PDFUtil.fixedPrecision(g) + " g");
}
public void colorSpaceStroke(double g) throws IOException {
println(PDFUtil.fixedPrecision(g) + " G");
}
public void colorSpace(double r, double g, double b) throws IOException {
println(PDFUtil.fixedPrecision(r) + " " + PDFUtil.fixedPrecision(g)
+ " " + PDFUtil.fixedPrecision(b) + " rg");
}
public void colorSpaceStroke(double r, double g, double b)
throws IOException {
println(PDFUtil.fixedPrecision(r) + " " + PDFUtil.fixedPrecision(g)
+ " " + PDFUtil.fixedPrecision(b) + " RG");
}
public void colorSpace(double c, double m, double y, double k)
throws IOException {
println(PDFUtil.fixedPrecision(c) + " " + PDFUtil.fixedPrecision(m)
+ " " + PDFUtil.fixedPrecision(y) + " "
+ PDFUtil.fixedPrecision(k) + " k");
}
public void colorSpaceStroke(double c, double m, double y, double k)
throws IOException {
println(PDFUtil.fixedPrecision(c) + " " + PDFUtil.fixedPrecision(m)
+ " " + PDFUtil.fixedPrecision(y) + " "
+ PDFUtil.fixedPrecision(k) + " K");
}
//
// Shading Pattern operator (see Table 4.24)
//
public void shade(PDFName name) throws IOException {
println(name + " sh");
}
/**
* returns the decode-format for an image -format
*
* @param encode {@link ImageConstants#ZLIB} or {@link ImageConstants#JPG}
* @return {@link #decodeFilters(String[])}
*/
private PDFName[] getFilterName(String encode) {
if (ImageConstants.ZLIB.equals(encode)) {
return decodeFilters(new String[] {
ImageConstants.ENCODING_FLATE,
ImageConstants.ENCODING_ASCII85});
}
if (ImageConstants.JPG.equals(encode)) {
return decodeFilters(new String[] {
ImageConstants.ENCODING_DCT,
ImageConstants.ENCODING_ASCII85});
}
throw new IllegalArgumentException("unknown image encoding " + encode + " for PDFStream");
}
/**
* Image convenience function (see Table 4.35). Ouputs the data of the image
* using "DeviceRGB" colorspace, and the requested encodings
*
* @param image Image to write
* @param bkg Background color, null for transparent image
* @param encode {@link org.freehep.graphicsio.ImageConstants#ZLIB} or {@link org.freehep.graphicsio.ImageConstants#JPG}
* @throws java.io.IOException thrown by ImageBytes
*/
public void image(RenderedImage image, Color bkg, String encode)
throws IOException {
ImageBytes bytes = new ImageBytes(image, bkg, encode, ImageConstants.COLOR_MODEL_RGB);
entry("Width", image.getWidth());
entry("Height", image.getHeight());
entry("ColorSpace", pdf.name("DeviceRGB"));
entry("BitsPerComponent", 8);
entry("Filter", getFilterName(bytes.getFormat()));
write(bytes.getBytes());
}
public void imageMask(RenderedImage image, String encode)
throws IOException {
ImageBytes bytes = new ImageBytes(image, null, encode, ImageConstants.COLOR_MODEL_A);
entry("Width", image.getWidth());
entry("Height", image.getHeight());
entry("BitsPerComponent", 8);
entry("ColorSpace", pdf.name("DeviceGray"));
entry("Filter", getFilterName(bytes.getFormat()));
write(bytes.getBytes());
}
/**
* Inline Image convenience function (see Table 4.39 and 4.40). Ouputs the
* data of the image using "DeviceRGB" colorspace, and the requested
* encoding.
* @param image Image to write
* @param bkg Background color, null for transparent image
* @param encode {@link org.freehep.graphicsio.ImageConstants#ZLIB} or {@link org.freehep.graphicsio.ImageConstants#JPG}
* @throws java.io.IOException thrown by ImageBytes
*/
public void inlineImage(RenderedImage image, Color bkg, String encode)
throws IOException {
ImageBytes bytes = new ImageBytes(image, bkg, ImageConstants.JPG, ImageConstants.COLOR_MODEL_RGB);
println("BI");
imageInfo("Width", image.getWidth());
imageInfo("Height", image.getHeight());
imageInfo("ColorSpace", pdf.name("DeviceRGB"));
imageInfo("BitsPerComponent", 8);
imageInfo("Filter", getFilterName(bytes.getFormat()));
print("ID\n");
write(bytes.getBytes());
println("\nEI");
}
//
// In-line Image operators (see Table 4.38)
//
private void imageInfo(String key, int number) throws IOException {
println("/" + key + " " + number);
}
private void imageInfo(String key, PDFName name) throws IOException {
println("/" + key + " " + name);
}
private void imageInfo(String key, Object[] array) throws IOException {
print("/" + key + " [");
for (int i = 0; i < array.length; i++) {
print(" " + array[i]);
}
println("]");
}
/**
* Draws the points of the shape using path construction
* operators. The path is neither stroked nor filled.
*
* @return true if even-odd winding rule should be used, false if non-zero
* winding rule should be used.
*/
public boolean drawPath(Shape s) throws IOException {
PDFPathConstructor path = new PDFPathConstructor(this);
return path.addPath(s);
}
//
// XObject operators (see Table 4.34)
//
public void xObject(PDFName name) throws IOException {
println(name + " Do");
}
//
// Marked Content operators (see Table 8.5)
//
// FIXME: missing all
//
// Compatibility operators (see Table 3.19)
//
private boolean compatibilityOpen = false;
public void beginCompatibility() throws IOException {
if (compatibilityOpen)
System.err
.println("PDFStream: nested use of Compatibility sections not allowed.");
println("BX");
compatibilityOpen = true;
}
public void endCompatibility() throws IOException {
if (!compatibilityOpen)
System.err
.println("PDFStream: unbalanced use of begin/endCompatibilty().");
println("EX");
compatibilityOpen = false;
}
}
src/site/ 0000700 0001750 0001750 00000000000 11343262370 011624 5 ustar user03 user03 src/site/apt/ 0000700 0001750 0001750 00000000000 11343262370 012410 5 ustar user03 user03 src/site/site.xml 0000644 0001750 0001750 00000001737 11343262370 013334 0 ustar user03 user03