mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-02 20:04:37 +00:00
gnujpdf reformat
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,7 @@ package gnu.jpdf;
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MyRect {
|
||||
|
||||
public int xMin;
|
||||
public int yMin;
|
||||
public int xMax;
|
||||
|
||||
@@ -24,249 +24,257 @@ import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>This class defines an annotation (commonly known as a Bookmark).</p>
|
||||
* <p>
|
||||
* This class defines an annotation (commonly known as a Bookmark).</p>
|
||||
*
|
||||
* @author Eric Z. Beard, ericzbeard@hotmail.com
|
||||
* @author Peter T Mount, http://www.retep.org.uk/pdf/
|
||||
* @version $Revision: 1.2 $, $Date: 2007/08/26 18:56:35 $
|
||||
*/
|
||||
public class PDFAnnot extends PDFObject implements Serializable
|
||||
{
|
||||
/*
|
||||
public class PDFAnnot extends PDFObject implements Serializable {
|
||||
|
||||
/*
|
||||
* NOTE: The original class is the work of Peter T. Mount, who released it
|
||||
* in the uk.org.retep.pdf package. It was modified by Eric Z. Beard as
|
||||
* follows: the package name was changed to gnu.pdf. It is still
|
||||
* licensed under the LGPL.
|
||||
*/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Solid border. The border is drawn as a solid line.
|
||||
*/
|
||||
public static final short SOLID = 0;
|
||||
|
||||
/**
|
||||
* The border is drawn with a dashed line.
|
||||
*/
|
||||
public static final short DASHED = 1;
|
||||
|
||||
/**
|
||||
* The border is drawn in a beveled style (faux three-dimensional) such
|
||||
* that it looks as if it is pushed out of the page (opposite of INSET)
|
||||
*/
|
||||
public static final short BEVELED = 2;
|
||||
|
||||
/**
|
||||
* The border is drawn in an inset style (faux three-dimensional) such
|
||||
* that it looks as if it is inset into the page (opposite of BEVELED)
|
||||
*/
|
||||
public static final short INSET = 3;
|
||||
|
||||
/**
|
||||
* The border is drawn as a line on the bottom of the annotation rectangle
|
||||
*/
|
||||
public static final short UNDERLINED = 4;
|
||||
|
||||
/**
|
||||
* The subtype of the outline, ie text, note, etc
|
||||
*/
|
||||
private String subtype;
|
||||
|
||||
/**
|
||||
* The size of the annotation
|
||||
*/
|
||||
private int l,b,r,t;
|
||||
|
||||
/**
|
||||
* The text of a text annotation
|
||||
*/
|
||||
private String s;
|
||||
|
||||
/**
|
||||
* flag used to indicate that the destination should fit the screen
|
||||
*/
|
||||
private static final int FULL_PAGE = -9999;
|
||||
|
||||
/**
|
||||
* Link to the Destination page
|
||||
*/
|
||||
private PDFObject dest;
|
||||
|
||||
/**
|
||||
* If fl!=FULL_PAGE then this is the region of the destination page shown.
|
||||
* Otherwise they are ignored.
|
||||
*/
|
||||
private int fl,fb,fr,ft;
|
||||
|
||||
/**
|
||||
* the border for this annotation
|
||||
*/
|
||||
private PDFBorder border;
|
||||
|
||||
/**
|
||||
* This is used to create an annotation.
|
||||
* @param s Subtype for this annotation
|
||||
* @param l Left coordinate
|
||||
* @param b Bottom coordinate
|
||||
* @param r Right coordinate
|
||||
* @param t Top coordinate
|
||||
*/
|
||||
protected PDFAnnot(String s,int l,int b,int r,int t) {
|
||||
super("/Annot");
|
||||
subtype = s;
|
||||
this.l = l;
|
||||
this.b = b;
|
||||
this.r = r;
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a text annotation
|
||||
* @param l Left coordinate
|
||||
* @param b Bottom coordinate
|
||||
* @param r Right coordinate
|
||||
* @param t Top coordinate
|
||||
* @param s Text for this annotation
|
||||
*/
|
||||
public PDFAnnot(int l,int b,int r,int t,String s) {
|
||||
this("/Text",l,b,r,t);
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a link annotation
|
||||
* @param l Left coordinate
|
||||
* @param b Bottom coordinate
|
||||
* @param r Right coordinate
|
||||
* @param t Top coordinate
|
||||
* @param dest Destination for this link. The page will fit the display.
|
||||
*/
|
||||
public PDFAnnot(int l,int b,int r,int t,PDFObject dest) {
|
||||
this("/Link",l,b,r,t);
|
||||
this.dest = dest;
|
||||
this.fl = FULL_PAGE; // this is used to indicate a full page
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a link annotation
|
||||
* @param l Left coordinate
|
||||
* @param b Bottom coordinate
|
||||
* @param r Right coordinate
|
||||
* @param t Top coordinate
|
||||
* @param dest Destination for this link
|
||||
* @param fl Left coordinate
|
||||
* @param fb Bottom coordinate
|
||||
* @param fr Right coordinate
|
||||
* @param ft Top coordinate
|
||||
* <br><br>Rectangle describing what part of the page to be displayed
|
||||
* (must be in User Coordinates)
|
||||
*/
|
||||
public PDFAnnot(int l,int b,int r,int t,
|
||||
PDFObject dest,
|
||||
int fl,int fb,int fr,int ft
|
||||
) {
|
||||
this("/Link",l,b,r,t);
|
||||
this.dest = dest;
|
||||
this.fl = fl;
|
||||
this.fb = fb;
|
||||
this.fr = fr;
|
||||
this.ft = ft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the border for the annotation. By default, no border is defined.
|
||||
*
|
||||
* <p>If the style is DASHED, then this method uses PDF's default dash
|
||||
* scheme {3}
|
||||
*
|
||||
* <p>Important: the annotation must have been added to the document before
|
||||
* this is used. If the annotation was created using the methods in
|
||||
* PDFPage, then the annotation is already in the document.
|
||||
*
|
||||
* @param style Border style SOLID, DASHED, BEVELED, INSET or UNDERLINED.
|
||||
* @param width Width of the border
|
||||
*/
|
||||
public void setBorder(short style,double width) {
|
||||
border = new PDFBorder(style,width);
|
||||
pdfDocument.add(border);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the border for the annotation. Unlike the other method, this
|
||||
* produces a dashed border.
|
||||
*
|
||||
* <p>Important: the annotation must have been added to the document before
|
||||
* this is used. If the annotation was created using the methods in
|
||||
* PDFPage, then the annotation is already in the document.
|
||||
*
|
||||
* @param width Width of the border
|
||||
* @param dash Array of lengths, used for drawing the dashes. If this
|
||||
* is null, then the default of {3} is used.
|
||||
*/
|
||||
public void setBorder(double width,double dash[]) {
|
||||
border = new PDFBorder(width,dash);
|
||||
pdfDocument.add(border);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should this be public??
|
||||
*
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void write(OutputStream os) throws IOException {
|
||||
// Write the object header
|
||||
writeStart(os);
|
||||
|
||||
// now the objects body
|
||||
os.write("/Subtype ".getBytes());
|
||||
os.write(subtype.getBytes());
|
||||
os.write("\n/Rect [".getBytes());
|
||||
os.write(Integer.toString(l).getBytes());
|
||||
os.write(" ".getBytes());
|
||||
os.write(Integer.toString(b).getBytes());
|
||||
os.write(" ".getBytes());
|
||||
os.write(Integer.toString(r).getBytes());
|
||||
os.write(" ".getBytes());
|
||||
os.write(Integer.toString(t).getBytes());
|
||||
os.write("]\n".getBytes());
|
||||
|
||||
// handle the border
|
||||
if(border==null) {
|
||||
os.write("/Border [0 0 0]\n".getBytes());
|
||||
//if(pdf.defaultOutlineBorder==null)
|
||||
//pdf.add(pdf.defaultOutlineBorder = new border(SOLID,0.0));
|
||||
//os.write(pdf.defaultOutlineBorder.toString().getBytes());
|
||||
} else {
|
||||
os.write("/BS ".getBytes());
|
||||
os.write(border.toString().getBytes());
|
||||
os.write("\n".getBytes());
|
||||
/**
|
||||
* Solid border. The border is drawn as a solid line.
|
||||
*/
|
||||
public static final short SOLID = 0;
|
||||
|
||||
/**
|
||||
* The border is drawn with a dashed line.
|
||||
*/
|
||||
public static final short DASHED = 1;
|
||||
|
||||
/**
|
||||
* The border is drawn in a beveled style (faux three-dimensional) such that
|
||||
* it looks as if it is pushed out of the page (opposite of INSET)
|
||||
*/
|
||||
public static final short BEVELED = 2;
|
||||
|
||||
/**
|
||||
* The border is drawn in an inset style (faux three-dimensional) such that
|
||||
* it looks as if it is inset into the page (opposite of BEVELED)
|
||||
*/
|
||||
public static final short INSET = 3;
|
||||
|
||||
/**
|
||||
* The border is drawn as a line on the bottom of the annotation rectangle
|
||||
*/
|
||||
public static final short UNDERLINED = 4;
|
||||
|
||||
/**
|
||||
* The subtype of the outline, ie text, note, etc
|
||||
*/
|
||||
private String subtype;
|
||||
|
||||
/**
|
||||
* The size of the annotation
|
||||
*/
|
||||
private int l, b, r, t;
|
||||
|
||||
/**
|
||||
* The text of a text annotation
|
||||
*/
|
||||
private String s;
|
||||
|
||||
/**
|
||||
* flag used to indicate that the destination should fit the screen
|
||||
*/
|
||||
private static final int FULL_PAGE = -9999;
|
||||
|
||||
/**
|
||||
* Link to the Destination page
|
||||
*/
|
||||
private PDFObject dest;
|
||||
|
||||
/**
|
||||
* If fl!=FULL_PAGE then this is the region of the destination page shown.
|
||||
* Otherwise they are ignored.
|
||||
*/
|
||||
private int fl, fb, fr, ft;
|
||||
|
||||
/**
|
||||
* the border for this annotation
|
||||
*/
|
||||
private PDFBorder border;
|
||||
|
||||
/**
|
||||
* This is used to create an annotation.
|
||||
*
|
||||
* @param s Subtype for this annotation
|
||||
* @param l Left coordinate
|
||||
* @param b Bottom coordinate
|
||||
* @param r Right coordinate
|
||||
* @param t Top coordinate
|
||||
*/
|
||||
protected PDFAnnot(String s, int l, int b, int r, int t) {
|
||||
super("/Annot");
|
||||
subtype = s;
|
||||
this.l = l;
|
||||
this.b = b;
|
||||
this.r = r;
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
// Now the annotation subtypes
|
||||
if(subtype.equals("/Text")) {
|
||||
os.write("/Contents ".getBytes());
|
||||
os.write(PDFStringHelper.makePDFString(s).getBytes());
|
||||
os.write("\n".getBytes());
|
||||
} else if(subtype.equals("/Link")) {
|
||||
os.write("/Dest [".getBytes());
|
||||
os.write(dest.toString().getBytes());
|
||||
if(fl==FULL_PAGE)
|
||||
os.write(" /Fit]".getBytes());
|
||||
else {
|
||||
os.write(" /FitR ".getBytes());
|
||||
os.write(Integer.toString(fl).getBytes());
|
||||
os.write(" ".getBytes());
|
||||
os.write(Integer.toString(fb).getBytes());
|
||||
os.write(" ".getBytes());
|
||||
os.write(Integer.toString(fr).getBytes());
|
||||
os.write(" ".getBytes());
|
||||
os.write(Integer.toString(ft).getBytes());
|
||||
os.write("]".getBytes());
|
||||
}
|
||||
os.write("\n".getBytes());
|
||||
|
||||
/**
|
||||
* Creates a text annotation
|
||||
*
|
||||
* @param l Left coordinate
|
||||
* @param b Bottom coordinate
|
||||
* @param r Right coordinate
|
||||
* @param t Top coordinate
|
||||
* @param s Text for this annotation
|
||||
*/
|
||||
public PDFAnnot(int l, int b, int r, int t, String s) {
|
||||
this("/Text", l, b, r, t);
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a link annotation
|
||||
*
|
||||
* @param l Left coordinate
|
||||
* @param b Bottom coordinate
|
||||
* @param r Right coordinate
|
||||
* @param t Top coordinate
|
||||
* @param dest Destination for this link. The page will fit the display.
|
||||
*/
|
||||
public PDFAnnot(int l, int b, int r, int t, PDFObject dest) {
|
||||
this("/Link", l, b, r, t);
|
||||
this.dest = dest;
|
||||
this.fl = FULL_PAGE; // this is used to indicate a full page
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a link annotation
|
||||
*
|
||||
* @param l Left coordinate
|
||||
* @param b Bottom coordinate
|
||||
* @param r Right coordinate
|
||||
* @param t Top coordinate
|
||||
* @param dest Destination for this link
|
||||
* @param fl Left coordinate
|
||||
* @param fb Bottom coordinate
|
||||
* @param fr Right coordinate
|
||||
* @param ft Top coordinate
|
||||
* <br><br>Rectangle describing what part of the page to be displayed (must
|
||||
* be in User Coordinates)
|
||||
*/
|
||||
public PDFAnnot(int l, int b, int r, int t,
|
||||
PDFObject dest,
|
||||
int fl, int fb, int fr, int ft
|
||||
) {
|
||||
this("/Link", l, b, r, t);
|
||||
this.dest = dest;
|
||||
this.fl = fl;
|
||||
this.fb = fb;
|
||||
this.fr = fr;
|
||||
this.ft = ft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the border for the annotation. By default, no border is defined.
|
||||
*
|
||||
* <p>
|
||||
* If the style is DASHED, then this method uses PDF's default dash scheme
|
||||
* {3}
|
||||
*
|
||||
* <p>
|
||||
* Important: the annotation must have been added to the document before
|
||||
* this is used. If the annotation was created using the methods in PDFPage,
|
||||
* then the annotation is already in the document.
|
||||
*
|
||||
* @param style Border style SOLID, DASHED, BEVELED, INSET or UNDERLINED.
|
||||
* @param width Width of the border
|
||||
*/
|
||||
public void setBorder(short style, double width) {
|
||||
border = new PDFBorder(style, width);
|
||||
pdfDocument.add(border);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the border for the annotation. Unlike the other method, this
|
||||
* produces a dashed border.
|
||||
*
|
||||
* <p>
|
||||
* Important: the annotation must have been added to the document before
|
||||
* this is used. If the annotation was created using the methods in PDFPage,
|
||||
* then the annotation is already in the document.
|
||||
*
|
||||
* @param width Width of the border
|
||||
* @param dash Array of lengths, used for drawing the dashes. If this is
|
||||
* null, then the default of {3} is used.
|
||||
*/
|
||||
public void setBorder(double width, double dash[]) {
|
||||
border = new PDFBorder(width, dash);
|
||||
pdfDocument.add(border);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should this be public??
|
||||
*
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void write(OutputStream os) throws IOException {
|
||||
// Write the object header
|
||||
writeStart(os);
|
||||
|
||||
// now the objects body
|
||||
os.write("/Subtype ".getBytes());
|
||||
os.write(subtype.getBytes());
|
||||
os.write("\n/Rect [".getBytes());
|
||||
os.write(Integer.toString(l).getBytes());
|
||||
os.write(" ".getBytes());
|
||||
os.write(Integer.toString(b).getBytes());
|
||||
os.write(" ".getBytes());
|
||||
os.write(Integer.toString(r).getBytes());
|
||||
os.write(" ".getBytes());
|
||||
os.write(Integer.toString(t).getBytes());
|
||||
os.write("]\n".getBytes());
|
||||
|
||||
// handle the border
|
||||
if (border == null) {
|
||||
os.write("/Border [0 0 0]\n".getBytes());
|
||||
//if(pdf.defaultOutlineBorder==null)
|
||||
//pdf.add(pdf.defaultOutlineBorder = new border(SOLID,0.0));
|
||||
//os.write(pdf.defaultOutlineBorder.toString().getBytes());
|
||||
} else {
|
||||
os.write("/BS ".getBytes());
|
||||
os.write(border.toString().getBytes());
|
||||
os.write("\n".getBytes());
|
||||
}
|
||||
|
||||
// Now the annotation subtypes
|
||||
if (subtype.equals("/Text")) {
|
||||
os.write("/Contents ".getBytes());
|
||||
os.write(PDFStringHelper.makePDFString(s).getBytes());
|
||||
os.write("\n".getBytes());
|
||||
} else if (subtype.equals("/Link")) {
|
||||
os.write("/Dest [".getBytes());
|
||||
os.write(dest.toString().getBytes());
|
||||
if (fl == FULL_PAGE) {
|
||||
os.write(" /Fit]".getBytes());
|
||||
} else {
|
||||
os.write(" /FitR ".getBytes());
|
||||
os.write(Integer.toString(fl).getBytes());
|
||||
os.write(" ".getBytes());
|
||||
os.write(Integer.toString(fb).getBytes());
|
||||
os.write(" ".getBytes());
|
||||
os.write(Integer.toString(fr).getBytes());
|
||||
os.write(" ".getBytes());
|
||||
os.write(Integer.toString(ft).getBytes());
|
||||
os.write("]".getBytes());
|
||||
}
|
||||
os.write("\n".getBytes());
|
||||
}
|
||||
|
||||
// finish off with its footer
|
||||
writeEnd(os);
|
||||
}
|
||||
|
||||
// finish off with its footer
|
||||
writeEnd(os);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,65 +23,67 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* <p>A border around an annotation </p>
|
||||
* <p>
|
||||
* A border around an annotation </p>
|
||||
*
|
||||
*
|
||||
* @author Peter T Mount, http://www.retep.org.uk/pdf/
|
||||
* @author Eric Z. Beard, ericzbeard@hotmail.com
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class PDFBorder extends PDFObject
|
||||
{
|
||||
public class PDFBorder extends PDFObject {
|
||||
|
||||
/*
|
||||
* NOTE: The original class is the work of Peter T. Mount, who released it
|
||||
* in the uk.org.retep.pdf package. It was modified by Eric Z. Beard as
|
||||
* follows: the package name was changed to gnu.pdf. It is still
|
||||
* licensed under the LGPL.
|
||||
*/
|
||||
*/
|
||||
|
||||
/**
|
||||
* The style of the border
|
||||
*/
|
||||
private short style;
|
||||
|
||||
|
||||
/**
|
||||
* The width of the border
|
||||
*/
|
||||
private double width;
|
||||
|
||||
|
||||
/**
|
||||
* This array allows the definition of a dotted line for the border
|
||||
*/
|
||||
private double dash[];
|
||||
|
||||
|
||||
/**
|
||||
* Creates a border using the predefined styles in PDFAnnot.
|
||||
* <p>Note: Do not use PDFAnnot.DASHED with this method.
|
||||
* Use the other constructor.
|
||||
* <p>
|
||||
* Note: Do not use PDFAnnot.DASHED with this method. Use the other
|
||||
* constructor.
|
||||
*
|
||||
* @param style The style of the border
|
||||
* @param width The width of the border
|
||||
* @see PDFAnnot
|
||||
*/
|
||||
public PDFBorder(short style,double width) {
|
||||
public PDFBorder(short style, double width) {
|
||||
super("/Border");
|
||||
this.style = style;
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a border of style PDFAnnot.DASHED
|
||||
*
|
||||
* @param width The width of the border
|
||||
* @param dash The line pattern definition
|
||||
*/
|
||||
public PDFBorder(double width,double dash[]) {
|
||||
public PDFBorder(double width, double dash[]) {
|
||||
super("/Border");
|
||||
this.style = PDFAnnot.DASHED;
|
||||
this.width = width;
|
||||
this.dash = dash;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
@@ -90,23 +92,23 @@ public class PDFBorder extends PDFObject
|
||||
//writeStart(os);
|
||||
os.write(Integer.toString(objser).getBytes());
|
||||
os.write(" 0 obj\n".getBytes());
|
||||
|
||||
|
||||
os.write("[/S /".getBytes());
|
||||
os.write("SDBIU".substring(style,style+1).getBytes());
|
||||
os.write("SDBIU".substring(style, style + 1).getBytes());
|
||||
os.write(" /W ".getBytes());
|
||||
os.write(Double.toString(width).getBytes());
|
||||
if(dash!=null) {
|
||||
if (dash != null) {
|
||||
os.write(" /D [".getBytes());
|
||||
os.write(Double.toString(dash[0]).getBytes());
|
||||
for(int i=1;i<dash.length;i++) {
|
||||
for (int i = 1; i < dash.length; i++) {
|
||||
os.write(" ".getBytes());
|
||||
os.write(Double.toString(dash[i]).getBytes());
|
||||
}
|
||||
os.write("] ".getBytes());
|
||||
}
|
||||
os.write("]\n".getBytes());
|
||||
|
||||
|
||||
//writeEnd(os);
|
||||
os.write("endobj\n".getBytes());
|
||||
}
|
||||
}
|
||||
} // end class PDFBorder
|
||||
|
||||
@@ -23,84 +23,85 @@ package gnu.jpdf;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* <p>This class implements the PDF Catalog,
|
||||
* also known as the root node</p>
|
||||
* <p>
|
||||
* This class implements the PDF Catalog, also known as the root node</p>
|
||||
*
|
||||
* @author Peter T. Mount
|
||||
* @author Eric Z. Beard, ericzbeard@hotmail.com
|
||||
* @version $Revision: 1.2 $, $Date: 2007/08/26 18:56:35 $
|
||||
*/
|
||||
public class PDFCatalog extends PDFObject
|
||||
{
|
||||
/**
|
||||
* The pages of the document
|
||||
*/
|
||||
private PDFPageList pdfPageList;
|
||||
|
||||
/**
|
||||
* The outlines of the document
|
||||
*/
|
||||
private PDFOutline outlines;
|
||||
|
||||
/**
|
||||
* The initial page mode
|
||||
*/
|
||||
private int pagemode;
|
||||
|
||||
/**
|
||||
* This constructs a PDF Catalog object
|
||||
*
|
||||
* @param pdfPageList The PDFPageList object that's the root
|
||||
* of the documents page tree
|
||||
* @param pagemode How the document should appear when opened.
|
||||
* Allowed values are USENONE, USEOUTLINES, USETHUMBS or FULLSCREEN.
|
||||
*/
|
||||
public PDFCatalog(PDFPageList pdfPageList,int pagemode) {
|
||||
super("/Catalog");
|
||||
this.pdfPageList = pdfPageList;
|
||||
this.pagemode = pagemode;
|
||||
}
|
||||
|
||||
/**
|
||||
* This sets the root outline object
|
||||
* @param outline The root outline
|
||||
*/
|
||||
protected void setOutline(PDFOutline outline) {
|
||||
this.outlines = outline;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void write(OutputStream os) throws IOException {
|
||||
// Write the object header
|
||||
writeStart(os);
|
||||
|
||||
// now the objects body
|
||||
os.write("/Version /1.7\n".getBytes());
|
||||
public class PDFCatalog extends PDFObject {
|
||||
|
||||
// the /Pages object
|
||||
os.write("/Pages ".getBytes());
|
||||
os.write(pdfPageList.toString().getBytes());
|
||||
os.write("\n".getBytes());
|
||||
|
||||
// the Outlines object
|
||||
if(outlines!=null) {
|
||||
//if(outlines.getLast()>-1) {
|
||||
os.write("/Outlines ".getBytes());
|
||||
os.write(outlines.toString().getBytes());
|
||||
os.write("\n".getBytes());
|
||||
//}
|
||||
/**
|
||||
* The pages of the document
|
||||
*/
|
||||
private PDFPageList pdfPageList;
|
||||
|
||||
/**
|
||||
* The outlines of the document
|
||||
*/
|
||||
private PDFOutline outlines;
|
||||
|
||||
/**
|
||||
* The initial page mode
|
||||
*/
|
||||
private int pagemode;
|
||||
|
||||
/**
|
||||
* This constructs a PDF Catalog object
|
||||
*
|
||||
* @param pdfPageList The PDFPageList object that's the root of the
|
||||
* documents page tree
|
||||
* @param pagemode How the document should appear when opened. Allowed
|
||||
* values are USENONE, USEOUTLINES, USETHUMBS or FULLSCREEN.
|
||||
*/
|
||||
public PDFCatalog(PDFPageList pdfPageList, int pagemode) {
|
||||
super("/Catalog");
|
||||
this.pdfPageList = pdfPageList;
|
||||
this.pagemode = pagemode;
|
||||
}
|
||||
|
||||
/**
|
||||
* This sets the root outline object
|
||||
*
|
||||
* @param outline The root outline
|
||||
*/
|
||||
protected void setOutline(PDFOutline outline) {
|
||||
this.outlines = outline;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void write(OutputStream os) throws IOException {
|
||||
// Write the object header
|
||||
writeStart(os);
|
||||
|
||||
// now the objects body
|
||||
os.write("/Version /1.7\n".getBytes());
|
||||
|
||||
// the /Pages object
|
||||
os.write("/Pages ".getBytes());
|
||||
os.write(pdfPageList.toString().getBytes());
|
||||
os.write("\n".getBytes());
|
||||
|
||||
// the Outlines object
|
||||
if (outlines != null) {
|
||||
//if(outlines.getLast()>-1) {
|
||||
os.write("/Outlines ".getBytes());
|
||||
os.write(outlines.toString().getBytes());
|
||||
os.write("\n".getBytes());
|
||||
//}
|
||||
}
|
||||
|
||||
// the /PageMode setting
|
||||
os.write("/PageMode ".getBytes());
|
||||
os.write(PDFDocument.PDF_PAGE_MODES[pagemode].getBytes());
|
||||
os.write("\n".getBytes());
|
||||
|
||||
// finish off with its footer
|
||||
writeEnd(os);
|
||||
}
|
||||
|
||||
// the /PageMode setting
|
||||
os.write("/PageMode ".getBytes());
|
||||
os.write(PDFDocument.PDF_PAGE_MODES[pagemode].getBytes());
|
||||
os.write("\n".getBytes());
|
||||
|
||||
// finish off with its footer
|
||||
writeEnd(os);
|
||||
}
|
||||
} // end class PDFCatalog
|
||||
|
||||
|
||||
|
||||
@@ -37,230 +37,234 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* <p>This class is the base of the PDF generator. A PDFDocument class is
|
||||
* created for a document, and each page, object, annotation,
|
||||
* etc is added to the document.
|
||||
* Once complete, the document can be written to an OutputStream, and the PDF
|
||||
* document's internal structures are kept in sync.</p>
|
||||
* <p>
|
||||
* This class is the base of the PDF generator. A PDFDocument class is created
|
||||
* for a document, and each page, object, annotation, etc is added to the
|
||||
* document. Once complete, the document can be written to an OutputStream, and
|
||||
* the PDF document's internal structures are kept in sync.</p>
|
||||
*
|
||||
* <p>Note that most programmers using this package will NEVER access
|
||||
* one of these objects directly. Most everything can be done using
|
||||
* <code>PDFJob</code> and <code>PDFGraphics</code>, so you don't need
|
||||
* to directly instantiate a <code>PDFDocument</code></p>
|
||||
* <p>
|
||||
* Note that most programmers using this package will NEVER access one of these
|
||||
* objects directly. Most everything can be done using <code>PDFJob</code> and
|
||||
* <code>PDFGraphics</code>, so you don't need to directly instantiate a
|
||||
* <code>PDFDocument</code></p>
|
||||
*
|
||||
* <p>ezb - 20011115 - Wondering if the constructors should even be public.
|
||||
* When would someone want to make one of these and manipulate it outside
|
||||
* the context of a job and graphics object?</p>
|
||||
* <p>
|
||||
* ezb - 20011115 - Wondering if the constructors should even be public. When
|
||||
* would someone want to make one of these and manipulate it outside the context
|
||||
* of a job and graphics object?</p>
|
||||
*
|
||||
* @author Peter T Mount, http://www.retep.org.uk/pdf/
|
||||
* @author Eric Z. Beard, ericzbeard@hotmail.com
|
||||
* @author Gilbert DeLeeuw, gil1@users.sourceforge.net
|
||||
* @version $Revision: 1.4 $, $Date: 2007/09/22 12:58:40 $
|
||||
*/
|
||||
public class PDFDocument implements Serializable
|
||||
{
|
||||
|
||||
/*
|
||||
public class PDFDocument implements Serializable {
|
||||
|
||||
/*
|
||||
* NOTE: This class originated in uk.org.retep.pdf, by Peter T. Mount, and it
|
||||
* has been modified by Eric Z. Beard, ericzbeard@hotmail.com. The
|
||||
* package name was changed to gnu.jpdf and several inner classes were
|
||||
* moved out into their own files.
|
||||
*/
|
||||
*/
|
||||
/**
|
||||
* This is used to allocate objects a unique serial number in the document.
|
||||
*/
|
||||
protected int objser;
|
||||
|
||||
/**
|
||||
* This is used to allocate objects a unique serial number in the document.
|
||||
*/
|
||||
protected int objser;
|
||||
|
||||
/**
|
||||
* This vector contains each indirect object within the document.
|
||||
*/
|
||||
protected Vector<PDFObject> objects;
|
||||
|
||||
/**
|
||||
* This is the Catalog object, which is required by each PDF Document
|
||||
*/
|
||||
private PDFCatalog catalog;
|
||||
|
||||
/**
|
||||
* This is the info object. Although this is an optional object, we
|
||||
* include it.
|
||||
*/
|
||||
private PDFInfo info;
|
||||
|
||||
/**
|
||||
* This is the Pages object, which is required by each PDF Document
|
||||
*/
|
||||
private PDFPageList pdfPageList;
|
||||
|
||||
/**
|
||||
* This is the Outline object, which is optional
|
||||
*/
|
||||
private PDFOutline outline;
|
||||
|
||||
/**
|
||||
* This holds a PDFObject describing the default border for annotations.
|
||||
* It's only used when the document is being written.
|
||||
*/
|
||||
protected PDFObject defaultOutlineBorder;
|
||||
|
||||
/**
|
||||
* <p>This page mode indicates that the document
|
||||
* should be opened just with the page visible. This is the default</p>
|
||||
*/
|
||||
public static final int USENONE = 0;
|
||||
|
||||
/**
|
||||
* <p>This page mode indicates that the Outlines
|
||||
* should also be displayed when the document is opened.</p>
|
||||
*/
|
||||
public static final int USEOUTLINES = 1;
|
||||
|
||||
/**
|
||||
* <p>This page mode indicates that the Thumbnails should be visible when the
|
||||
* document first opens.</p>
|
||||
*/
|
||||
public static final int USETHUMBS = 2;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This page mode indicates that when the document is opened, it is displayed
|
||||
* in full-screen-mode. There is no menu bar, window controls nor any other
|
||||
* window present.</p>
|
||||
*/
|
||||
public static final int FULLSCREEN = 3;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* These map the page modes just defined to the pagemodes setting of PDF.
|
||||
* </p>
|
||||
*/
|
||||
public static final String PDF_PAGE_MODES[] = {
|
||||
"/UseNone",
|
||||
"/UseOutlines",
|
||||
"/UseThumbs",
|
||||
"/FullScreen"
|
||||
};
|
||||
|
||||
/**
|
||||
* This is used to provide a unique name for a font
|
||||
*/
|
||||
private int fontid = 0;
|
||||
|
||||
/**
|
||||
* <p>This is used to provide a unique name for an image</p>
|
||||
*/
|
||||
private int imageid = 0;
|
||||
|
||||
/**
|
||||
* This holds the current fonts
|
||||
*/
|
||||
private Vector<PDFFont> fonts;
|
||||
|
||||
|
||||
/**
|
||||
* <p>This creates a PDF document with the default pagemode</p>
|
||||
*/
|
||||
public PDFDocument() {
|
||||
this(USENONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>This creates a PDF document</p>
|
||||
* @param pagemode an int, determines how the document will present itself to
|
||||
* the viewer when it first opens.
|
||||
*/
|
||||
public PDFDocument(int pagemode) {
|
||||
objser = 1;
|
||||
objects = new Vector<PDFObject>();
|
||||
fonts = new Vector<PDFFont>();
|
||||
|
||||
// Now create some standard objects
|
||||
add(pdfPageList = new PDFPageList());
|
||||
add(catalog = new PDFCatalog(pdfPageList,pagemode));
|
||||
add(info = new PDFInfo());
|
||||
|
||||
// Acroread on linux seems to die if there is no root outline
|
||||
add(getOutline());
|
||||
}
|
||||
|
||||
/**
|
||||
* This vector contains each indirect object within the document.
|
||||
*/
|
||||
protected Vector<PDFObject> objects;
|
||||
|
||||
/**
|
||||
* This is the Catalog object, which is required by each PDF Document
|
||||
*/
|
||||
private PDFCatalog catalog;
|
||||
|
||||
/**
|
||||
* This adds a top level object to the document.
|
||||
*
|
||||
* <p>Once added, it is allocated a unique serial number.
|
||||
*
|
||||
* <p><b>Note:</b> Not all object are added directly using this method.
|
||||
* Some objects which have Kids (in PDF sub-objects or children are
|
||||
* called Kids) will have their own add() method, which will call this
|
||||
* one internally.
|
||||
*
|
||||
* @param obj The PDFObject to add to the document
|
||||
* @return the unique serial number for this object.
|
||||
*/
|
||||
public synchronized int add(PDFObject obj)
|
||||
{
|
||||
objects.addElement(obj);
|
||||
obj.objser=objser++; // create a new serial number
|
||||
obj.pdfDocument = this; // so they can find the document they belong to
|
||||
|
||||
// If its a page, then add it to the pages collection
|
||||
if(obj instanceof PDFPage)
|
||||
pdfPageList.add((PDFPage)obj);
|
||||
|
||||
return obj.objser;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>This returns a specific page. It's used mainly when using a
|
||||
* Serialized template file.</p>
|
||||
*
|
||||
* ?? How does a serialized template file work ???
|
||||
*
|
||||
* @param page page number to return
|
||||
* @return PDFPage at that position
|
||||
*/
|
||||
public PDFPage getPage(int page) {
|
||||
return pdfPageList.getPage(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the info object. Although this is an optional object, we include
|
||||
* it.
|
||||
*/
|
||||
private PDFInfo info;
|
||||
|
||||
/**
|
||||
* @return the root outline
|
||||
*/
|
||||
public PDFOutline getOutline()
|
||||
{
|
||||
if(outline==null) {
|
||||
outline = new PDFOutline();
|
||||
catalog.setOutline(outline);
|
||||
/**
|
||||
* This is the Pages object, which is required by each PDF Document
|
||||
*/
|
||||
private PDFPageList pdfPageList;
|
||||
|
||||
/**
|
||||
* This is the Outline object, which is optional
|
||||
*/
|
||||
private PDFOutline outline;
|
||||
|
||||
/**
|
||||
* This holds a PDFObject describing the default border for annotations.
|
||||
* It's only used when the document is being written.
|
||||
*/
|
||||
protected PDFObject defaultOutlineBorder;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This page mode indicates that the document should be opened just with the
|
||||
* page visible. This is the default</p>
|
||||
*/
|
||||
public static final int USENONE = 0;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This page mode indicates that the Outlines should also be displayed when
|
||||
* the document is opened.</p>
|
||||
*/
|
||||
public static final int USEOUTLINES = 1;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This page mode indicates that the Thumbnails should be visible when the
|
||||
* document first opens.</p>
|
||||
*/
|
||||
public static final int USETHUMBS = 2;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This page mode indicates that when the document is opened, it is
|
||||
* displayed in full-screen-mode. There is no menu bar, window controls nor
|
||||
* any other window present.</p>
|
||||
*/
|
||||
public static final int FULLSCREEN = 3;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* These map the page modes just defined to the pagemodes setting of PDF.
|
||||
* </p>
|
||||
*/
|
||||
public static final String PDF_PAGE_MODES[] = {
|
||||
"/UseNone",
|
||||
"/UseOutlines",
|
||||
"/UseThumbs",
|
||||
"/FullScreen"
|
||||
};
|
||||
|
||||
/**
|
||||
* This is used to provide a unique name for a font
|
||||
*/
|
||||
private int fontid = 0;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This is used to provide a unique name for an image</p>
|
||||
*/
|
||||
private int imageid = 0;
|
||||
|
||||
/**
|
||||
* This holds the current fonts
|
||||
*/
|
||||
private Vector<PDFFont> fonts;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This creates a PDF document with the default pagemode</p>
|
||||
*/
|
||||
public PDFDocument() {
|
||||
this(USENONE);
|
||||
}
|
||||
return outline;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns a font of the specified type and font. If the font has
|
||||
* not been defined, it creates a new font in the PDF document, and
|
||||
* returns it.
|
||||
*
|
||||
* @param type PDF Font Type - usually "/Type1"
|
||||
* @param font Java font name
|
||||
* @param style java.awt.Font style (NORMAL, BOLD etc)
|
||||
* @return PDFFont defining this font
|
||||
*/
|
||||
public PDFFont getFont(String type,String font,int style) {
|
||||
for(PDFFont ft : fonts) {
|
||||
if(ft.equals(type,font,style))
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This creates a PDF document</p>
|
||||
*
|
||||
* @param pagemode an int, determines how the document will present itself
|
||||
* to the viewer when it first opens.
|
||||
*/
|
||||
public PDFDocument(int pagemode) {
|
||||
objser = 1;
|
||||
objects = new Vector<PDFObject>();
|
||||
fonts = new Vector<PDFFont>();
|
||||
|
||||
// Now create some standard objects
|
||||
add(pdfPageList = new PDFPageList());
|
||||
add(catalog = new PDFCatalog(pdfPageList, pagemode));
|
||||
add(info = new PDFInfo());
|
||||
|
||||
// Acroread on linux seems to die if there is no root outline
|
||||
add(getOutline());
|
||||
}
|
||||
|
||||
/**
|
||||
* This adds a top level object to the document.
|
||||
*
|
||||
* <p>
|
||||
* Once added, it is allocated a unique serial number.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> Not all object are added directly using this method. Some
|
||||
* objects which have Kids (in PDF sub-objects or children are called Kids)
|
||||
* will have their own add() method, which will call this one internally.
|
||||
*
|
||||
* @param obj The PDFObject to add to the document
|
||||
* @return the unique serial number for this object.
|
||||
*/
|
||||
public synchronized int add(PDFObject obj) {
|
||||
objects.addElement(obj);
|
||||
obj.objser = objser++; // create a new serial number
|
||||
obj.pdfDocument = this; // so they can find the document they belong to
|
||||
|
||||
// If its a page, then add it to the pages collection
|
||||
if (obj instanceof PDFPage) {
|
||||
pdfPageList.add((PDFPage) obj);
|
||||
}
|
||||
|
||||
return obj.objser;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This returns a specific page. It's used mainly when using a Serialized
|
||||
* template file.</p>
|
||||
*
|
||||
* ?? How does a serialized template file work ???
|
||||
*
|
||||
* @param page page number to return
|
||||
* @return PDFPage at that position
|
||||
*/
|
||||
public PDFPage getPage(int page) {
|
||||
return pdfPageList.getPage(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the root outline
|
||||
*/
|
||||
public PDFOutline getOutline() {
|
||||
if (outline == null) {
|
||||
outline = new PDFOutline();
|
||||
catalog.setOutline(outline);
|
||||
}
|
||||
return outline;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns a font of the specified type and font. If the font has not
|
||||
* been defined, it creates a new font in the PDF document, and returns it.
|
||||
*
|
||||
* @param type PDF Font Type - usually "/Type1"
|
||||
* @param font Java font name
|
||||
* @param style java.awt.Font style (NORMAL, BOLD etc)
|
||||
* @return PDFFont defining this font
|
||||
*/
|
||||
public PDFFont getFont(String type, String font, int style) {
|
||||
for (PDFFont ft : fonts) {
|
||||
if (ft.equals(type, font, style)) {
|
||||
return ft;
|
||||
}
|
||||
}
|
||||
|
||||
// the font wasn't found, so create it
|
||||
fontid++;
|
||||
PDFFont ft = new PDFFont("/F" + fontid, type, font, style);
|
||||
add(ft);
|
||||
fonts.addElement(ft);
|
||||
return ft;
|
||||
}
|
||||
|
||||
// the font wasn't found, so create it
|
||||
fontid++;
|
||||
PDFFont ft = new PDFFont("/F"+fontid,type,font,style);
|
||||
add(ft);
|
||||
fonts.addElement(ft);
|
||||
return ft;
|
||||
}
|
||||
|
||||
public PDFFont getEmbeddedFont(String font, int style, File file) throws FileNotFoundException, IOException {
|
||||
for (PDFFont ft : fonts) {
|
||||
@@ -301,7 +305,6 @@ public class PDFDocument implements Serializable
|
||||
Logger.getLogger(PDFDocument.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
|
||||
PDFStream cidToGidMap = new PDFStream();
|
||||
cidToGidMap.getOutputStream().write(par.getCidtogidmap());
|
||||
cidToGidMap.setDeflate(true);
|
||||
@@ -378,8 +381,7 @@ public class PDFDocument implements Serializable
|
||||
if (first) {
|
||||
widths.append("" + c + " [" + w);
|
||||
first = false;
|
||||
}
|
||||
else if (c == prevC + 1) {
|
||||
} else if (c == prevC + 1) {
|
||||
widths.append(" " + w);
|
||||
} else {
|
||||
widths.append("]");
|
||||
@@ -392,67 +394,70 @@ public class PDFDocument implements Serializable
|
||||
}
|
||||
return "/W [" + widths.toString() + " ]";
|
||||
}
|
||||
/**
|
||||
* Sets a unique name to a PDFImage
|
||||
* @param img PDFImage to set the name of
|
||||
* @return the name given to the image
|
||||
*/
|
||||
public String setImageName(PDFImage img) {
|
||||
imageid++;
|
||||
img.setName("/Image"+imageid);
|
||||
return img.getName();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>Set the PDFInfo object, which contains author, title,
|
||||
* keywords, etc</p>
|
||||
* @param info a PDFInof object
|
||||
*/
|
||||
public void setPDFInfo(PDFInfo info) {
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>Get the PDFInfo object, which contains author, title, keywords,
|
||||
* etc</p>
|
||||
* @return the PDFInfo object for this document.
|
||||
*/
|
||||
public PDFInfo getPDFInfo() {
|
||||
return this.info;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This writes the document to an OutputStream.
|
||||
*
|
||||
* <p><b>Note:</b> You can call this as many times as you wish, as long as
|
||||
* the calls are not running at the same time.
|
||||
*
|
||||
* <p>Also, objects can be added or amended between these calls.
|
||||
*
|
||||
* <p>Also, the OutputStream is not closed, but will be flushed on
|
||||
* completion. It is up to the caller to close the stream.
|
||||
*
|
||||
* @param os OutputStream to write the document to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void write(OutputStream os) throws IOException
|
||||
{
|
||||
PDFOutput pos = new PDFOutput(os);
|
||||
|
||||
// Write each object to the OutputStream. We call via the output
|
||||
// as that builds the xref table
|
||||
for(PDFObject o : objects) {
|
||||
pos.write(o);
|
||||
/**
|
||||
* Sets a unique name to a PDFImage
|
||||
*
|
||||
* @param img PDFImage to set the name of
|
||||
* @return the name given to the image
|
||||
*/
|
||||
public String setImageName(PDFImage img) {
|
||||
imageid++;
|
||||
img.setName("/Image" + imageid);
|
||||
return img.getName();
|
||||
}
|
||||
|
||||
// Finally close the output, which writes the xref table.
|
||||
pos.close();
|
||||
|
||||
// and flush the output stream to ensure everything is written.
|
||||
os.flush();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Set the PDFInfo object, which contains author, title, keywords, etc</p>
|
||||
*
|
||||
* @param info a PDFInof object
|
||||
*/
|
||||
public void setPDFInfo(PDFInfo info) {
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Get the PDFInfo object, which contains author, title, keywords, etc</p>
|
||||
*
|
||||
* @return the PDFInfo object for this document.
|
||||
*/
|
||||
public PDFInfo getPDFInfo() {
|
||||
return this.info;
|
||||
}
|
||||
|
||||
/**
|
||||
* This writes the document to an OutputStream.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> You can call this as many times as you wish, as long as the
|
||||
* calls are not running at the same time.
|
||||
*
|
||||
* <p>
|
||||
* Also, objects can be added or amended between these calls.
|
||||
*
|
||||
* <p>
|
||||
* Also, the OutputStream is not closed, but will be flushed on completion.
|
||||
* It is up to the caller to close the stream.
|
||||
*
|
||||
* @param os OutputStream to write the document to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void write(OutputStream os) throws IOException {
|
||||
PDFOutput pos = new PDFOutput(os);
|
||||
|
||||
// Write each object to the OutputStream. We call via the output
|
||||
// as that builds the xref table
|
||||
for (PDFObject o : objects) {
|
||||
pos.write(o);
|
||||
}
|
||||
|
||||
// Finally close the output, which writes the xref table.
|
||||
pos.close();
|
||||
|
||||
// and flush the output stream to ensure everything is written.
|
||||
os.flush();
|
||||
}
|
||||
|
||||
} // end class PDFDocument
|
||||
|
||||
@@ -51,14 +51,14 @@ public class PDFEmbeddedFont extends PDFFont {
|
||||
os.write((" " + i).getBytes());
|
||||
}
|
||||
os.write(("]\n").getBytes());
|
||||
*/
|
||||
*/
|
||||
//os.write("/Widths [500 583 587 796]".getBytes());
|
||||
|
||||
/*os.write("/FontDescriptor ".getBytes());
|
||||
os.write(descriptor.getBytes());
|
||||
os.write("\n".getBytes());*/
|
||||
|
||||
/*os.write("/ToUnicode ".getBytes());
|
||||
/*os.write("/ToUnicode ".getBytes());
|
||||
os.write(toUnicode.getBytes());
|
||||
os.write("\n".getBytes());*/
|
||||
// finish off with its footer
|
||||
|
||||
@@ -32,219 +32,217 @@ import java.io.Serializable;
|
||||
* @author Gilbert DeLeeuw, gil1@users.sourceforge.net
|
||||
* @version $Revision: 1.3 $, $Date: 2007/08/26 19:00:11 $
|
||||
*/
|
||||
public class PDFFont extends PDFObject implements Serializable
|
||||
{
|
||||
public class PDFFont extends PDFObject implements Serializable {
|
||||
|
||||
/*
|
||||
/*
|
||||
* NOTE: The original class is the work of Peter T. Mount, who released it
|
||||
* in the uk.org.retep.pdf package. It was modified by Eric Z. Beard as
|
||||
* follows:
|
||||
* The package name was changed to gnu.pdf.
|
||||
* The formatting was changed a little bit
|
||||
* It is still licensed under the LGPL.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The PDF document name of the font
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* The PDF type of the font, usually /Type1
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* The font's real name
|
||||
*/
|
||||
private String font;
|
||||
|
||||
/**
|
||||
* The name of the equivalent Java font
|
||||
*/
|
||||
private String javaFont;
|
||||
|
||||
/**
|
||||
* The PDF Style, ie: BOLD, ITALIC, etc
|
||||
*/
|
||||
private int style;
|
||||
|
||||
/**
|
||||
* This constructs a default PDFFont. In this case Helvetica
|
||||
*/
|
||||
protected PDFFont() {
|
||||
this("/F1","/Type1","Helvetica",Font.PLAIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a PDFFont. This will attempt to map the font from a known
|
||||
* Java font name to that in PDF, defaulting to Helvetica if not possible.
|
||||
*
|
||||
* @param name The document name, ie /F1
|
||||
* @param type The pdf type, ie /Type1
|
||||
* @param font The font name, ie Helvetica
|
||||
* @param style The java.awt.Font style, ie: Font.PLAIN
|
||||
*/
|
||||
public PDFFont(String name,String type,String font,int style) {
|
||||
super("/Font");
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.style = style;
|
||||
|
||||
String f = font.toLowerCase();
|
||||
|
||||
// default PDF Font name
|
||||
*/
|
||||
/**
|
||||
* The PDF document name of the font
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* The PDF type of the font, usually /Type1
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* The font's real name
|
||||
*/
|
||||
private String font;
|
||||
|
||||
/**
|
||||
* The name of the equivalent Java font
|
||||
*/
|
||||
private String javaFont;
|
||||
|
||||
/**
|
||||
* The PDF Style, ie: BOLD, ITALIC, etc
|
||||
*/
|
||||
private int style;
|
||||
|
||||
/**
|
||||
* This constructs a default PDFFont. In this case Helvetica
|
||||
*/
|
||||
protected PDFFont() {
|
||||
this("/F1", "/Type1", "Helvetica", Font.PLAIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a PDFFont. This will attempt to map the font from a known Java
|
||||
* font name to that in PDF, defaulting to Helvetica if not possible.
|
||||
*
|
||||
* @param name The document name, ie /F1
|
||||
* @param type The pdf type, ie /Type1
|
||||
* @param font The font name, ie Helvetica
|
||||
* @param style The java.awt.Font style, ie: Font.PLAIN
|
||||
*/
|
||||
public PDFFont(String name, String type, String font, int style) {
|
||||
super("/Font");
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.style = style;
|
||||
|
||||
String f = font.toLowerCase();
|
||||
|
||||
// default PDF Font name
|
||||
// this.font = base14[0][1];
|
||||
// this.javaFont = base14[0][0];
|
||||
this.font = font;
|
||||
this.javaFont = "/" + font;
|
||||
|
||||
// attempt to translate the font name from Java to PDF
|
||||
for(int i=0;i<base14.length;i++) {
|
||||
if(base14[i][0].equals(f)) {
|
||||
this.javaFont = base14[i][0];
|
||||
this.font = base14[i][1+style];
|
||||
//System.out.println("Setting a font style to: " + this.font);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the most common method to use.
|
||||
* @return the Font name within the PDF document.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Font's PDF type
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The PDF Font name
|
||||
*/
|
||||
public String getFont() {
|
||||
return font;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the font style.
|
||||
* @see java.awt.Font
|
||||
*/
|
||||
public int getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void write(OutputStream os) throws IOException {
|
||||
// Write the object header
|
||||
writeStart(os);
|
||||
|
||||
// now the objects body
|
||||
os.write("/Subtype ".getBytes());
|
||||
os.write(type.getBytes());
|
||||
os.write("\n/Name ".getBytes());
|
||||
os.write(name.getBytes());
|
||||
os.write("\n/BaseFont ".getBytes());
|
||||
os.write(font.getBytes());
|
||||
// The performance problem in Bug#106693 comments out the
|
||||
// encoding line, and removes the /WinAnsiEncoding. I'm going
|
||||
// to leave them in, as the Encoding fixes another problem.
|
||||
os.write("\n/Encoding ".getBytes());
|
||||
os.write("/WinAnsiEncoding".getBytes());
|
||||
//os.write(encoding.getBytes());
|
||||
os.write("\n".getBytes());
|
||||
|
||||
// finish off with its footer
|
||||
writeEnd(os);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used by the PDF and PDFPage classes to compare font names
|
||||
*
|
||||
* @param type The pdf type, ie /Type1
|
||||
* @param font The font name, ie Helvetica
|
||||
* @param style The java.awt.Font style, ie: Font.PLAIN
|
||||
* @return true if this object is identical to this font's spec
|
||||
*/
|
||||
protected boolean equals(String type,String font,int style) {
|
||||
return this.type.equals(type)
|
||||
&& (this.font.equalsIgnoreCase(font)
|
||||
|| this.javaFont.equalsIgnoreCase(font));
|
||||
// new styles not being picked up - ezb june 6 2001
|
||||
// || this.javaFont.equalsIgnoreCase(font));
|
||||
|
||||
// Removed in fix for Bug#106693
|
||||
//why? - ezb - can't find bug in bug tracker
|
||||
//&& this.style==style;
|
||||
}
|
||||
|
||||
/**
|
||||
* This maps the standard JDK1.1 font names and styles to
|
||||
* the base 14 PDF fonts
|
||||
*/
|
||||
private static String[][] base14 = {
|
||||
// java name
|
||||
// NORMAL
|
||||
// BOLD
|
||||
// ITALIC
|
||||
// BOLD+ITALIC
|
||||
{
|
||||
"arial",
|
||||
"/Helvetica",
|
||||
"/Helvetica-Bold",
|
||||
"/Helvetica-Oblique",
|
||||
"/Helvetica-BoldOblique" },
|
||||
{
|
||||
"sansserif",
|
||||
"/Helvetica",
|
||||
"/Helvetica-Bold",
|
||||
"/Helvetica-Oblique",
|
||||
"/Helvetica-BoldOblique" },
|
||||
{
|
||||
"monospaced",
|
||||
"/Courier",
|
||||
"/Courier-Bold",
|
||||
"/Courier-Oblique",
|
||||
"/Courier-BoldOblique" },
|
||||
{
|
||||
"timesroman",
|
||||
"/Times-Roman",
|
||||
"/Times-Bold",
|
||||
"/Times-Italic",
|
||||
"/Times-BoldItalic" },
|
||||
{
|
||||
"courier",
|
||||
"/Courier",
|
||||
"/Courier-Bold",
|
||||
"/Courier-Oblique",
|
||||
"/Courier-BoldOblique" },
|
||||
{
|
||||
"helvetica",
|
||||
"/Helvetica",
|
||||
"/Helvetica-Bold",
|
||||
"/Helvetica-Oblique",
|
||||
"/Helvetica-BoldOblique" },
|
||||
{
|
||||
"dialog",
|
||||
"/Courier",
|
||||
"/Courier-Bold",
|
||||
"/Courier-Oblique",
|
||||
"/Courier-BoldOblique" },
|
||||
{
|
||||
"dialoginput",
|
||||
"/Courier",
|
||||
"/Courier-Bold",
|
||||
"/Courier-Oblique",
|
||||
"/Courier-BoldOblique" }, };
|
||||
|
||||
}
|
||||
this.font = font;
|
||||
this.javaFont = "/" + font;
|
||||
|
||||
// attempt to translate the font name from Java to PDF
|
||||
for (int i = 0; i < base14.length; i++) {
|
||||
if (base14[i][0].equals(f)) {
|
||||
this.javaFont = base14[i][0];
|
||||
this.font = base14[i][1 + style];
|
||||
//System.out.println("Setting a font style to: " + this.font);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the most common method to use.
|
||||
*
|
||||
* @return the Font name within the PDF document.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Font's PDF type
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The PDF Font name
|
||||
*/
|
||||
public String getFont() {
|
||||
return font;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the font style.
|
||||
* @see java.awt.Font
|
||||
*/
|
||||
public int getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void write(OutputStream os) throws IOException {
|
||||
// Write the object header
|
||||
writeStart(os);
|
||||
|
||||
// now the objects body
|
||||
os.write("/Subtype ".getBytes());
|
||||
os.write(type.getBytes());
|
||||
os.write("\n/Name ".getBytes());
|
||||
os.write(name.getBytes());
|
||||
os.write("\n/BaseFont ".getBytes());
|
||||
os.write(font.getBytes());
|
||||
// The performance problem in Bug#106693 comments out the
|
||||
// encoding line, and removes the /WinAnsiEncoding. I'm going
|
||||
// to leave them in, as the Encoding fixes another problem.
|
||||
os.write("\n/Encoding ".getBytes());
|
||||
os.write("/WinAnsiEncoding".getBytes());
|
||||
//os.write(encoding.getBytes());
|
||||
os.write("\n".getBytes());
|
||||
|
||||
// finish off with its footer
|
||||
writeEnd(os);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used by the PDF and PDFPage classes to compare font names
|
||||
*
|
||||
* @param type The pdf type, ie /Type1
|
||||
* @param font The font name, ie Helvetica
|
||||
* @param style The java.awt.Font style, ie: Font.PLAIN
|
||||
* @return true if this object is identical to this font's spec
|
||||
*/
|
||||
protected boolean equals(String type, String font, int style) {
|
||||
return this.type.equals(type)
|
||||
&& (this.font.equalsIgnoreCase(font)
|
||||
|| this.javaFont.equalsIgnoreCase(font));
|
||||
// new styles not being picked up - ezb june 6 2001
|
||||
// || this.javaFont.equalsIgnoreCase(font));
|
||||
|
||||
// Removed in fix for Bug#106693
|
||||
//why? - ezb - can't find bug in bug tracker
|
||||
//&& this.style==style;
|
||||
}
|
||||
|
||||
/**
|
||||
* This maps the standard JDK1.1 font names and styles to the base 14 PDF
|
||||
* fonts
|
||||
*/
|
||||
private static String[][] base14 = {
|
||||
// java name
|
||||
// NORMAL
|
||||
// BOLD
|
||||
// ITALIC
|
||||
// BOLD+ITALIC
|
||||
{
|
||||
"arial",
|
||||
"/Helvetica",
|
||||
"/Helvetica-Bold",
|
||||
"/Helvetica-Oblique",
|
||||
"/Helvetica-BoldOblique"},
|
||||
{
|
||||
"sansserif",
|
||||
"/Helvetica",
|
||||
"/Helvetica-Bold",
|
||||
"/Helvetica-Oblique",
|
||||
"/Helvetica-BoldOblique"},
|
||||
{
|
||||
"monospaced",
|
||||
"/Courier",
|
||||
"/Courier-Bold",
|
||||
"/Courier-Oblique",
|
||||
"/Courier-BoldOblique"},
|
||||
{
|
||||
"timesroman",
|
||||
"/Times-Roman",
|
||||
"/Times-Bold",
|
||||
"/Times-Italic",
|
||||
"/Times-BoldItalic"},
|
||||
{
|
||||
"courier",
|
||||
"/Courier",
|
||||
"/Courier-Bold",
|
||||
"/Courier-Oblique",
|
||||
"/Courier-BoldOblique"},
|
||||
{
|
||||
"helvetica",
|
||||
"/Helvetica",
|
||||
"/Helvetica-Bold",
|
||||
"/Helvetica-Oblique",
|
||||
"/Helvetica-BoldOblique"},
|
||||
{
|
||||
"dialog",
|
||||
"/Courier",
|
||||
"/Courier-Bold",
|
||||
"/Courier-Oblique",
|
||||
"/Courier-BoldOblique"},
|
||||
{
|
||||
"dialoginput",
|
||||
"/Courier",
|
||||
"/Courier-Bold",
|
||||
"/Courier-Oblique",
|
||||
"/Courier-BoldOblique"},};
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -26,18 +26,19 @@ import java.util.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
/**
|
||||
* <p>This implements the Image XObject. Calling one of the
|
||||
* <code>drawImage</code> methods of <code>PDFGraphics</code> will
|
||||
* put all the necessary code into the pdf file, and the image will
|
||||
* be encoded in ascii base 85, then deflated in zip format.</p>
|
||||
* <p>
|
||||
* This implements the Image XObject. Calling one of the <code>drawImage</code>
|
||||
* methods of <code>PDFGraphics</code> will put all the necessary code into the
|
||||
* pdf file, and the image will be encoded in ascii base 85, then deflated in
|
||||
* zip format.</p>
|
||||
*
|
||||
* @author Eric Z. Beard (original version by Peter Mount)
|
||||
* @author Matthew Hreljac, mhreljac@hotmail.com
|
||||
* @version $Revision: 1.2 $, $Date: 2007/08/26 18:56:35 $
|
||||
*/
|
||||
public class PDFImage extends PDFStream implements ImageObserver, Serializable
|
||||
{
|
||||
/*
|
||||
public class PDFImage extends PDFStream implements ImageObserver, Serializable {
|
||||
|
||||
/*
|
||||
* NOTE: The original class is the work of Peter T. Mount, who released it
|
||||
* in the uk.org.retep.pdf package. It was modified by Eric Z. Beard as
|
||||
* follows:
|
||||
@@ -47,206 +48,211 @@ public class PDFImage extends PDFStream implements ImageObserver, Serializable
|
||||
* class was mostly rewritten
|
||||
* It is still licensed under the LGPL.
|
||||
* Got some help with base85 methods from Mathew Hreljac
|
||||
*/
|
||||
*/
|
||||
|
||||
// Dimensions of the object.
|
||||
private int objwidth;
|
||||
private int objheight;
|
||||
|
||||
// Dimensions of the object.
|
||||
private int objwidth;
|
||||
private int objheight;
|
||||
// Dimensions of the image.
|
||||
private int width;
|
||||
private int height;
|
||||
private Image img;
|
||||
private String name;
|
||||
|
||||
// Dimensions of the image.
|
||||
private int width;
|
||||
private int height;
|
||||
private Image img;
|
||||
private String name;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>PDFImage</code> instance.
|
||||
*
|
||||
*/
|
||||
public PDFImage()
|
||||
{
|
||||
super("/XObject");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>PDFImage</code> instance.
|
||||
*
|
||||
* @param img an <code>Image</code> value
|
||||
*/
|
||||
public PDFImage(Image img) {
|
||||
this();
|
||||
setImage(img, 0, 0, img.getWidth(this), img.getHeight(this), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>PDFImage</code> instance.
|
||||
*
|
||||
* @param img an <code>Image</code> value
|
||||
* @param x an <code>int</code> value
|
||||
* @param y an <code>int</code> value
|
||||
* @param w an <code>int</code> value
|
||||
* @param h an <code>int</code> value
|
||||
* @param obs an <code>ImageObserver</code> value
|
||||
*/
|
||||
public PDFImage(Image img,int x,int y,int w,int h,ImageObserver obs) {
|
||||
this();
|
||||
objwidth = w;
|
||||
objheight = h;
|
||||
setImage(img, x, y, img.getWidth(this), img.getHeight(this), obs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of width.
|
||||
* @return value of width.
|
||||
*/
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of width.
|
||||
* @param v Value to assign to width.
|
||||
*/
|
||||
public void setWidth(int v) {
|
||||
this.width = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of height.
|
||||
* @return value of height.
|
||||
*/
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of height.
|
||||
* @param v Value to assign to height.
|
||||
*/
|
||||
public void setHeight(int v) {
|
||||
this.height = v;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the name
|
||||
*
|
||||
* @param n a <code>String</code> value
|
||||
*/
|
||||
public void setName(String n) {
|
||||
name = n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name
|
||||
*
|
||||
* @return a <code>String</code> value
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the image
|
||||
*
|
||||
* @param img an <code>Image</code> value
|
||||
* @param x an <code>int</code> value
|
||||
* @param y an <code>int</code> value
|
||||
* @param w an <code>int</code> value
|
||||
* @param h an <code>int</code> value
|
||||
* @param obs an <code>ImageObserver</code> value
|
||||
*/
|
||||
public void setImage(Image img,int x,int y,int w,int h,ImageObserver obs) {
|
||||
this.img = img;
|
||||
width = w;
|
||||
height = h;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>Adobe's base 85 does not follow the format used by ipv6
|
||||
* addresses. It simply starts with 33 and goes straight up without
|
||||
* skipping any characters</p>
|
||||
*
|
||||
* <p>Parts of this method contributed by Mathew Hreljac</p>
|
||||
*
|
||||
* @param stringToEncode a <code>String</code> value
|
||||
* @return a <code>String</code> value
|
||||
*/
|
||||
private String base85Encoding(String stringToEncode)
|
||||
throws NumberFormatException {
|
||||
if ((stringToEncode == null) || (stringToEncode.length() == 0)) {
|
||||
//System.out.println("PDFImage.base85Encoding() null or blank String");
|
||||
return "";
|
||||
/**
|
||||
* Creates a new <code>PDFImage</code> instance.
|
||||
*
|
||||
*/
|
||||
public PDFImage() {
|
||||
super("/XObject");
|
||||
}
|
||||
if ((stringToEncode.length() > 8) ||
|
||||
((stringToEncode.length() % 2) != 0)) {
|
||||
System.out.println("PDFImage.base85Encoding, Incorrect tuple length: " +
|
||||
stringToEncode.length());
|
||||
return "";
|
||||
|
||||
/**
|
||||
* Creates a new <code>PDFImage</code> instance.
|
||||
*
|
||||
* @param img an <code>Image</code> value
|
||||
*/
|
||||
public PDFImage(Image img) {
|
||||
this();
|
||||
setImage(img, 0, 0, img.getWidth(this), img.getHeight(this), this);
|
||||
}
|
||||
//System.out.println("str: " + stringToEncode);
|
||||
// String buffer to use to return the String encoding
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
// Deal with a partial tuple (less than 8 hex digits)
|
||||
// From Adobe's docs:
|
||||
// "Given n (1, 2 or 3) bytes of binary data, the encoding first
|
||||
// appends 4 - n zero bytes to make a complete 4-tuple. This 4-tuple
|
||||
// is encoded in the usual way, but without applying the special
|
||||
// z-case. Finally, only the first n+1 characters of the resulting
|
||||
// 5-tuple are written out. Those characters are immediately followed
|
||||
// by the EOD marker, ~>"
|
||||
|
||||
int numHexDigits = stringToEncode.length() / 2;
|
||||
int numAppendBytes = 4 - numHexDigits;
|
||||
for (int i = 0; i < numAppendBytes; i++) {
|
||||
stringToEncode += "00";
|
||||
/**
|
||||
* Creates a new <code>PDFImage</code> instance.
|
||||
*
|
||||
* @param img an <code>Image</code> value
|
||||
* @param x an <code>int</code> value
|
||||
* @param y an <code>int</code> value
|
||||
* @param w an <code>int</code> value
|
||||
* @param h an <code>int</code> value
|
||||
* @param obs an <code>ImageObserver</code> value
|
||||
*/
|
||||
public PDFImage(Image img, int x, int y, int w, int h, ImageObserver obs) {
|
||||
this();
|
||||
objwidth = w;
|
||||
objheight = h;
|
||||
setImage(img, x, y, img.getWidth(this), img.getHeight(this), obs);
|
||||
}
|
||||
Vector<Integer> digitVector = new Vector<Integer>();
|
||||
long number = Long.parseLong(stringToEncode, 16);
|
||||
int remainder = 0;
|
||||
|
||||
while (number >= 85) {
|
||||
remainder = (int) (number % 85);
|
||||
number = number / 85;
|
||||
digitVector.add( 0, new Integer( remainder ) );
|
||||
/**
|
||||
* Get the value of width.
|
||||
*
|
||||
* @return value of width.
|
||||
*/
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
digitVector.add( 0, new Integer( (int)number ) );
|
||||
|
||||
for ( int i = 0; i < digitVector.size(); i++) {
|
||||
char c = (char) (((Integer)digitVector.elementAt(i)).intValue() + 33);
|
||||
sb.append(c);
|
||||
/**
|
||||
* Set the value of width.
|
||||
*
|
||||
* @param v Value to assign to width.
|
||||
*/
|
||||
public void setWidth(int v) {
|
||||
this.width = v;
|
||||
}
|
||||
String tuple = sb.toString();
|
||||
int len = tuple.length();
|
||||
switch (len) {
|
||||
case 1: tuple = "!!!!" + tuple; break;
|
||||
case 2: tuple = "!!!" + tuple; break;
|
||||
case 3: tuple = "!!" + tuple; break;
|
||||
case 4: tuple = "!" + tuple; break;
|
||||
default: break;
|
||||
} // end switch
|
||||
//System.out.println("enc tuple: " + tuple);
|
||||
|
||||
return (tuple);
|
||||
} // end base85encoding
|
||||
/**
|
||||
* Get the value of height.
|
||||
*
|
||||
* @return value of height.
|
||||
*/
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of height.
|
||||
*
|
||||
* @param v Value to assign to height.
|
||||
*/
|
||||
public void setHeight(int v) {
|
||||
this.height = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name
|
||||
*
|
||||
* @param n a <code>String</code> value
|
||||
*/
|
||||
public void setName(String n) {
|
||||
name = n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the image to the stream
|
||||
*
|
||||
* @param os an <code>OutputStream</code> value
|
||||
* @exception IOException if an error occurs
|
||||
*/
|
||||
public void writeStream(OutputStream os) throws IOException {
|
||||
// This is a non-deflated stream
|
||||
/*
|
||||
/**
|
||||
* Get the name
|
||||
*
|
||||
* @return a <code>String</code> value
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the image
|
||||
*
|
||||
* @param img an <code>Image</code> value
|
||||
* @param x an <code>int</code> value
|
||||
* @param y an <code>int</code> value
|
||||
* @param w an <code>int</code> value
|
||||
* @param h an <code>int</code> value
|
||||
* @param obs an <code>ImageObserver</code> value
|
||||
*/
|
||||
public void setImage(Image img, int x, int y, int w, int h, ImageObserver obs) {
|
||||
this.img = img;
|
||||
width = w;
|
||||
height = h;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Adobe's base 85 does not follow the format used by ipv6 addresses. It
|
||||
* simply starts with 33 and goes straight up without skipping any
|
||||
* characters</p>
|
||||
*
|
||||
* <p>
|
||||
* Parts of this method contributed by Mathew Hreljac</p>
|
||||
*
|
||||
* @param stringToEncode a <code>String</code> value
|
||||
* @return a <code>String</code> value
|
||||
*/
|
||||
private String base85Encoding(String stringToEncode)
|
||||
throws NumberFormatException {
|
||||
if ((stringToEncode == null) || (stringToEncode.length() == 0)) {
|
||||
//System.out.println("PDFImage.base85Encoding() null or blank String");
|
||||
return "";
|
||||
}
|
||||
if ((stringToEncode.length() > 8)
|
||||
|| ((stringToEncode.length() % 2) != 0)) {
|
||||
System.out.println("PDFImage.base85Encoding, Incorrect tuple length: "
|
||||
+ stringToEncode.length());
|
||||
return "";
|
||||
}
|
||||
//System.out.println("str: " + stringToEncode);
|
||||
// String buffer to use to return the String encoding
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
// Deal with a partial tuple (less than 8 hex digits)
|
||||
// From Adobe's docs:
|
||||
// "Given n (1, 2 or 3) bytes of binary data, the encoding first
|
||||
// appends 4 - n zero bytes to make a complete 4-tuple. This 4-tuple
|
||||
// is encoded in the usual way, but without applying the special
|
||||
// z-case. Finally, only the first n+1 characters of the resulting
|
||||
// 5-tuple are written out. Those characters are immediately followed
|
||||
// by the EOD marker, ~>"
|
||||
int numHexDigits = stringToEncode.length() / 2;
|
||||
int numAppendBytes = 4 - numHexDigits;
|
||||
for (int i = 0; i < numAppendBytes; i++) {
|
||||
stringToEncode += "00";
|
||||
}
|
||||
Vector<Integer> digitVector = new Vector<Integer>();
|
||||
long number = Long.parseLong(stringToEncode, 16);
|
||||
int remainder = 0;
|
||||
|
||||
while (number >= 85) {
|
||||
remainder = (int) (number % 85);
|
||||
number = number / 85;
|
||||
digitVector.add(0, new Integer(remainder));
|
||||
}
|
||||
digitVector.add(0, new Integer((int) number));
|
||||
|
||||
for (int i = 0; i < digitVector.size(); i++) {
|
||||
char c = (char) (((Integer) digitVector.elementAt(i)).intValue() + 33);
|
||||
sb.append(c);
|
||||
}
|
||||
String tuple = sb.toString();
|
||||
int len = tuple.length();
|
||||
switch (len) {
|
||||
case 1:
|
||||
tuple = "!!!!" + tuple;
|
||||
break;
|
||||
case 2:
|
||||
tuple = "!!!" + tuple;
|
||||
break;
|
||||
case 3:
|
||||
tuple = "!!" + tuple;
|
||||
break;
|
||||
case 4:
|
||||
tuple = "!" + tuple;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} // end switch
|
||||
//System.out.println("enc tuple: " + tuple);
|
||||
|
||||
return (tuple);
|
||||
} // end base85encoding
|
||||
|
||||
/**
|
||||
* Writes the image to the stream
|
||||
*
|
||||
* @param os an <code>OutputStream</code> value
|
||||
* @exception IOException if an error occurs
|
||||
*/
|
||||
public void writeStream(OutputStream os) throws IOException {
|
||||
// This is a non-deflated stream
|
||||
/*
|
||||
os.write("/Length ".getBytes());
|
||||
// Accout for stream\n ... >\nendstream
|
||||
os.write(Integer.toString(buf.size() + 18).getBytes());
|
||||
@@ -254,156 +260,150 @@ public class PDFImage extends PDFStream implements ImageObserver, Serializable
|
||||
os.write("\n>>\nstream\n".getBytes());
|
||||
buf.writeTo(os);
|
||||
os.write(">\nendstream\nendobj\n\n".getBytes());
|
||||
*/
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
DeflaterOutputStream dos = new DeflaterOutputStream(b);
|
||||
buf.writeTo(dos);
|
||||
dos.finish();
|
||||
dos.close();
|
||||
*/
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
DeflaterOutputStream dos = new DeflaterOutputStream(b);
|
||||
buf.writeTo(dos);
|
||||
dos.finish();
|
||||
dos.close();
|
||||
|
||||
// FlatDecode is compatible with the java.util.zip.Deflater class
|
||||
//os.write("/Filter [/FlateDecode /ASCIIHexDecode]\n".getBytes());
|
||||
os.write("/Filter [/FlateDecode /ASCII85Decode]\n".getBytes());
|
||||
os.write("/Length ".getBytes());
|
||||
os.write(Integer.toString(b.size()).getBytes());
|
||||
os.write("\n>>\nstream\n".getBytes());
|
||||
b.writeTo(os);
|
||||
os.write("\nendstream\nendobj\n".getBytes());
|
||||
// FlatDecode is compatible with the java.util.zip.Deflater class
|
||||
//os.write("/Filter [/FlateDecode /ASCIIHexDecode]\n".getBytes());
|
||||
os.write("/Filter [/FlateDecode /ASCII85Decode]\n".getBytes());
|
||||
os.write("/Length ".getBytes());
|
||||
os.write(Integer.toString(b.size()).getBytes());
|
||||
os.write("\n>>\nstream\n".getBytes());
|
||||
b.writeTo(os);
|
||||
os.write("\nendstream\nendobj\n".getBytes());
|
||||
|
||||
} // end writeStream
|
||||
} // end writeStream
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Compression needs to be improved here</p>
|
||||
*
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void write(OutputStream os) throws IOException {
|
||||
writeStart(os);
|
||||
|
||||
/**
|
||||
* <p>Compression needs to be improved here</p>
|
||||
*
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void write(OutputStream os) throws IOException
|
||||
{
|
||||
writeStart(os);
|
||||
// write the extra details
|
||||
os.write("/Subtype /Image\n/Name ".getBytes());
|
||||
os.write(name.getBytes());
|
||||
os.write("\n/Width ".getBytes());
|
||||
os.write(Integer.toString(width).getBytes());
|
||||
os.write("\n/Height ".getBytes());
|
||||
os.write(Integer.toString(height).getBytes());
|
||||
os.write("\n/BitsPerComponent 8\n/ColorSpace /DeviceRGB\n".getBytes());
|
||||
|
||||
// write the extra details
|
||||
os.write("/Subtype /Image\n/Name ".getBytes());
|
||||
os.write(name.getBytes());
|
||||
os.write("\n/Width ".getBytes());
|
||||
os.write(Integer.toString(width).getBytes());
|
||||
os.write("\n/Height ".getBytes());
|
||||
os.write(Integer.toString(height).getBytes());
|
||||
os.write("\n/BitsPerComponent 8\n/ColorSpace /DeviceRGB\n".getBytes());
|
||||
// write the pixels to the stream
|
||||
//System.err.println("Processing image "+width+"x"+height+" pixels");
|
||||
ByteArrayOutputStream bos = getStream();
|
||||
|
||||
// write the pixels to the stream
|
||||
//System.err.println("Processing image "+width+"x"+height+" pixels");
|
||||
ByteArrayOutputStream bos = getStream();
|
||||
|
||||
int w = width;
|
||||
int h = height;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int[] pixels = new int[w * h];
|
||||
PixelGrabber pg = new PixelGrabber(img, x, y, w, h, pixels, 0, w);
|
||||
try {
|
||||
pg.grabPixels();
|
||||
} catch (InterruptedException e) {
|
||||
System.err.println("interrupted waiting for pixels!");
|
||||
return;
|
||||
}
|
||||
if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
|
||||
System.err.println("image fetch aborted or errored");
|
||||
return;
|
||||
}
|
||||
StringBuffer out = new StringBuffer();
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
//System.out.print("p[" + j * w + i+ "]=" + pixels[j * w + i] + ".");
|
||||
out.append(handlePixel(x+i, y+j, pixels[j * w + i]));
|
||||
if (out.toString().length() >= 8) {
|
||||
String tuple = out.substring(0, 8);
|
||||
out.delete(0, 8);
|
||||
// Convert !!!!! to 'z'
|
||||
String encTuple = base85Encoding(tuple);
|
||||
if (encTuple.equals("!!!!!")) {
|
||||
encTuple = "z";
|
||||
}
|
||||
bos.write(encTuple.getBytes());
|
||||
int w = width;
|
||||
int h = height;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int[] pixels = new int[w * h];
|
||||
PixelGrabber pg = new PixelGrabber(img, x, y, w, h, pixels, 0, w);
|
||||
try {
|
||||
pg.grabPixels();
|
||||
} catch (InterruptedException e) {
|
||||
System.err.println("interrupted waiting for pixels!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
|
||||
System.err.println("image fetch aborted or errored");
|
||||
return;
|
||||
}
|
||||
StringBuffer out = new StringBuffer();
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
//System.out.print("p[" + j * w + i+ "]=" + pixels[j * w + i] + ".");
|
||||
out.append(handlePixel(x + i, y + j, pixels[j * w + i]));
|
||||
if (out.toString().length() >= 8) {
|
||||
String tuple = out.substring(0, 8);
|
||||
out.delete(0, 8);
|
||||
// Convert !!!!! to 'z'
|
||||
String encTuple = base85Encoding(tuple);
|
||||
if (encTuple.equals("!!!!!")) {
|
||||
encTuple = "z";
|
||||
}
|
||||
bos.write(encTuple.getBytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
// This should be the only partial tuple case,
|
||||
|
||||
String lastTuple = base85Encoding(out.toString());
|
||||
//System.out.println("lastTuple: " + lastTuple);
|
||||
bos.write(lastTuple.getBytes());
|
||||
bos.write("~".getBytes());
|
||||
|
||||
//System.out.println("Processing done");
|
||||
// this will write the actual stream
|
||||
setDeflate(false);
|
||||
|
||||
writeStream(os);
|
||||
|
||||
// Note: we do not call writeEnd() on streams!
|
||||
}
|
||||
// This should be the only partial tuple case,
|
||||
|
||||
String lastTuple = base85Encoding(out.toString());
|
||||
//System.out.println("lastTuple: " + lastTuple);
|
||||
bos.write(lastTuple.getBytes());
|
||||
bos.write("~".getBytes());
|
||||
/**
|
||||
* <p>
|
||||
* Converts a pixel to a hex string</p>
|
||||
*
|
||||
* @param x an <code>int</code> value
|
||||
* @param y an <code>int</code> value
|
||||
* @param p an <code>int</code> value
|
||||
* @return a <code>String</code> value
|
||||
*/
|
||||
public static String handlePixel(int x, int y, int p) {
|
||||
int alpha = (p >> 24) & 0xff;
|
||||
int red = (p >> 16) & 0xff;
|
||||
int green = (p >> 8) & 0xff;
|
||||
int blue = (p) & 0xff;
|
||||
String redHex = Integer.toHexString(red);
|
||||
String greenHex = Integer.toHexString(green);
|
||||
String blueHex = Integer.toHexString(blue);
|
||||
if (redHex.length() == 1) {
|
||||
redHex = "0" + redHex;
|
||||
}
|
||||
if (greenHex.length() == 1) {
|
||||
greenHex = "0" + greenHex;
|
||||
}
|
||||
if (blueHex.length() == 1) {
|
||||
blueHex = "0" + blueHex;
|
||||
}
|
||||
return redHex + greenHex + blueHex;
|
||||
} // end handlePixel
|
||||
|
||||
/**
|
||||
* Describe <code>imageUpdate</code> method here.
|
||||
*
|
||||
* @param img an <code>Image</code> value
|
||||
* @param infoflags an <code>int</code> value
|
||||
* @param x an <code>int</code> value
|
||||
* @param y an <code>int</code> value
|
||||
* @param w an <code>int</code> value
|
||||
* @param h an <code>int</code> value
|
||||
* @return a <code>boolean</code> value
|
||||
*/
|
||||
public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
|
||||
System.err.println("img=" + img + "\ninfoflags=" + infoflags
|
||||
+ "\nx=" + x + " y=" + y + " w=" + w + " h=" + h);
|
||||
//if(img == this.img) {
|
||||
if (infoflags == ImageObserver.WIDTH) {
|
||||
width = w;
|
||||
}
|
||||
if (infoflags == ImageObserver.HEIGHT) {
|
||||
height = h;
|
||||
}
|
||||
|
||||
//System.out.println("Processing done");
|
||||
|
||||
// this will write the actual stream
|
||||
setDeflate(false);
|
||||
|
||||
writeStream(os);
|
||||
|
||||
// Note: we do not call writeEnd() on streams!
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>Converts a pixel to a hex string</p>
|
||||
*
|
||||
* @param x an <code>int</code> value
|
||||
* @param y an <code>int</code> value
|
||||
* @param p an <code>int</code> value
|
||||
* @return a <code>String</code> value
|
||||
*/
|
||||
public static String handlePixel(int x, int y, int p) {
|
||||
int alpha = (p >> 24) & 0xff;
|
||||
int red = (p >> 16) & 0xff;
|
||||
int green = (p >> 8) & 0xff;
|
||||
int blue = (p ) & 0xff;
|
||||
String redHex = Integer.toHexString(red);
|
||||
String greenHex = Integer.toHexString(green);
|
||||
String blueHex = Integer.toHexString(blue);
|
||||
if (redHex.length() == 1) {
|
||||
redHex = "0" + redHex;
|
||||
//return true;
|
||||
//}
|
||||
return false;
|
||||
}
|
||||
if (greenHex.length() == 1) {
|
||||
greenHex = "0" + greenHex;
|
||||
}
|
||||
if (blueHex.length() == 1) {
|
||||
blueHex = "0" + blueHex;
|
||||
}
|
||||
return redHex + greenHex + blueHex;
|
||||
} // end handlePixel
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Describe <code>imageUpdate</code> method here.
|
||||
*
|
||||
* @param img an <code>Image</code> value
|
||||
* @param infoflags an <code>int</code> value
|
||||
* @param x an <code>int</code> value
|
||||
* @param y an <code>int</code> value
|
||||
* @param w an <code>int</code> value
|
||||
* @param h an <code>int</code> value
|
||||
* @return a <code>boolean</code> value
|
||||
*/
|
||||
public boolean imageUpdate(Image img,int infoflags,int x,int y,int w,int h) {
|
||||
System.err.println("img="+img+"\ninfoflags="+infoflags+
|
||||
"\nx="+x+" y="+y+" w="+w+" h="+h);
|
||||
//if(img == this.img) {
|
||||
if(infoflags==ImageObserver.WIDTH)
|
||||
width = w;
|
||||
if(infoflags==ImageObserver.HEIGHT)
|
||||
height = h;
|
||||
|
||||
//return true;
|
||||
//}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // end class PDFImage
|
||||
|
||||
@@ -24,170 +24,176 @@ package gnu.jpdf;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* <p>This class stores details of the author, the PDF generator etc.
|
||||
* The values are accessible via the PDFDocument class.</p>
|
||||
* <p>
|
||||
* This class stores details of the author, the PDF generator etc. The values
|
||||
* are accessible via the PDFDocument class.</p>
|
||||
*
|
||||
* @author Peter T. Mount
|
||||
* @author Eric Z. Beard, ericzbeard@hotmail.com
|
||||
* @version $Revision: 1.2 $, $Date: 2007/08/26 18:56:35 $
|
||||
|
||||
*
|
||||
*/
|
||||
public class PDFInfo extends PDFObject
|
||||
{
|
||||
private String author;
|
||||
private String creator;
|
||||
private String title;
|
||||
private String subject;
|
||||
private String keywords;
|
||||
public class PDFInfo extends PDFObject {
|
||||
|
||||
/**
|
||||
* This constructs a minimal info object
|
||||
*/
|
||||
public PDFInfo() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param title Title of this document
|
||||
*/
|
||||
public PDFInfo(String title) {
|
||||
this();
|
||||
this.title = title;
|
||||
}
|
||||
private String author;
|
||||
private String creator;
|
||||
private String title;
|
||||
private String subject;
|
||||
private String keywords;
|
||||
|
||||
/**
|
||||
* This constructs a minimal info object
|
||||
*/
|
||||
public PDFInfo() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of author.
|
||||
* @return value of author.
|
||||
*/
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of author.
|
||||
* @param v Value to assign to author.
|
||||
*/
|
||||
public void setAuthor(String v) {
|
||||
this.author = v;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param title Title of this document
|
||||
*/
|
||||
public PDFInfo(String title) {
|
||||
this();
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
/**
|
||||
* PDF has two values, a Creator and a Producer. The creator field is
|
||||
* available for calling code. The producer is fixed by this library.
|
||||
* Get the value of creator.
|
||||
* @return value of creator.
|
||||
*/
|
||||
public String getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of creator.
|
||||
* @param v Value to assign to creator.
|
||||
*/
|
||||
public void setCreator(String v) {
|
||||
this.creator = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of title.
|
||||
* @return value of title.
|
||||
*/
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of title.
|
||||
* @param v Value to assign to title.
|
||||
*/
|
||||
public void setTitle(String v) {
|
||||
this.title = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of subject.
|
||||
* @return value of subject.
|
||||
*/
|
||||
public String getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of subject.
|
||||
* @param v Value to assign to subject.
|
||||
*/
|
||||
public void setSubject(String v) {
|
||||
this.subject = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of keywords.
|
||||
* @return value of keywords.
|
||||
*/
|
||||
public String getKeywords() {
|
||||
return keywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of keywords.
|
||||
* @param v Value to assign to keywords.
|
||||
*/
|
||||
public void setKeywords(String v) {
|
||||
this.keywords = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void write(OutputStream os) throws IOException {
|
||||
// Write the object header
|
||||
writeStart(os);
|
||||
|
||||
// now the objects body
|
||||
|
||||
if(author!=null) {
|
||||
os.write("/Author (".getBytes());
|
||||
os.write(PDFStringHelper.makePDFString(author).getBytes());
|
||||
os.write(")\n".getBytes());
|
||||
/**
|
||||
* Get the value of author.
|
||||
*
|
||||
* @return value of author.
|
||||
*/
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
if(creator!=null) {
|
||||
os.write("/Creator (".getBytes());
|
||||
os.write(PDFStringHelper.makePDFString(creator).getBytes());
|
||||
os.write(")\n".getBytes());
|
||||
|
||||
/**
|
||||
* Set the value of author.
|
||||
*
|
||||
* @param v Value to assign to author.
|
||||
*/
|
||||
public void setAuthor(String v) {
|
||||
this.author = v;
|
||||
}
|
||||
|
||||
os.write("/Producer ".getBytes());
|
||||
os.write(PDFStringHelper.makePDFString("gnujpdf - gnujpdf.sourceforge.net")
|
||||
.getBytes());
|
||||
os.write("\n".getBytes());
|
||||
|
||||
if(title!=null) {
|
||||
os.write("/Title ".getBytes());
|
||||
os.write(PDFStringHelper.makePDFString(title).getBytes());
|
||||
os.write("\n".getBytes());
|
||||
|
||||
/**
|
||||
* PDF has two values, a Creator and a Producer. The creator field is
|
||||
* available for calling code. The producer is fixed by this library. Get
|
||||
* the value of creator.
|
||||
*
|
||||
* @return value of creator.
|
||||
*/
|
||||
public String getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
if(subject!=null) {
|
||||
os.write("/Subject (".getBytes());
|
||||
os.write(PDFStringHelper.makePDFString(subject).getBytes());
|
||||
os.write(")\n".getBytes());
|
||||
|
||||
/**
|
||||
* Set the value of creator.
|
||||
*
|
||||
* @param v Value to assign to creator.
|
||||
*/
|
||||
public void setCreator(String v) {
|
||||
this.creator = v;
|
||||
}
|
||||
|
||||
if(keywords!=null) {
|
||||
os.write("/Keywords (".getBytes());
|
||||
os.write(PDFStringHelper.makePDFString(keywords).getBytes());
|
||||
os.write(")\n".getBytes());
|
||||
|
||||
/**
|
||||
* Get the value of title.
|
||||
*
|
||||
* @return value of title.
|
||||
*/
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
// finish off with its footer
|
||||
writeEnd(os);
|
||||
} // end write
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of title.
|
||||
*
|
||||
* @param v Value to assign to title.
|
||||
*/
|
||||
public void setTitle(String v) {
|
||||
this.title = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of subject.
|
||||
*
|
||||
* @return value of subject.
|
||||
*/
|
||||
public String getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of subject.
|
||||
*
|
||||
* @param v Value to assign to subject.
|
||||
*/
|
||||
public void setSubject(String v) {
|
||||
this.subject = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of keywords.
|
||||
*
|
||||
* @return value of keywords.
|
||||
*/
|
||||
public String getKeywords() {
|
||||
return keywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of keywords.
|
||||
*
|
||||
* @param v Value to assign to keywords.
|
||||
*/
|
||||
public void setKeywords(String v) {
|
||||
this.keywords = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void write(OutputStream os) throws IOException {
|
||||
// Write the object header
|
||||
writeStart(os);
|
||||
|
||||
// now the objects body
|
||||
if (author != null) {
|
||||
os.write("/Author (".getBytes());
|
||||
os.write(PDFStringHelper.makePDFString(author).getBytes());
|
||||
os.write(")\n".getBytes());
|
||||
}
|
||||
|
||||
if (creator != null) {
|
||||
os.write("/Creator (".getBytes());
|
||||
os.write(PDFStringHelper.makePDFString(creator).getBytes());
|
||||
os.write(")\n".getBytes());
|
||||
}
|
||||
|
||||
os.write("/Producer ".getBytes());
|
||||
os.write(PDFStringHelper.makePDFString("gnujpdf - gnujpdf.sourceforge.net")
|
||||
.getBytes());
|
||||
os.write("\n".getBytes());
|
||||
|
||||
if (title != null) {
|
||||
os.write("/Title ".getBytes());
|
||||
os.write(PDFStringHelper.makePDFString(title).getBytes());
|
||||
os.write("\n".getBytes());
|
||||
}
|
||||
|
||||
if (subject != null) {
|
||||
os.write("/Subject (".getBytes());
|
||||
os.write(PDFStringHelper.makePDFString(subject).getBytes());
|
||||
os.write(")\n".getBytes());
|
||||
}
|
||||
|
||||
if (keywords != null) {
|
||||
os.write("/Keywords (".getBytes());
|
||||
os.write(PDFStringHelper.makePDFString(keywords).getBytes());
|
||||
os.write(")\n".getBytes());
|
||||
}
|
||||
|
||||
// finish off with its footer
|
||||
writeEnd(os);
|
||||
} // end write
|
||||
|
||||
} // end class PDFInfo
|
||||
|
||||
@@ -30,23 +30,24 @@ import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* <p>This class extends awt's PrintJob, to provide a simple method of writing
|
||||
* PDF documents.</p>
|
||||
* <p>
|
||||
* This class extends awt's PrintJob, to provide a simple method of writing PDF
|
||||
* documents.</p>
|
||||
*
|
||||
* <p>You can use this with any code that uses Java's printing mechanism. It
|
||||
* does include a few extra methods to provide access to some of PDF's features
|
||||
* like annotations, or outlines.</p>
|
||||
* <p>
|
||||
* You can use this with any code that uses Java's printing mechanism. It does
|
||||
* include a few extra methods to provide access to some of PDF's features like
|
||||
* annotations, or outlines.</p>
|
||||
*
|
||||
*
|
||||
* @author Peter T Mount, http://www.retep.org.uk/pdf/
|
||||
* @author Eric Z. Beard, ericzbeard@hotmail.com
|
||||
* @version $Revision: 1.3 $, $Date: 2007/08/26 18:56:35 $
|
||||
*/
|
||||
public class PDFJob extends PrintJob implements Serializable
|
||||
{
|
||||
/*
|
||||
public class PDFJob extends PrintJob implements Serializable {
|
||||
|
||||
/*
|
||||
* NOTE: The original class is the work of Peter T. Mount, who released it
|
||||
* in the uk.org.retep.pdf package. It was modified by Eric Z. Beard as
|
||||
* follows:
|
||||
@@ -58,348 +59,346 @@ public class PDFJob extends PrintJob implements Serializable
|
||||
* Instances of PDFJob come directly from constructors, not
|
||||
* static methods in PDFDocument (which used to be PDF)
|
||||
* It is still licensed under the LGPL.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* This is the OutputStream the PDF file will be written to when complete
|
||||
* Note: This is transient, as it's not valid after being Serialized.
|
||||
*/
|
||||
protected transient OutputStream os;
|
||||
|
||||
/**
|
||||
* This is the PDF file being constructed
|
||||
*/
|
||||
protected PDFDocument pdfDocument;
|
||||
|
||||
/**
|
||||
* This is the current page being constructed by the last getGraphics()
|
||||
* call
|
||||
*/
|
||||
protected PDFPage page;
|
||||
|
||||
/**
|
||||
* This is the page number of the current page
|
||||
*/
|
||||
protected int pagenum;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
/**
|
||||
* <p>This constructs the job. This method must be used when creating a
|
||||
* template pdf file, ie one that is Serialised by one application, and
|
||||
* then restored by another.</p>
|
||||
*
|
||||
* <p>ezb 20011115 - Haven't done anything with templates yet, don't know
|
||||
* how/if they are implemented</p>
|
||||
*/
|
||||
public PDFJob() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>This constructs the job. This is the primary constructor that
|
||||
* will be used for creating pdf documents with this package. The
|
||||
* specified output stream is a handle to the .pdf file you wish to
|
||||
* create.</p>
|
||||
*
|
||||
* @param os - <code>OutputStream</code> to use for the pdf output
|
||||
*/
|
||||
public PDFJob(OutputStream os) {
|
||||
this(os, "PDF Doc");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>This constructs the job. This is the primary constructor that
|
||||
* will be used for creating pdf documents with this package. The
|
||||
* specified output stream is a handle to the .pdf file you wish to
|
||||
* create.</p>
|
||||
*
|
||||
* <p>Use this constructor if you want to give the pdf document a name
|
||||
* other than the default of "PDF Doc"</p>
|
||||
*
|
||||
* @param os - <code>OutputStream</code> to use for the pdf output
|
||||
* @param title a <code>String</code> value
|
||||
*/
|
||||
public PDFJob(OutputStream os, String title) {
|
||||
this.os = os;
|
||||
this.pdfDocument = new PDFDocument();
|
||||
pagenum = 0;
|
||||
pdfDocument.getPDFInfo().setTitle(title);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>This returns a graphics object that can be used to draw on a page.
|
||||
* In PDF, this will be a new page within the document.</p>
|
||||
*
|
||||
* @param orient - the <code>int</code> Orientation of the new page,
|
||||
* as defined in <code>PDFPage</code>
|
||||
* @return Graphics object to draw.
|
||||
* @see PageFormat#PORTRAIT
|
||||
* @see PageFormat#LANDSCAPE
|
||||
* @see PageFormat#REVERSE_LANDSCAPE
|
||||
*/
|
||||
public Graphics getGraphics(int orient) {
|
||||
// create a new page
|
||||
page = new PDFPage(orient);
|
||||
pdfDocument.add(page);
|
||||
pagenum++;
|
||||
|
||||
// Now create a Graphics object to draw onto the page
|
||||
return new graphic(page,this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>This returns a graphics object that can be used to draw on a page.
|
||||
* In PDF, this will be a new page within the document.</p>
|
||||
*
|
||||
* @param pageFormat PageFormat describing the page size
|
||||
* @return Graphics object to draw.
|
||||
*/
|
||||
public Graphics getGraphics(PageFormat pageFormat) {
|
||||
// create a new page
|
||||
page = new PDFPage(pageFormat);
|
||||
pdfDocument.add(page);
|
||||
pagenum++;
|
||||
|
||||
// Now create a Graphics object to draw onto the page
|
||||
return new graphic(page,this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>This writes the PDF document to the OutputStream, finishing the
|
||||
* document.</p>
|
||||
*/
|
||||
public void end() {
|
||||
try {
|
||||
pdfDocument.write(os);
|
||||
} catch(IOException ioe) {
|
||||
// Ideally we should throw this. However, PrintJob doesn't throw
|
||||
// anything, so we will print the Stack Trace instead.
|
||||
ioe.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// This should mark us as dead
|
||||
os = null;
|
||||
pdfDocument = null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>This returns a graphics object that can be used to draw on a page.
|
||||
* In PDF, this will be a new page within the document.</p>
|
||||
*
|
||||
* <p>This new page will by default be oriented as a portrait</p>
|
||||
*
|
||||
* @return a <code>Graphics</code> object to draw to.
|
||||
*/
|
||||
public Graphics getGraphics() {
|
||||
return getGraphics(PageFormat.PORTRAIT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>Returns the page dimension</p>
|
||||
*
|
||||
* @return a <code>Dimension</code> instance, the size of the page
|
||||
*/
|
||||
public Dimension getPageDimension() {
|
||||
if (page == null) {
|
||||
System.err.println("PDFJob.getPageDimension(), page is null");
|
||||
}
|
||||
return page.getDimension();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>How about a setPageDimension(Rectangle media) ?? </p>
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* This returns the page resolution.
|
||||
*
|
||||
* <p>This is the PDF (and Postscript) device resolution of 72 dpi
|
||||
* (equivalent to 1 point).</p>
|
||||
*
|
||||
* @return an <code>int</code>, the resolution in pixels per inch
|
||||
*/
|
||||
public int getPageResolution() {
|
||||
return 72;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>In AWT's PrintJob, this would return true if the user requested that the
|
||||
* file is printed in reverse order. For PDF's this is not applicable, so
|
||||
* it will always return false.</p>
|
||||
*
|
||||
* @return false
|
||||
*/
|
||||
public boolean lastPageFirst() {
|
||||
return false;
|
||||
}
|
||||
|
||||
//======== END OF PrintJob extension ==========
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the PDFDocument object for this document.
|
||||
* Useful for gaining access to
|
||||
* the internals of PDFDocument.
|
||||
* @return the PDF object
|
||||
*/
|
||||
public PDFDocument getPDFDocument() {
|
||||
return pdfDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the current PDFPage being worked on. Useful for working on
|
||||
* Annotations (like links), etc.</p>
|
||||
*
|
||||
* @return the <code>PDFPage</code> currently being constructed
|
||||
*/
|
||||
public PDFPage getCurrentPage() {
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the current page number.
|
||||
* Useful if you need to include one in the document</p>
|
||||
*
|
||||
* @return the <code>int</code> current page number
|
||||
*/
|
||||
public int getCurrentPageNumber() {
|
||||
return pagenum;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>This method attaches an outline to the current page being generated.
|
||||
* When selected, the outline displays the top of the page.</p>
|
||||
*
|
||||
* @param title a <code>String</code>, the title of the Outline
|
||||
* @return a <code>PDFOutline</code> object that was created,
|
||||
* for adding sub-outline's if required.
|
||||
*/
|
||||
public PDFOutline addOutline(String title) {
|
||||
return page.addOutline(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>This method attaches an outline to the current page being generated.
|
||||
* When selected, the outline displays the specified region.</p>
|
||||
*
|
||||
* @param title Outline title to attach
|
||||
* @param x Left coordinate of region
|
||||
* @param y Top coordinate of region
|
||||
* @param w width of region
|
||||
* @param h height of region
|
||||
* @return the <code>PDFOutline</code> object created,
|
||||
* for adding sub-outline's if required.
|
||||
*/
|
||||
public PDFOutline addOutline(String title,int x,int y,int w,int h) {
|
||||
return page.addOutline(title,x,y,w,h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method: Adds a text note to the document.
|
||||
* @param note Text of the note
|
||||
* @param x Coordinate of note
|
||||
* @param y Coordinate of note
|
||||
* @param w Width of the note
|
||||
* @param h Height of the note
|
||||
* @return Returns the annotation, so other settings can be changed.
|
||||
*/
|
||||
public PDFAnnot addNote(String note,int x,int y,int w,int h) {
|
||||
return page.addNote(note,x,y,w,h);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>This inner class extends PDFGraphics for the PrintJob.</p>
|
||||
*
|
||||
* <p>Like with java.awt, Graphics instances created with PrintJob implement
|
||||
* the PrintGraphics interface. Here we implement that method, and overide
|
||||
* PDFGraphics.create() method, so all instances have this interface.</p>
|
||||
*/
|
||||
class graphic extends PDFGraphics implements PrintGraphics {
|
||||
/**
|
||||
* The PDFJob we are linked with
|
||||
*/
|
||||
private PDFJob job;
|
||||
|
||||
|
||||
/**
|
||||
* @param page to attach to
|
||||
* @param job PDFJob containing this graphic
|
||||
* This is the OutputStream the PDF file will be written to when complete
|
||||
* Note: This is transient, as it's not valid after being Serialized.
|
||||
*/
|
||||
graphic(PDFPage page,PDFJob job) {
|
||||
super();
|
||||
this.init(page);
|
||||
this.job = job;
|
||||
}
|
||||
|
||||
protected transient OutputStream os;
|
||||
|
||||
/**
|
||||
* This is used by our version of create()
|
||||
* This is the PDF file being constructed
|
||||
*/
|
||||
graphic(PDFPage page, PDFJob job, RawPrintWriter pw) {
|
||||
super();
|
||||
this.init(page,pw);
|
||||
this.job = job;
|
||||
}
|
||||
|
||||
protected PDFDocument pdfDocument;
|
||||
|
||||
/**
|
||||
* This returns a child instance of this Graphics object. As with AWT,
|
||||
* the affects of using the parent instance while the child exists,
|
||||
* is not determined.
|
||||
* This is the current page being constructed by the last getGraphics() call
|
||||
*/
|
||||
protected PDFPage page;
|
||||
|
||||
/**
|
||||
* This is the page number of the current page
|
||||
*/
|
||||
protected int pagenum;
|
||||
|
||||
// Constructors
|
||||
/**
|
||||
* <p>
|
||||
* This constructs the job. This method must be used when creating a
|
||||
* template pdf file, ie one that is Serialised by one application, and then
|
||||
* restored by another.</p>
|
||||
*
|
||||
* <p>This method is used to make a new Graphics object without
|
||||
* going to a new page</p>
|
||||
*
|
||||
* <p>Once complete, the child should be released with it's dispose()
|
||||
* method which will restore the graphics state to it's parent.
|
||||
*
|
||||
* @return Graphics object
|
||||
* <p>
|
||||
* ezb 20011115 - Haven't done anything with templates yet, don't know
|
||||
* how/if they are implemented</p>
|
||||
*/
|
||||
public Graphics create() {
|
||||
closeBlock();
|
||||
graphic g = new graphic(getPage(),job,getWriter());
|
||||
|
||||
// The new instance inherits a few items
|
||||
g.clipRectangle = new Rectangle(clipRectangle);
|
||||
|
||||
return (Graphics) g;
|
||||
public PDFJob() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is the PrintGraphics interface
|
||||
* @return PrintJob for this object
|
||||
* <p>
|
||||
* This constructs the job. This is the primary constructor that will be
|
||||
* used for creating pdf documents with this package. The specified output
|
||||
* stream is a handle to the .pdf file you wish to create.</p>
|
||||
*
|
||||
* @param os - <code>OutputStream</code> to use for the pdf output
|
||||
*/
|
||||
public PrintJob getPrintJob() {
|
||||
return (PrintJob)job;
|
||||
public PDFJob(OutputStream os) {
|
||||
this(os, "PDF Doc");
|
||||
}
|
||||
|
||||
} // end inner class graphic
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This constructs the job. This is the primary constructor that will be
|
||||
* used for creating pdf documents with this package. The specified output
|
||||
* stream is a handle to the .pdf file you wish to create.</p>
|
||||
*
|
||||
* <p>
|
||||
* Use this constructor if you want to give the pdf document a name other
|
||||
* than the default of "PDF Doc"</p>
|
||||
*
|
||||
* @param os - <code>OutputStream</code> to use for the pdf output
|
||||
* @param title a <code>String</code> value
|
||||
*/
|
||||
public PDFJob(OutputStream os, String title) {
|
||||
this.os = os;
|
||||
this.pdfDocument = new PDFDocument();
|
||||
pagenum = 0;
|
||||
pdfDocument.getPDFInfo().setTitle(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This returns a graphics object that can be used to draw on a page. In
|
||||
* PDF, this will be a new page within the document.</p>
|
||||
*
|
||||
* @param orient - the <code>int</code> Orientation of the new page, as
|
||||
* defined in <code>PDFPage</code>
|
||||
* @return Graphics object to draw.
|
||||
* @see PageFormat#PORTRAIT
|
||||
* @see PageFormat#LANDSCAPE
|
||||
* @see PageFormat#REVERSE_LANDSCAPE
|
||||
*/
|
||||
public Graphics getGraphics(int orient) {
|
||||
// create a new page
|
||||
page = new PDFPage(orient);
|
||||
pdfDocument.add(page);
|
||||
pagenum++;
|
||||
|
||||
// Now create a Graphics object to draw onto the page
|
||||
return new graphic(page, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This returns a graphics object that can be used to draw on a page. In
|
||||
* PDF, this will be a new page within the document.</p>
|
||||
*
|
||||
* @param pageFormat PageFormat describing the page size
|
||||
* @return Graphics object to draw.
|
||||
*/
|
||||
public Graphics getGraphics(PageFormat pageFormat) {
|
||||
// create a new page
|
||||
page = new PDFPage(pageFormat);
|
||||
pdfDocument.add(page);
|
||||
pagenum++;
|
||||
|
||||
// Now create a Graphics object to draw onto the page
|
||||
return new graphic(page, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This writes the PDF document to the OutputStream, finishing the
|
||||
* document.</p>
|
||||
*/
|
||||
public void end() {
|
||||
try {
|
||||
pdfDocument.write(os);
|
||||
} catch (IOException ioe) {
|
||||
// Ideally we should throw this. However, PrintJob doesn't throw
|
||||
// anything, so we will print the Stack Trace instead.
|
||||
ioe.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// This should mark us as dead
|
||||
os = null;
|
||||
pdfDocument = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This returns a graphics object that can be used to draw on a page. In
|
||||
* PDF, this will be a new page within the document.</p>
|
||||
*
|
||||
* <p>
|
||||
* This new page will by default be oriented as a portrait</p>
|
||||
*
|
||||
* @return a <code>Graphics</code> object to draw to.
|
||||
*/
|
||||
public Graphics getGraphics() {
|
||||
return getGraphics(PageFormat.PORTRAIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns the page dimension</p>
|
||||
*
|
||||
* @return a <code>Dimension</code> instance, the size of the page
|
||||
*/
|
||||
public Dimension getPageDimension() {
|
||||
if (page == null) {
|
||||
System.err.println("PDFJob.getPageDimension(), page is null");
|
||||
}
|
||||
return page.getDimension();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* How about a setPageDimension(Rectangle media) ?? </p>
|
||||
*/
|
||||
/**
|
||||
* This returns the page resolution.
|
||||
*
|
||||
* <p>
|
||||
* This is the PDF (and Postscript) device resolution of 72 dpi (equivalent
|
||||
* to 1 point).</p>
|
||||
*
|
||||
* @return an <code>int</code>, the resolution in pixels per inch
|
||||
*/
|
||||
public int getPageResolution() {
|
||||
return 72;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* In AWT's PrintJob, this would return true if the user requested that the
|
||||
* file is printed in reverse order. For PDF's this is not applicable, so it
|
||||
* will always return false.</p>
|
||||
*
|
||||
* @return false
|
||||
*/
|
||||
public boolean lastPageFirst() {
|
||||
return false;
|
||||
}
|
||||
|
||||
//======== END OF PrintJob extension ==========
|
||||
/**
|
||||
* Returns the PDFDocument object for this document. Useful for gaining
|
||||
* access to the internals of PDFDocument.
|
||||
*
|
||||
* @return the PDF object
|
||||
*/
|
||||
public PDFDocument getPDFDocument() {
|
||||
return pdfDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns the current PDFPage being worked on. Useful for working on
|
||||
* Annotations (like links), etc.</p>
|
||||
*
|
||||
* @return the <code>PDFPage</code> currently being constructed
|
||||
*/
|
||||
public PDFPage getCurrentPage() {
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns the current page number. Useful if you need to include one in the
|
||||
* document</p>
|
||||
*
|
||||
* @return the <code>int</code> current page number
|
||||
*/
|
||||
public int getCurrentPageNumber() {
|
||||
return pagenum;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This method attaches an outline to the current page being generated. When
|
||||
* selected, the outline displays the top of the page.</p>
|
||||
*
|
||||
* @param title a <code>String</code>, the title of the Outline
|
||||
* @return a <code>PDFOutline</code> object that was created, for adding
|
||||
* sub-outline's if required.
|
||||
*/
|
||||
public PDFOutline addOutline(String title) {
|
||||
return page.addOutline(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This method attaches an outline to the current page being generated. When
|
||||
* selected, the outline displays the specified region.</p>
|
||||
*
|
||||
* @param title Outline title to attach
|
||||
* @param x Left coordinate of region
|
||||
* @param y Top coordinate of region
|
||||
* @param w width of region
|
||||
* @param h height of region
|
||||
* @return the <code>PDFOutline</code> object created, for adding
|
||||
* sub-outline's if required.
|
||||
*/
|
||||
public PDFOutline addOutline(String title, int x, int y, int w, int h) {
|
||||
return page.addOutline(title, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method: Adds a text note to the document.
|
||||
*
|
||||
* @param note Text of the note
|
||||
* @param x Coordinate of note
|
||||
* @param y Coordinate of note
|
||||
* @param w Width of the note
|
||||
* @param h Height of the note
|
||||
* @return Returns the annotation, so other settings can be changed.
|
||||
*/
|
||||
public PDFAnnot addNote(String note, int x, int y, int w, int h) {
|
||||
return page.addNote(note, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This inner class extends PDFGraphics for the PrintJob.</p>
|
||||
*
|
||||
* <p>
|
||||
* Like with java.awt, Graphics instances created with PrintJob implement
|
||||
* the PrintGraphics interface. Here we implement that method, and overide
|
||||
* PDFGraphics.create() method, so all instances have this interface.</p>
|
||||
*/
|
||||
class graphic extends PDFGraphics implements PrintGraphics {
|
||||
|
||||
/**
|
||||
* The PDFJob we are linked with
|
||||
*/
|
||||
private PDFJob job;
|
||||
|
||||
/**
|
||||
* @param page to attach to
|
||||
* @param job PDFJob containing this graphic
|
||||
*/
|
||||
graphic(PDFPage page, PDFJob job) {
|
||||
super();
|
||||
this.init(page);
|
||||
this.job = job;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used by our version of create()
|
||||
*/
|
||||
graphic(PDFPage page, PDFJob job, RawPrintWriter pw) {
|
||||
super();
|
||||
this.init(page, pw);
|
||||
this.job = job;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns a child instance of this Graphics object. As with AWT,
|
||||
* the affects of using the parent instance while the child exists, is
|
||||
* not determined.
|
||||
*
|
||||
* <p>
|
||||
* This method is used to make a new Graphics object without going to a
|
||||
* new page</p>
|
||||
*
|
||||
* <p>
|
||||
* Once complete, the child should be released with it's dispose()
|
||||
* method which will restore the graphics state to it's parent.
|
||||
*
|
||||
* @return Graphics object
|
||||
*/
|
||||
public Graphics create() {
|
||||
closeBlock();
|
||||
graphic g = new graphic(getPage(), job, getWriter());
|
||||
|
||||
// The new instance inherits a few items
|
||||
g.clipRectangle = new Rectangle(clipRectangle);
|
||||
|
||||
return (Graphics) g;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the PrintGraphics interface
|
||||
*
|
||||
* @return PrintJob for this object
|
||||
*/
|
||||
public PrintJob getPrintJob() {
|
||||
return (PrintJob) job;
|
||||
}
|
||||
|
||||
} // end inner class graphic
|
||||
|
||||
} // end class PDFJob
|
||||
|
||||
|
||||
@@ -30,148 +30,145 @@ import java.util.*;
|
||||
* @author Eric Z. Beard, ericzbeard@hotmail.com
|
||||
* @version $Revision: 1.3 $, $Date: 2007/09/22 12:48:16 $
|
||||
*/
|
||||
public abstract class PDFObject implements Serializable
|
||||
{
|
||||
public abstract class PDFObject implements Serializable {
|
||||
|
||||
/*
|
||||
/*
|
||||
* NOTE: The original class is the work of Peter T. Mount, who released it
|
||||
* in the uk.org.retep.pdf package. It was modified by Eric Z. Beard as
|
||||
* follows:
|
||||
* The package name was changed to gnu.pdf.
|
||||
* The formatting was changed a little bit.
|
||||
* It is still licensed under the LGPL.
|
||||
*/
|
||||
*/
|
||||
/**
|
||||
* This is the object's PDF Type
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* This is the object's PDF Type
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* This is the unique serial number for this object.
|
||||
*/
|
||||
protected int objser;
|
||||
|
||||
/**
|
||||
* This allows any PDF object to refer to the document being constructed.
|
||||
*/
|
||||
protected PDFDocument pdfDocument;
|
||||
|
||||
|
||||
/**
|
||||
* This is usually called by extensors to this class, and sets the
|
||||
* PDF Object Type
|
||||
* @param type the PDF Object Type
|
||||
*/
|
||||
public PDFObject(String type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the PDF Type of this object
|
||||
* @return The PDF Type of this object
|
||||
*/
|
||||
public String getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique serial number of this object.
|
||||
* @return Unique serial number of this object.
|
||||
*/
|
||||
public final int getSerialID()
|
||||
{
|
||||
return objser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the PDF document this object belongs to.
|
||||
* @return PDF containing this object
|
||||
*/
|
||||
public final PDFDocument getPDFDocument()
|
||||
{
|
||||
return pdfDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Writes the object to the output stream.
|
||||
* This method must be overidden.</p>
|
||||
*
|
||||
* <p><b>Note:</b> It should not write any other objects, even if they are
|
||||
* it's Kids, as they will be written by the calling routine.</p>
|
||||
*
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public abstract void write(OutputStream os) throws IOException;
|
||||
|
||||
/**
|
||||
* The write method should call this before writing anything to the
|
||||
* OutputStream. This will send the standard header for each object.
|
||||
*
|
||||
* <p>Note: There are a few rare cases where this method is not called.
|
||||
*
|
||||
* @param os OutputStream to write to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public final void writeStart(OutputStream os) throws IOException
|
||||
{
|
||||
os.write(Integer.toString(objser).getBytes());
|
||||
os.write(" 0 obj\n<<\n".getBytes());
|
||||
if(type!=null) {
|
||||
os.write("/Type ".getBytes());
|
||||
os.write(type.getBytes());
|
||||
os.write("\n".getBytes());
|
||||
/**
|
||||
* This is the unique serial number for this object.
|
||||
*/
|
||||
protected int objser;
|
||||
|
||||
/**
|
||||
* This allows any PDF object to refer to the document being constructed.
|
||||
*/
|
||||
protected PDFDocument pdfDocument;
|
||||
|
||||
/**
|
||||
* This is usually called by extensors to this class, and sets the PDF
|
||||
* Object Type
|
||||
*
|
||||
* @param type the PDF Object Type
|
||||
*/
|
||||
public PDFObject(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The write method should call this after writing anything to the
|
||||
* OutputStream. This will send the standard footer for each object.
|
||||
*
|
||||
* <p>Note: There are a few rare cases where this method is not called.
|
||||
*
|
||||
* @param os OutputStream to write to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public final void writeEnd(OutputStream os) throws IOException
|
||||
{
|
||||
os.write(">>\nendobj\n".getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique serial number in PDF format
|
||||
* @return the serial number in PDF format
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return ""+objser+" 0 R";
|
||||
}
|
||||
|
||||
/**
|
||||
* This utility method returns a String containing an array definition
|
||||
* based on a Vector containing PDFObjects
|
||||
* @param v Vector containing PDFObjects
|
||||
* @return String containing a PDF array
|
||||
*/
|
||||
public static String toArray(Vector<? extends PDFObject> v)
|
||||
{
|
||||
if(v.size()==0)
|
||||
return "";
|
||||
|
||||
StringBuffer b = new StringBuffer();
|
||||
String bs = "[";
|
||||
for(PDFObject x : v) {
|
||||
b.append(bs);
|
||||
b.append(x.toString());
|
||||
bs = " ";
|
||||
/**
|
||||
* Returns the PDF Type of this object
|
||||
*
|
||||
* @return The PDF Type of this object
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique serial number of this object.
|
||||
*
|
||||
* @return Unique serial number of this object.
|
||||
*/
|
||||
public final int getSerialID() {
|
||||
return objser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the PDF document this object belongs to.
|
||||
*
|
||||
* @return PDF containing this object
|
||||
*/
|
||||
public final PDFDocument getPDFDocument() {
|
||||
return pdfDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Writes the object to the output stream. This method must be
|
||||
* overidden.</p>
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> It should not write any other objects, even if they are it's
|
||||
* Kids, as they will be written by the calling routine.</p>
|
||||
*
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public abstract void write(OutputStream os) throws IOException;
|
||||
|
||||
/**
|
||||
* The write method should call this before writing anything to the
|
||||
* OutputStream. This will send the standard header for each object.
|
||||
*
|
||||
* <p>
|
||||
* Note: There are a few rare cases where this method is not called.
|
||||
*
|
||||
* @param os OutputStream to write to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public final void writeStart(OutputStream os) throws IOException {
|
||||
os.write(Integer.toString(objser).getBytes());
|
||||
os.write(" 0 obj\n<<\n".getBytes());
|
||||
if (type != null) {
|
||||
os.write("/Type ".getBytes());
|
||||
os.write(type.getBytes());
|
||||
os.write("\n".getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The write method should call this after writing anything to the
|
||||
* OutputStream. This will send the standard footer for each object.
|
||||
*
|
||||
* <p>
|
||||
* Note: There are a few rare cases where this method is not called.
|
||||
*
|
||||
* @param os OutputStream to write to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public final void writeEnd(OutputStream os) throws IOException {
|
||||
os.write(">>\nendobj\n".getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique serial number in PDF format
|
||||
*
|
||||
* @return the serial number in PDF format
|
||||
*/
|
||||
public String toString() {
|
||||
return "" + objser + " 0 R";
|
||||
}
|
||||
|
||||
/**
|
||||
* This utility method returns a String containing an array definition based
|
||||
* on a Vector containing PDFObjects
|
||||
*
|
||||
* @param v Vector containing PDFObjects
|
||||
* @return String containing a PDF array
|
||||
*/
|
||||
public static String toArray(Vector<? extends PDFObject> v) {
|
||||
if (v.size() == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
StringBuffer b = new StringBuffer();
|
||||
String bs = "[";
|
||||
for (PDFObject x : v) {
|
||||
b.append(bs);
|
||||
b.append(x.toString());
|
||||
bs = " ";
|
||||
}
|
||||
b.append("]");
|
||||
return b.toString();
|
||||
}
|
||||
b.append("]");
|
||||
return b.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,70 +29,67 @@ import java.util.*;
|
||||
* @author Eric Z. Beard, ericzbeard@hotmail.com
|
||||
* @version $Revision: 1.3 $, $Date: 2007/09/22 12:58:40 $
|
||||
*/
|
||||
public class PDFOutline extends PDFObject implements Serializable
|
||||
{
|
||||
public class PDFOutline extends PDFObject implements Serializable {
|
||||
|
||||
/*
|
||||
/*
|
||||
* NOTE: The original class is the work of Peter T. Mount, who released it
|
||||
* in the uk.org.retep.pdf package. It was modified by Eric Z. Beard as
|
||||
* follows:
|
||||
* The package name was changed to gnu.pdf.
|
||||
* The formatting was changed a little bit.
|
||||
* It is still licensed under the LGPL.
|
||||
*/
|
||||
|
||||
*/
|
||||
/**
|
||||
* This holds any outlines below us
|
||||
*/
|
||||
private Vector<PDFOutline> outlines;
|
||||
|
||||
|
||||
/**
|
||||
* For subentries, this points to it's parent outline
|
||||
*/
|
||||
protected PDFOutline parent;
|
||||
|
||||
|
||||
/**
|
||||
* This is this outlines Title
|
||||
*/
|
||||
private String title;
|
||||
|
||||
|
||||
/**
|
||||
* The destination page
|
||||
*/
|
||||
PDFPage dest;
|
||||
|
||||
|
||||
/**
|
||||
* The region on the destination page
|
||||
*/
|
||||
int l,b,r,t;
|
||||
|
||||
int l, b, r, t;
|
||||
|
||||
/**
|
||||
* How the destination is handled
|
||||
*/
|
||||
boolean destMode;
|
||||
|
||||
|
||||
/**
|
||||
* When jumping to the destination, display the whole page
|
||||
*/
|
||||
static final boolean FITPAGE = false;
|
||||
|
||||
|
||||
/**
|
||||
* When jumping to the destination, display the specified region
|
||||
*/
|
||||
static final boolean FITRECT = true;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a PDF Outline object. This method is used internally only.
|
||||
*/
|
||||
protected PDFOutline()
|
||||
{
|
||||
protected PDFOutline() {
|
||||
super("/Outlines");
|
||||
outlines = new Vector<PDFOutline>();
|
||||
title = null;
|
||||
dest = null;
|
||||
destMode = FITPAGE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a PDF Outline object. When selected, the whole page is
|
||||
* displayed.
|
||||
@@ -100,16 +97,15 @@ public class PDFOutline extends PDFObject implements Serializable
|
||||
* @param title Title of the outline
|
||||
* @param dest The destination page
|
||||
*/
|
||||
public PDFOutline(String title,PDFPage dest)
|
||||
{
|
||||
public PDFOutline(String title, PDFPage dest) {
|
||||
this();
|
||||
this.title = title;
|
||||
this.dest = dest;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a PDF Outline object. When selected, the specified region
|
||||
* is displayed.
|
||||
* Constructs a PDF Outline object. When selected, the specified region is
|
||||
* displayed.
|
||||
*
|
||||
* @param title Title of the outline
|
||||
* @param dest The destination page
|
||||
@@ -118,47 +114,46 @@ public class PDFOutline extends PDFObject implements Serializable
|
||||
* @param r right coordinate
|
||||
* @param t top coordinate
|
||||
*/
|
||||
public PDFOutline(String title,PDFPage dest,int l,int b,int r,int t)
|
||||
{
|
||||
this(title,dest);
|
||||
public PDFOutline(String title, PDFPage dest, int l, int b, int r, int t) {
|
||||
this(title, dest);
|
||||
this.destMode = FITRECT;
|
||||
this.l = l;
|
||||
this.b = b;
|
||||
this.r = r;
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method creates an outline, and attaches it to this one.
|
||||
* When the outline is selected, the entire page is displayed.
|
||||
* This method creates an outline, and attaches it to this one. When the
|
||||
* outline is selected, the entire page is displayed.
|
||||
*
|
||||
* <p>This allows you to have an outline for say a Chapter,
|
||||
* then under the chapter, one for each section. You are not really
|
||||
* limited on how deep you go, but it's best not to go below say 6 levels,
|
||||
* for the reader's sake.
|
||||
* <p>
|
||||
* This allows you to have an outline for say a Chapter, then under the
|
||||
* chapter, one for each section. You are not really limited on how deep you
|
||||
* go, but it's best not to go below say 6 levels, for the reader's sake.
|
||||
*
|
||||
* @param title Title of the outline
|
||||
* @param dest The destination page
|
||||
* @return PDFOutline object created, for creating sub-outlines
|
||||
* @return PDFOutline object created, for creating sub-outlines
|
||||
*/
|
||||
public PDFOutline add(String title,PDFPage dest) {
|
||||
PDFOutline outline = new PDFOutline(title,dest);
|
||||
public PDFOutline add(String title, PDFPage dest) {
|
||||
PDFOutline outline = new PDFOutline(title, dest);
|
||||
pdfDocument.add(outline); // add to the pdf first!
|
||||
add(outline);
|
||||
return outline;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method creates an outline, and attaches it to this one.
|
||||
* When the outline is selected, the supplied region is displayed.
|
||||
* This method creates an outline, and attaches it to this one. When the
|
||||
* outline is selected, the supplied region is displayed.
|
||||
*
|
||||
* <p>Note: the coordiates are in Java space. They are converted to User
|
||||
* space.
|
||||
* <p>
|
||||
* Note: the coordiates are in Java space. They are converted to User space.
|
||||
*
|
||||
* <p>This allows you to have an outline for say a Chapter,
|
||||
* then under the chapter, one for each section. You are not really
|
||||
* limited on how deep you go, but it's best not to go below say 6 levels,
|
||||
* for the reader's sake.
|
||||
* <p>
|
||||
* This allows you to have an outline for say a Chapter, then under the
|
||||
* chapter, one for each section. You are not really limited on how deep you
|
||||
* go, but it's best not to go below say 6 levels, for the reader's sake.
|
||||
*
|
||||
* @param title Title of the outline
|
||||
* @param dest The destination page
|
||||
@@ -168,53 +163,51 @@ public class PDFOutline extends PDFObject implements Serializable
|
||||
* @param h height of region in Java space
|
||||
* @return PDFOutline object created, for creating sub-outlines
|
||||
*/
|
||||
public PDFOutline add(String title,PDFPage dest,
|
||||
int x,int y,int w,int h) {
|
||||
int xy1[] = dest.cxy(x,y+h);
|
||||
int xy2[] = dest.cxy(x+w,y);
|
||||
PDFOutline outline = new PDFOutline(title,dest,
|
||||
xy1[0],xy1[1],
|
||||
xy2[0],xy2[1]);
|
||||
public PDFOutline add(String title, PDFPage dest,
|
||||
int x, int y, int w, int h) {
|
||||
int xy1[] = dest.cxy(x, y + h);
|
||||
int xy2[] = dest.cxy(x + w, y);
|
||||
PDFOutline outline = new PDFOutline(title, dest,
|
||||
xy1[0], xy1[1],
|
||||
xy2[0], xy2[1]);
|
||||
pdfDocument.add(outline); // add to the pdf first!
|
||||
add(outline);
|
||||
return outline;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This adds an already existing outline to this one.
|
||||
*
|
||||
* <p>Note: the outline must have been added to the PDF document before
|
||||
* calling this method. Normally the other add methods are used.
|
||||
* <p>
|
||||
* Note: the outline must have been added to the PDF document before calling
|
||||
* this method. Normally the other add methods are used.
|
||||
*
|
||||
* @param outline PDFOutline to add
|
||||
*/
|
||||
public void add(PDFOutline outline)
|
||||
{
|
||||
public void add(PDFOutline outline) {
|
||||
outlines.addElement(outline);
|
||||
|
||||
|
||||
// Tell the outline of ourselves
|
||||
outline.parent = this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void write(OutputStream os) throws IOException
|
||||
{
|
||||
public void write(OutputStream os) throws IOException {
|
||||
// Write the object header
|
||||
writeStart(os);
|
||||
|
||||
|
||||
// now the objects body
|
||||
|
||||
// These are for kids only
|
||||
if(parent!=null) {
|
||||
if (parent != null) {
|
||||
os.write("/Title ".getBytes());
|
||||
os.write(PDFStringHelper.makePDFString(title).getBytes());
|
||||
os.write("\n/Dest [".getBytes());
|
||||
os.write(dest.toString().getBytes());
|
||||
|
||||
if(destMode==FITPAGE) {
|
||||
|
||||
if (destMode == FITPAGE) {
|
||||
//os.write(" null null null]\n/Parent ".getBytes());
|
||||
os.write(" /Fit]\n/Parent ".getBytes());
|
||||
} else {
|
||||
@@ -231,9 +224,9 @@ public class PDFOutline extends PDFObject implements Serializable
|
||||
os.write(parent.toString().getBytes());
|
||||
os.write("\n".getBytes());
|
||||
}
|
||||
|
||||
|
||||
// the number of outlines in this document
|
||||
if(parent==null) {
|
||||
if (parent == null) {
|
||||
// were the top level node, so all are open by default
|
||||
if (outlines.size() > 0) {
|
||||
os.write("/Count ".getBytes());
|
||||
@@ -244,99 +237,97 @@ public class PDFOutline extends PDFObject implements Serializable
|
||||
// were a decendent, so by default we are closed. Find out how many
|
||||
// entries are below us
|
||||
int c = descendants();
|
||||
if(c>0) {
|
||||
if (c > 0) {
|
||||
os.write("/Count ".getBytes());
|
||||
os.write(Integer.toString(-c).getBytes());
|
||||
os.write("\n".getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// These only valid if we have children
|
||||
if(outlines.size()>0) {
|
||||
if (outlines.size() > 0) {
|
||||
// the number of the first outline in list
|
||||
os.write("/First ".getBytes());
|
||||
os.write(outlines.elementAt(0).toString().getBytes());
|
||||
os.write("\n".getBytes());
|
||||
|
||||
|
||||
// the number of the last outline in list
|
||||
os.write("/Last ".getBytes());
|
||||
os.write(outlines.elementAt(outlines.size()-1).toString().getBytes());
|
||||
os.write(outlines.elementAt(outlines.size() - 1).toString().getBytes());
|
||||
os.write("\n".getBytes());
|
||||
}
|
||||
|
||||
if(parent!=null) {
|
||||
|
||||
if (parent != null) {
|
||||
int index = parent.getIndex(this);
|
||||
if(index>0) {
|
||||
if (index > 0) {
|
||||
// Now if were not the first, then we have a /Prev node
|
||||
os.write("/Prev ".getBytes());
|
||||
os.write(parent.getNode(index-1).toString().getBytes());
|
||||
os.write(parent.getNode(index - 1).toString().getBytes());
|
||||
os.write("\n".getBytes());
|
||||
}
|
||||
if(index<parent.getLast()) {
|
||||
if (index < parent.getLast()) {
|
||||
// We have a /Next node
|
||||
os.write("/Next ".getBytes());
|
||||
os.write(parent.getNode(index+1).toString().getBytes());
|
||||
os.write(parent.getNode(index + 1).toString().getBytes());
|
||||
os.write("\n".getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// finish off with its footer
|
||||
writeEnd(os);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is called by children to find their position in this outlines
|
||||
* tree.
|
||||
* This is called by children to find their position in this outlines tree.
|
||||
*
|
||||
* @param outline PDFOutline to search for
|
||||
* @return index within Vector
|
||||
*/
|
||||
protected int getIndex(PDFOutline outline)
|
||||
{
|
||||
protected int getIndex(PDFOutline outline) {
|
||||
return outlines.indexOf(outline);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the last index in this outline
|
||||
*
|
||||
* @return last index in outline
|
||||
*/
|
||||
protected int getLast()
|
||||
{
|
||||
return outlines.size()-1;
|
||||
protected int getLast() {
|
||||
return outlines.size() - 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the outline at a specified position.
|
||||
*
|
||||
* @param i index
|
||||
* @return the node at index i
|
||||
*/
|
||||
protected PDFOutline getNode(int i)
|
||||
{
|
||||
return (PDFOutline)(outlines.elementAt(i));
|
||||
protected PDFOutline getNode(int i) {
|
||||
return (PDFOutline) (outlines.elementAt(i));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all outlines directly below this one.
|
||||
*
|
||||
* @return Enumeration of child elements
|
||||
*/
|
||||
public Enumeration<PDFOutline> elements()
|
||||
{
|
||||
public Enumeration<PDFOutline> elements() {
|
||||
return outlines.elements();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the total number of descendants below this one.
|
||||
*
|
||||
* @return the number of descendants below this one
|
||||
*/
|
||||
protected int descendants()
|
||||
{
|
||||
protected int descendants() {
|
||||
int c = outlines.size(); // initially the number of kids
|
||||
|
||||
|
||||
// now call each one for their descendants
|
||||
for(PDFOutline o : outlines) {
|
||||
for (PDFOutline o : outlines) {
|
||||
c += o.descendants();
|
||||
}
|
||||
|
||||
|
||||
return c;
|
||||
}
|
||||
} // end class PDFOutline
|
||||
|
||||
@@ -25,194 +25,198 @@ import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This class is used to write a PDF document. It acts as a wrapper
|
||||
* to a real OutputStream, but is necessary for certain internal PDF
|
||||
* structures to be built correctly.
|
||||
* This class is used to write a PDF document. It acts as a wrapper to a real
|
||||
* OutputStream, but is necessary for certain internal PDF structures to be
|
||||
* built correctly.
|
||||
*
|
||||
* @author Peter T. Mount
|
||||
* @author Eric Z. Beard, ericzbeard@hotmail.com
|
||||
* @version $Revision: 1.3 $, $Date: 2007/09/22 12:48:16 $
|
||||
*/
|
||||
public class PDFOutput
|
||||
{
|
||||
/**
|
||||
* This is the actual OutputStream used to write to.
|
||||
*/
|
||||
protected OutputStream os;
|
||||
|
||||
/**
|
||||
* This is the OutputStream used to write each object to.
|
||||
*
|
||||
* <p>We use a separate stream, because we need to keep track of how
|
||||
* many bytes have been written for each object for the xref table to
|
||||
* work correctly.
|
||||
*/
|
||||
protected ByteArrayOutputStream baos;
|
||||
|
||||
/**
|
||||
* This is the current position within the stream
|
||||
*/
|
||||
protected int offset;
|
||||
|
||||
/**
|
||||
* This vector contains offsets of each object
|
||||
*/
|
||||
protected Vector<PDFXref> offsets;
|
||||
|
||||
/**
|
||||
* This is used to track the /Root object (catalog)
|
||||
*/
|
||||
protected PDFObject rootID;
|
||||
|
||||
/**
|
||||
* This is used to track the /Info object (info)
|
||||
*/
|
||||
protected PDFObject infoID;
|
||||
|
||||
/**
|
||||
* This creates a PDF OutputStream
|
||||
*
|
||||
* @param os The output stream to write the PDF file to.
|
||||
* @throws IOException if there is an I/O error.
|
||||
*/
|
||||
public PDFOutput(OutputStream os) throws IOException
|
||||
{
|
||||
this.os = os;
|
||||
offset = 0;
|
||||
offsets = new Vector<PDFXref>();
|
||||
baos = new ByteArrayOutputStream();
|
||||
|
||||
// Now write the PDF header
|
||||
//
|
||||
// Note: As the encoding is fixed here, we use getBytes().
|
||||
//
|
||||
baos.write("%PDF-1.2\n".getBytes());
|
||||
|
||||
// This second comment is advised in the PDF Reference manual
|
||||
// page 61
|
||||
baos.write("%\342\343\317\323\n".getBytes());
|
||||
|
||||
offset = baos.size();
|
||||
baos.writeTo(os);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method writes a PDFObject to the stream.
|
||||
*
|
||||
* @param ob PDFObject Obeject to write
|
||||
* @exception IOException on error
|
||||
*/
|
||||
protected void write(PDFObject ob) throws IOException
|
||||
{
|
||||
// Check the object to see if it's one that is needed in the trailer
|
||||
// object
|
||||
if(ob instanceof PDFCatalog) rootID=ob;
|
||||
if(ob instanceof PDFInfo) infoID=ob;
|
||||
|
||||
offsets.addElement(new PDFXref(ob.getSerialID(),offset));
|
||||
baos.reset();
|
||||
ob.write(baos);
|
||||
offset+=baos.size();
|
||||
baos.writeTo(os);
|
||||
}
|
||||
|
||||
/**
|
||||
* This closes the Stream, writing the xref table
|
||||
*/
|
||||
protected void close() throws IOException
|
||||
{
|
||||
// Make sure everything is written
|
||||
os.flush();
|
||||
|
||||
// we use baos to speed things up a little.
|
||||
// Also, offset is preserved, and marks the begining of this block.
|
||||
// This is required by PDF at the end of the PDF file.
|
||||
baos.reset();
|
||||
baos.write("xref\n".getBytes());
|
||||
|
||||
// Now a single subsection for object 0
|
||||
//baos.write("0 1\n0000000000 65535 f \n".getBytes());
|
||||
|
||||
// Now scan through the offsets list. The should be in sequence,
|
||||
// but just in case:
|
||||
int firstid = 0; // First id in block
|
||||
int lastid = -1; // The last id used
|
||||
Vector<PDFXref> block = new Vector<PDFXref>(); // xrefs in this block
|
||||
|
||||
// We need block 0 to exist
|
||||
block.addElement(new PDFXref(0,0,65535));
|
||||
|
||||
for(PDFXref x : offsets) {
|
||||
|
||||
if(firstid==-1) firstid=x.id;
|
||||
|
||||
// check to see if block is in range (-1 means empty)
|
||||
if(lastid>-1 && x.id != (lastid+1)) {
|
||||
// no, so write this block, and reset
|
||||
writeblock(firstid,block);
|
||||
block.removeAllElements();
|
||||
firstid=-1;
|
||||
}
|
||||
|
||||
// now add to block
|
||||
block.addElement(x);
|
||||
lastid = x.id;
|
||||
public class PDFOutput {
|
||||
|
||||
/**
|
||||
* This is the actual OutputStream used to write to.
|
||||
*/
|
||||
protected OutputStream os;
|
||||
|
||||
/**
|
||||
* This is the OutputStream used to write each object to.
|
||||
*
|
||||
* <p>
|
||||
* We use a separate stream, because we need to keep track of how many bytes
|
||||
* have been written for each object for the xref table to work correctly.
|
||||
*/
|
||||
protected ByteArrayOutputStream baos;
|
||||
|
||||
/**
|
||||
* This is the current position within the stream
|
||||
*/
|
||||
protected int offset;
|
||||
|
||||
/**
|
||||
* This vector contains offsets of each object
|
||||
*/
|
||||
protected Vector<PDFXref> offsets;
|
||||
|
||||
/**
|
||||
* This is used to track the /Root object (catalog)
|
||||
*/
|
||||
protected PDFObject rootID;
|
||||
|
||||
/**
|
||||
* This is used to track the /Info object (info)
|
||||
*/
|
||||
protected PDFObject infoID;
|
||||
|
||||
/**
|
||||
* This creates a PDF OutputStream
|
||||
*
|
||||
* @param os The output stream to write the PDF file to.
|
||||
* @throws IOException if there is an I/O error.
|
||||
*/
|
||||
public PDFOutput(OutputStream os) throws IOException {
|
||||
this.os = os;
|
||||
offset = 0;
|
||||
offsets = new Vector<PDFXref>();
|
||||
baos = new ByteArrayOutputStream();
|
||||
|
||||
// Now write the PDF header
|
||||
//
|
||||
// Note: As the encoding is fixed here, we use getBytes().
|
||||
//
|
||||
baos.write("%PDF-1.2\n".getBytes());
|
||||
|
||||
// This second comment is advised in the PDF Reference manual
|
||||
// page 61
|
||||
baos.write("%\342\343\317\323\n".getBytes());
|
||||
|
||||
offset = baos.size();
|
||||
baos.writeTo(os);
|
||||
}
|
||||
|
||||
// now write the last block
|
||||
if(firstid>-1)
|
||||
writeblock(firstid,block);
|
||||
|
||||
// now the trailer object
|
||||
baos.write("trailer\n<<\n".getBytes());
|
||||
|
||||
// the number of entries (REQUIRED)
|
||||
baos.write("/Size ".getBytes());
|
||||
baos.write(Integer.toString(offsets.size()+1).getBytes());
|
||||
baos.write("\n".getBytes());
|
||||
|
||||
// the /Root catalog indirect reference (REQUIRED)
|
||||
if(rootID != null) {
|
||||
baos.write("/Root ".getBytes());
|
||||
baos.write(rootID.toString().getBytes());
|
||||
baos.write("\n".getBytes());
|
||||
} else
|
||||
throw new IOException("Root object is not present in document");
|
||||
|
||||
// the /Info reference (OPTIONAL)
|
||||
if(infoID != null) {
|
||||
baos.write("/Info ".getBytes());
|
||||
baos.write(infoID.toString().getBytes());
|
||||
baos.write("\n".getBytes());
|
||||
|
||||
/**
|
||||
* This method writes a PDFObject to the stream.
|
||||
*
|
||||
* @param ob PDFObject Obeject to write
|
||||
* @exception IOException on error
|
||||
*/
|
||||
protected void write(PDFObject ob) throws IOException {
|
||||
// Check the object to see if it's one that is needed in the trailer
|
||||
// object
|
||||
if (ob instanceof PDFCatalog) {
|
||||
rootID = ob;
|
||||
}
|
||||
if (ob instanceof PDFInfo) {
|
||||
infoID = ob;
|
||||
}
|
||||
|
||||
offsets.addElement(new PDFXref(ob.getSerialID(), offset));
|
||||
baos.reset();
|
||||
ob.write(baos);
|
||||
offset += baos.size();
|
||||
baos.writeTo(os);
|
||||
}
|
||||
|
||||
// end the trailer object
|
||||
baos.write(">>\nstartxref\n".getBytes());
|
||||
baos.write(Integer.toString(offset).getBytes());
|
||||
baos.write("\n%%EOF\n".getBytes());
|
||||
|
||||
// now flush the stream
|
||||
baos.writeTo(os);
|
||||
os.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a block of references to the PDF file
|
||||
* @param firstid ID of the first reference in this block
|
||||
* @param block Vector containing the references in this block
|
||||
* @exception IOException on write error
|
||||
*/
|
||||
protected void writeblock(int firstid,Vector<PDFXref> block) throws IOException
|
||||
{
|
||||
baos.write(Integer.toString(firstid).getBytes());
|
||||
baos.write(" ".getBytes());
|
||||
baos.write(Integer.toString(block.size()).getBytes());
|
||||
baos.write("\n".getBytes());
|
||||
//baos.write("\n0000000000 65535 f\n".getBytes());
|
||||
|
||||
for(PDFXref x : block) {
|
||||
baos.write(x.toString().getBytes());
|
||||
baos.write("\n".getBytes());
|
||||
|
||||
/**
|
||||
* This closes the Stream, writing the xref table
|
||||
*/
|
||||
protected void close() throws IOException {
|
||||
// Make sure everything is written
|
||||
os.flush();
|
||||
|
||||
// we use baos to speed things up a little.
|
||||
// Also, offset is preserved, and marks the begining of this block.
|
||||
// This is required by PDF at the end of the PDF file.
|
||||
baos.reset();
|
||||
baos.write("xref\n".getBytes());
|
||||
|
||||
// Now a single subsection for object 0
|
||||
//baos.write("0 1\n0000000000 65535 f \n".getBytes());
|
||||
// Now scan through the offsets list. The should be in sequence,
|
||||
// but just in case:
|
||||
int firstid = 0; // First id in block
|
||||
int lastid = -1; // The last id used
|
||||
Vector<PDFXref> block = new Vector<PDFXref>(); // xrefs in this block
|
||||
|
||||
// We need block 0 to exist
|
||||
block.addElement(new PDFXref(0, 0, 65535));
|
||||
|
||||
for (PDFXref x : offsets) {
|
||||
|
||||
if (firstid == -1) {
|
||||
firstid = x.id;
|
||||
}
|
||||
|
||||
// check to see if block is in range (-1 means empty)
|
||||
if (lastid > -1 && x.id != (lastid + 1)) {
|
||||
// no, so write this block, and reset
|
||||
writeblock(firstid, block);
|
||||
block.removeAllElements();
|
||||
firstid = -1;
|
||||
}
|
||||
|
||||
// now add to block
|
||||
block.addElement(x);
|
||||
lastid = x.id;
|
||||
}
|
||||
|
||||
// now write the last block
|
||||
if (firstid > -1) {
|
||||
writeblock(firstid, block);
|
||||
}
|
||||
|
||||
// now the trailer object
|
||||
baos.write("trailer\n<<\n".getBytes());
|
||||
|
||||
// the number of entries (REQUIRED)
|
||||
baos.write("/Size ".getBytes());
|
||||
baos.write(Integer.toString(offsets.size() + 1).getBytes());
|
||||
baos.write("\n".getBytes());
|
||||
|
||||
// the /Root catalog indirect reference (REQUIRED)
|
||||
if (rootID != null) {
|
||||
baos.write("/Root ".getBytes());
|
||||
baos.write(rootID.toString().getBytes());
|
||||
baos.write("\n".getBytes());
|
||||
} else {
|
||||
throw new IOException("Root object is not present in document");
|
||||
}
|
||||
|
||||
// the /Info reference (OPTIONAL)
|
||||
if (infoID != null) {
|
||||
baos.write("/Info ".getBytes());
|
||||
baos.write(infoID.toString().getBytes());
|
||||
baos.write("\n".getBytes());
|
||||
}
|
||||
|
||||
// end the trailer object
|
||||
baos.write(">>\nstartxref\n".getBytes());
|
||||
baos.write(Integer.toString(offset).getBytes());
|
||||
baos.write("\n%%EOF\n".getBytes());
|
||||
|
||||
// now flush the stream
|
||||
baos.writeTo(os);
|
||||
os.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a block of references to the PDF file
|
||||
*
|
||||
* @param firstid ID of the first reference in this block
|
||||
* @param block Vector containing the references in this block
|
||||
* @exception IOException on write error
|
||||
*/
|
||||
protected void writeblock(int firstid, Vector<PDFXref> block) throws IOException {
|
||||
baos.write(Integer.toString(firstid).getBytes());
|
||||
baos.write(" ".getBytes());
|
||||
baos.write(Integer.toString(block.size()).getBytes());
|
||||
baos.write("\n".getBytes());
|
||||
//baos.write("\n0000000000 65535 f\n".getBytes());
|
||||
|
||||
for (PDFXref x : block) {
|
||||
baos.write(x.toString().getBytes());
|
||||
baos.write("\n".getBytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end class PDFOutput
|
||||
|
||||
@@ -29,8 +29,9 @@ import java.io.Serializable;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* <p>This class defines a single page within a document. It is linked to a
|
||||
* single PDFGraphics object</p>
|
||||
* <p>
|
||||
* This class defines a single page within a document. It is linked to a single
|
||||
* PDFGraphics object</p>
|
||||
*
|
||||
* @author Peter T Mount
|
||||
* @author Eric Z. Beard, ericzbeard@hotmail.com
|
||||
@@ -39,20 +40,20 @@ import java.util.Vector;
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class PDFPage extends PDFObject implements Serializable
|
||||
{
|
||||
/*
|
||||
public class PDFPage extends PDFObject implements Serializable {
|
||||
|
||||
/*
|
||||
* NOTE: The original class is the work of Peter T. Mount, who released it
|
||||
* in the uk.org.retep.pdf package. It was modified by Eric Z. Beard as
|
||||
* follows:
|
||||
* The package name was changed to gnu.pdf.
|
||||
* The formatting was changed a little bit.
|
||||
* It is still licensed under the LGPL.
|
||||
*/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default page format (Letter size with 1 inch margins and
|
||||
* Portrait orientation)
|
||||
* Default page format (Letter size with 1 inch margins and Portrait
|
||||
* orientation)
|
||||
*/
|
||||
private static final PageFormat DEF_FORMAT = new PageFormat();
|
||||
|
||||
@@ -60,10 +61,10 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
* This is this page format, ie the size of the page, margins, and rotation
|
||||
*/
|
||||
protected PageFormat pageFormat;
|
||||
|
||||
|
||||
/**
|
||||
* This is the pages object id that this page belongs to.
|
||||
* It is set by the pages object when it is added to it.
|
||||
* This is the pages object id that this page belongs to. It is set by the
|
||||
* pages object when it is added to it.
|
||||
*/
|
||||
protected PDFObject pdfPageList;
|
||||
|
||||
@@ -73,8 +74,8 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
protected Vector<PDFObject> contents;
|
||||
|
||||
/**
|
||||
* Object ID that contains a thumbnail sketch of the page.
|
||||
* -1 indicates no thumbnail.
|
||||
* Object ID that contains a thumbnail sketch of the page. -1 indicates no
|
||||
* thumbnail.
|
||||
*/
|
||||
protected PDFObject thumbnail;
|
||||
|
||||
@@ -100,79 +101,79 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
* The xobjects or other images in the pdf
|
||||
*/
|
||||
// protected Vector xobjects;
|
||||
|
||||
/**
|
||||
* These handle the procset for this page.
|
||||
* Refer to page 140 of the PDF Reference manual
|
||||
* NB: Text is handled when the fonts Vector is null, and a font is created
|
||||
* refer to getFont() to see where it's defined
|
||||
* These handle the procset for this page. Refer to page 140 of the PDF
|
||||
* Reference manual NB: Text is handled when the fonts Vector is null, and a
|
||||
* font is created refer to getFont() to see where it's defined
|
||||
*/
|
||||
protected boolean hasImageB,hasImageC,hasImageI;
|
||||
protected boolean hasImageB, hasImageC, hasImageI;
|
||||
protected procset procset;
|
||||
|
||||
/**
|
||||
* This constructs a Page object, which will hold any contents for this
|
||||
* page.
|
||||
*
|
||||
* <p>Once created, it is added to the document via the PDF.add() method.
|
||||
* (For Advanced use, via the PDFPages.add() method).
|
||||
* <p>
|
||||
* Once created, it is added to the document via the PDF.add() method. (For
|
||||
* Advanced use, via the PDFPages.add() method).
|
||||
*
|
||||
* <p>This defaults to a4 media.
|
||||
* <p>
|
||||
* This defaults to a4 media.
|
||||
*/
|
||||
public PDFPage()
|
||||
{
|
||||
public PDFPage() {
|
||||
super("/Page");
|
||||
pageFormat = DEF_FORMAT;
|
||||
contents = new Vector<PDFObject>();
|
||||
thumbnail = null;
|
||||
annotations = new Vector<PDFObject>();
|
||||
resources = new Vector<String>();
|
||||
// JM
|
||||
imageResources = new Vector<String>();
|
||||
fonts = new Vector<PDFFont>();
|
||||
procset = null;
|
||||
pageFormat = DEF_FORMAT;
|
||||
contents = new Vector<PDFObject>();
|
||||
thumbnail = null;
|
||||
annotations = new Vector<PDFObject>();
|
||||
resources = new Vector<String>();
|
||||
// JM
|
||||
imageResources = new Vector<String>();
|
||||
fonts = new Vector<PDFFont>();
|
||||
procset = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a page using A4 media, but using the supplied orientation.
|
||||
*
|
||||
* @param orientation Orientation: 0, 90 or 270
|
||||
* @see PageFormat#PORTRAIT
|
||||
* @see PageFormat#LANDSCAPE
|
||||
* @see PageFormat#REVERSE_LANDSCAPE
|
||||
*/
|
||||
public PDFPage(int orientation)
|
||||
{
|
||||
public PDFPage(int orientation) {
|
||||
this();
|
||||
setOrientation(orientation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a page using the supplied media size and orientation.
|
||||
*
|
||||
* @param pageFormat PageFormat describing the page size
|
||||
*/
|
||||
public PDFPage(PageFormat pageFormat)
|
||||
{
|
||||
public PDFPage(PageFormat pageFormat) {
|
||||
this();
|
||||
this.pageFormat = pageFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds to procset.
|
||||
*
|
||||
* @param proc the String to be added.
|
||||
*/
|
||||
public void addToProcset(String proc) {
|
||||
if (procset == null) {
|
||||
addProcset();
|
||||
}
|
||||
procset.add(proc);
|
||||
if (procset == null) {
|
||||
addProcset();
|
||||
}
|
||||
procset.add(proc);
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns a PDFGraphics object, which can then be used to render
|
||||
* on to this page. If a previous PDFGraphics object was used, this object
|
||||
* is appended to the page, and will be drawn over the top of any previous
|
||||
* This returns a PDFGraphics object, which can then be used to render on to
|
||||
* this page. If a previous PDFGraphics object was used, this object is
|
||||
* appended to the page, and will be drawn over the top of any previous
|
||||
* objects.
|
||||
*
|
||||
*
|
||||
* @return a new PDFGraphics object to be used to draw this page.
|
||||
*/
|
||||
public PDFGraphics getGraphics() {
|
||||
@@ -180,7 +181,7 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
PDFGraphics g = new PDFGraphics();
|
||||
g.init(this);
|
||||
return g;
|
||||
} catch(Exception ex) {
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -189,31 +190,32 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
|
||||
/**
|
||||
* Returns a PDFFont, creating it if not yet used.
|
||||
*
|
||||
* @param type Font type, usually /Type1
|
||||
* @param font Font name
|
||||
* @param style java.awt.Font style, ie Font.NORMAL
|
||||
* @return a PDFFont object.
|
||||
*/
|
||||
public PDFFont getFont(String type,String font,int style) {
|
||||
public PDFFont getFont(String type, String font, int style) {
|
||||
// Search the fonts on this page, and return one that matches this
|
||||
// font.
|
||||
// This keeps the number of font definitions down to one per font/style
|
||||
for(PDFFont ft : fonts) {
|
||||
if(ft.equals(type,font,style))
|
||||
for (PDFFont ft : fonts) {
|
||||
if (ft.equals(type, font, style)) {
|
||||
return ft;
|
||||
}
|
||||
}
|
||||
|
||||
// Ok, the font isn't in the page, so create one.
|
||||
|
||||
// We need a procset if we are using fonts, so create it (if not
|
||||
// already created, and add to our resources
|
||||
if(fonts.size()==0) {
|
||||
if (fonts.size() == 0) {
|
||||
addProcset();
|
||||
procset.add("/Text");
|
||||
}
|
||||
|
||||
// finally create and return the font
|
||||
PDFFont f = pdfDocument.getFont(type,font,style);
|
||||
PDFFont f = pdfDocument.getFont(type, font, style);
|
||||
fonts.addElement(f);
|
||||
return f;
|
||||
}
|
||||
@@ -244,6 +246,7 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
|
||||
/**
|
||||
* Returns the page's PageFormat.
|
||||
*
|
||||
* @return PageFormat describing the page size in device units (72dpi)
|
||||
*/
|
||||
public PageFormat getPageFormat() {
|
||||
@@ -252,45 +255,48 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
|
||||
/**
|
||||
* Gets the dimensions of the page.
|
||||
*
|
||||
* @return a Dimension object containing the width and height of the page.
|
||||
*/
|
||||
public Dimension getDimension() {
|
||||
return new Dimension((int) pageFormat.getWidth(), (int) pageFormat
|
||||
.getHeight());
|
||||
}
|
||||
return new Dimension((int) pageFormat.getWidth(), (int) pageFormat
|
||||
.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the imageable area of the page.
|
||||
*
|
||||
* @return a Rectangle containing the bounds of the imageable area.
|
||||
*/
|
||||
public Rectangle getImageableArea() {
|
||||
return new Rectangle((int) pageFormat.getImageableX(), (int) pageFormat
|
||||
.getImageableY(),
|
||||
(int) (pageFormat.getImageableX() + pageFormat
|
||||
.getImageableWidth()), (int) (pageFormat
|
||||
.getImageableY() + pageFormat.getImageableHeight()));
|
||||
}
|
||||
public Rectangle getImageableArea() {
|
||||
return new Rectangle((int) pageFormat.getImageableX(), (int) pageFormat
|
||||
.getImageableY(),
|
||||
(int) (pageFormat.getImageableX() + pageFormat
|
||||
.getImageableWidth()), (int) (pageFormat
|
||||
.getImageableY() + pageFormat.getImageableHeight()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the page's orientation.
|
||||
*
|
||||
* <p>Normally, this should be done when the page is created, to avoid
|
||||
* <p>
|
||||
* Normally, this should be done when the page is created, to avoid
|
||||
* problems.
|
||||
*
|
||||
* @param orientation a PageFormat orientation constant:
|
||||
* @param orientation a PageFormat orientation constant:
|
||||
* PageFormat.PORTRAIT, PageFormat.LANDSACPE or PageFromat.REVERSE_LANDSACPE
|
||||
*/
|
||||
public void setOrientation(int orientation) {
|
||||
pageFormat.setOrientation(orientation);
|
||||
}
|
||||
pageFormat.setOrientation(orientation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pages orientation:
|
||||
* PageFormat.PORTRAIT, PageFormat.LANDSACPE or PageFromat.REVERSE_LANDSACPE
|
||||
*
|
||||
* @see java.awt.print.PageFormat
|
||||
* @return current orientation of the page
|
||||
*/
|
||||
* Returns the pages orientation: PageFormat.PORTRAIT, PageFormat.LANDSACPE
|
||||
* or PageFromat.REVERSE_LANDSACPE
|
||||
*
|
||||
* @see java.awt.print.PageFormat
|
||||
* @return current orientation of the page
|
||||
*/
|
||||
public int getOrientation() {
|
||||
return pageFormat.getOrientation();
|
||||
}
|
||||
@@ -298,7 +304,8 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
/**
|
||||
* This adds an object that describes some content to this page.
|
||||
*
|
||||
* <p><b>Note:</b> Objects that describe contents must be added using this
|
||||
* <p>
|
||||
* <b>Note:</b> Objects that describe contents must be added using this
|
||||
* method _AFTER_ the PDF.add() method has been called.
|
||||
*
|
||||
* @param ob PDFObject describing some contents
|
||||
@@ -310,8 +317,9 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
/**
|
||||
* This adds an Annotation to the page.
|
||||
*
|
||||
* <p>As with other objects, the annotation must be added to the pdf
|
||||
* document using PDF.add() before adding to the page.
|
||||
* <p>
|
||||
* As with other objects, the annotation must be added to the pdf document
|
||||
* using PDF.add() before adding to the page.
|
||||
*
|
||||
* @param ob Annotation to add.
|
||||
*/
|
||||
@@ -321,6 +329,7 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
|
||||
/**
|
||||
* This method adds a text note to the document.
|
||||
*
|
||||
* @param note Text of the note
|
||||
* @param x Coordinate of note
|
||||
* @param y Coordinate of note
|
||||
@@ -328,12 +337,12 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
* @param h Height of the note
|
||||
* @return Returns the annotation, so other settings can be changed.
|
||||
*/
|
||||
public PDFAnnot addNote(String note,int x,int y,int w,int h) {
|
||||
int xy1[] = cxy(x,y+h);
|
||||
int xy2[] = cxy(x+w,y);
|
||||
PDFAnnot ob = new PDFAnnot(xy1[0],xy1[1],
|
||||
xy2[0],xy2[1],
|
||||
note);
|
||||
public PDFAnnot addNote(String note, int x, int y, int w, int h) {
|
||||
int xy1[] = cxy(x, y + h);
|
||||
int xy2[] = cxy(x + w, y);
|
||||
PDFAnnot ob = new PDFAnnot(xy1[0], xy1[1],
|
||||
xy2[0], xy2[1],
|
||||
note);
|
||||
pdfDocument.add(ob);
|
||||
annotations.addElement(ob);
|
||||
return ob;
|
||||
@@ -341,6 +350,7 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
|
||||
/**
|
||||
* Adds a hyperlink to the document.
|
||||
*
|
||||
* @param x Coordinate of active area
|
||||
* @param y Coordinate of active area
|
||||
* @param w Width of the active area
|
||||
@@ -349,13 +359,13 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
* displayed, the zoom factor will be changed to fit the display.
|
||||
* @return Returns the annotation, so other settings can be changed.
|
||||
*/
|
||||
public PDFAnnot addLink(int x,int y,int w,int h,PDFObject dest) {
|
||||
int xy1[] = cxy(x,y+h);
|
||||
int xy2[] = cxy(x+w,y);
|
||||
PDFAnnot ob = new PDFAnnot(xy1[0],xy1[1],
|
||||
xy2[0],xy2[1],
|
||||
dest
|
||||
);
|
||||
public PDFAnnot addLink(int x, int y, int w, int h, PDFObject dest) {
|
||||
int xy1[] = cxy(x, y + h);
|
||||
int xy2[] = cxy(x + w, y);
|
||||
PDFAnnot ob = new PDFAnnot(xy1[0], xy1[1],
|
||||
xy2[0], xy2[1],
|
||||
dest
|
||||
);
|
||||
pdfDocument.add(ob);
|
||||
annotations.addElement(ob);
|
||||
return ob;
|
||||
@@ -363,6 +373,7 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
|
||||
/**
|
||||
* Adds a hyperlink to the document.
|
||||
*
|
||||
* @param x Coordinate of active area
|
||||
* @param y Coordinate of active area
|
||||
* @param w Width of the active area
|
||||
@@ -374,39 +385,42 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
* @param vh Height of the view area
|
||||
* @return Returns the annotation, so other settings can be changed.
|
||||
*/
|
||||
public PDFAnnot addLink(int x,int y,int w,int h,
|
||||
PDFObject dest,
|
||||
int vx,int vy,int vw,int vh) {
|
||||
int xy1[] = cxy(x,y+h);
|
||||
int xy2[] = cxy(x+w,y);
|
||||
int xy3[] = cxy(vx,vy+vh);
|
||||
int xy4[] = cxy(vx+vw,vy);
|
||||
PDFAnnot ob = new PDFAnnot(xy1[0],xy1[1],
|
||||
xy2[0],xy2[1],
|
||||
dest,
|
||||
xy3[0],xy3[1],
|
||||
xy4[0],xy4[1]
|
||||
);
|
||||
public PDFAnnot addLink(int x, int y, int w, int h,
|
||||
PDFObject dest,
|
||||
int vx, int vy, int vw, int vh) {
|
||||
int xy1[] = cxy(x, y + h);
|
||||
int xy2[] = cxy(x + w, y);
|
||||
int xy3[] = cxy(vx, vy + vh);
|
||||
int xy4[] = cxy(vx + vw, vy);
|
||||
PDFAnnot ob = new PDFAnnot(xy1[0], xy1[1],
|
||||
xy2[0], xy2[1],
|
||||
dest,
|
||||
xy3[0], xy3[1],
|
||||
xy4[0], xy4[1]
|
||||
);
|
||||
pdfDocument.add(ob);
|
||||
annotations.addElement(ob);
|
||||
return ob;
|
||||
}
|
||||
|
||||
/** Contains the text strings for the xobjects. */
|
||||
private Vector<String> xobjects = new Vector<String>();
|
||||
|
||||
/**
|
||||
* This adds an XObject resource to the page.
|
||||
* The string should be of the format
|
||||
* /Name ObjectNumber RevisionNumber R as in /Image1 13 0 R .
|
||||
* Contains the text strings for the xobjects.
|
||||
*/
|
||||
private Vector<String> xobjects = new Vector<String>();
|
||||
|
||||
/**
|
||||
* This adds an XObject resource to the page. The string should be of the
|
||||
* format /Name ObjectNumber RevisionNumber R as in /Image1 13 0 R .
|
||||
*
|
||||
* @param inxobject the XObject resource to be added.
|
||||
*/
|
||||
public void addXObject(String inxobject){
|
||||
public void addXObject(String inxobject) {
|
||||
xobjects.addElement(inxobject);
|
||||
}
|
||||
|
||||
/**
|
||||
* This adds a resource to the page.
|
||||
*
|
||||
* @param resource String defining the resource
|
||||
*/
|
||||
public void addResource(String resource) {
|
||||
@@ -416,6 +430,7 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
// JM
|
||||
/**
|
||||
* This adds an image resource to the page.
|
||||
*
|
||||
* @param resource the XObject resource to be added.
|
||||
*/
|
||||
public void addImageResource(String resource) {
|
||||
@@ -424,34 +439,37 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
|
||||
/**
|
||||
* This adds an object that describes a thumbnail for this page.
|
||||
* <p><b>Note:</b> The object must already exist in the PDF, as only the
|
||||
* object ID is stored.
|
||||
* <p>
|
||||
* <b>Note:</b> The object must already exist in the PDF, as only the object
|
||||
* ID is stored.
|
||||
*
|
||||
* @param thumbnail PDFObject containing the thumbnail
|
||||
*/
|
||||
public void setThumbnail(PDFObject thumbnail)
|
||||
{
|
||||
public void setThumbnail(PDFObject thumbnail) {
|
||||
this.thumbnail = thumbnail;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method attaches an outline to the current page being generated. When
|
||||
* selected, the outline displays the top of the page.
|
||||
*
|
||||
* @param title Outline title to attach
|
||||
* @return PDFOutline object created, for addSubOutline if required.
|
||||
*/
|
||||
public PDFOutline addOutline(String title) {
|
||||
PDFOutline outline = new PDFOutline(title,this);
|
||||
PDFOutline outline = new PDFOutline(title, this);
|
||||
pdfDocument.add(outline);
|
||||
pdfDocument.getOutline().add(outline);
|
||||
return outline;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method attaches an outline to the current page being generated.
|
||||
* When selected, the outline displays the top of the page.
|
||||
* This method attaches an outline to the current page being generated. When
|
||||
* selected, the outline displays the top of the page.
|
||||
*
|
||||
* <p>Note: If the outline is not in the top level (ie below another
|
||||
* outline) then it must <b>not</b> be passed to this method.
|
||||
* <p>
|
||||
* Note: If the outline is not in the top level (ie below another outline)
|
||||
* then it must <b>not</b> be passed to this method.
|
||||
*
|
||||
* @param title Outline title to attach
|
||||
* @param x Left coordinate of region
|
||||
@@ -460,12 +478,12 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
* @param h Height coordinate of region
|
||||
* @return PDFOutline object created, for addSubOutline if required.
|
||||
*/
|
||||
public PDFOutline addOutline(String title,int x,int y,int w,int h) {
|
||||
int xy1[] = cxy(x,y+h);
|
||||
int xy2[] = cxy(x+w,y);
|
||||
PDFOutline outline = new PDFOutline(title,this,
|
||||
xy1[0],xy1[1],
|
||||
xy2[0],xy2[1]);
|
||||
public PDFOutline addOutline(String title, int x, int y, int w, int h) {
|
||||
int xy1[] = cxy(x, y + h);
|
||||
int xy2[] = cxy(x + w, y);
|
||||
PDFOutline outline = new PDFOutline(title, this,
|
||||
xy1[0], xy1[1],
|
||||
xy2[0], xy2[1]);
|
||||
pdfDocument.add(outline);
|
||||
pdfDocument.getOutline().add(outline);
|
||||
return outline;
|
||||
@@ -475,13 +493,11 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void write(OutputStream os) throws IOException
|
||||
{
|
||||
public void write(OutputStream os) throws IOException {
|
||||
// Write the object header
|
||||
writeStart(os);
|
||||
|
||||
// now the objects body
|
||||
|
||||
// the /Parent pages object
|
||||
os.write("/Parent ".getBytes());
|
||||
os.write(pdfPageList.toString().getBytes());
|
||||
@@ -493,9 +509,9 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
os.write(" ".getBytes());
|
||||
os.write(Integer.toString(0).getBytes());
|
||||
os.write(" ".getBytes());
|
||||
os.write(Integer.toString((int)pageFormat.getWidth()).getBytes());
|
||||
os.write(Integer.toString((int) pageFormat.getWidth()).getBytes());
|
||||
os.write(" ".getBytes());
|
||||
os.write(Integer.toString((int)pageFormat.getHeight()).getBytes());
|
||||
os.write(Integer.toString((int) pageFormat.getHeight()).getBytes());
|
||||
os.write("]\n".getBytes());
|
||||
|
||||
// Rotation (if not zero)
|
||||
@@ -504,14 +520,13 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
// os.write(Integer.toString(rotate).getBytes());
|
||||
// os.write("\n".getBytes());
|
||||
// }
|
||||
|
||||
// Now the resources
|
||||
os.write("/Resources << ".getBytes());
|
||||
// fonts
|
||||
if(fonts.size()>0) {
|
||||
//os.write("/Font << ".getBytes());
|
||||
if (fonts.size() > 0) {
|
||||
//os.write("/Font << ".getBytes());
|
||||
os.write("\n/Font << ".getBytes());
|
||||
for(PDFFont font : fonts) {
|
||||
for (PDFFont font : fonts) {
|
||||
os.write(font.getName().getBytes());
|
||||
os.write(" ".getBytes());
|
||||
os.write(font.toString().getBytes());
|
||||
@@ -520,41 +535,41 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
os.write(">> ".getBytes());
|
||||
}
|
||||
// Now the XObjects
|
||||
if (xobjects.size() > 0){
|
||||
if (xobjects.size() > 0) {
|
||||
os.write("\n/XObject << ".getBytes());
|
||||
for(String str : xobjects) {
|
||||
for (String str : xobjects) {
|
||||
os.write(str.getBytes());
|
||||
os.write(" ".getBytes());
|
||||
}
|
||||
os.write(">> ".getBytes());
|
||||
}
|
||||
// Any other resources
|
||||
for(String str : resources) {
|
||||
for (String str : resources) {
|
||||
os.write(str.getBytes());
|
||||
os.write(" ".getBytes());
|
||||
}
|
||||
// JM
|
||||
if(imageResources.size() > 0) {
|
||||
os.write("/XObject << ".getBytes());
|
||||
for(String str : imageResources) {
|
||||
os.write(str.getBytes());
|
||||
os.write(" ".getBytes());
|
||||
}
|
||||
os.write(" >> ".getBytes());
|
||||
}
|
||||
// JM
|
||||
if (imageResources.size() > 0) {
|
||||
os.write("/XObject << ".getBytes());
|
||||
for (String str : imageResources) {
|
||||
os.write(str.getBytes());
|
||||
os.write(" ".getBytes());
|
||||
}
|
||||
os.write(" >> ".getBytes());
|
||||
}
|
||||
os.write(">>\n".getBytes());
|
||||
|
||||
// The thumbnail
|
||||
if(thumbnail!=null) {
|
||||
if (thumbnail != null) {
|
||||
os.write("/Thumb ".getBytes());
|
||||
os.write(thumbnail.toString().getBytes());
|
||||
os.write("\n".getBytes());
|
||||
}
|
||||
|
||||
// the /Contents pages object
|
||||
if(contents.size()>0) {
|
||||
if(contents.size()==1) {
|
||||
PDFObject ob = (PDFObject)contents.elementAt(0);
|
||||
if (contents.size() > 0) {
|
||||
if (contents.size() == 1) {
|
||||
PDFObject ob = (PDFObject) contents.elementAt(0);
|
||||
os.write("/Contents ".getBytes());
|
||||
os.write(ob.toString().getBytes());
|
||||
os.write("\n".getBytes());
|
||||
@@ -566,7 +581,7 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
}
|
||||
|
||||
// The /Annots object
|
||||
if(annotations.size()>0) {
|
||||
if (annotations.size() > 0) {
|
||||
os.write("/Annots ".getBytes());
|
||||
os.write(PDFObject.toArray(annotations).getBytes());
|
||||
os.write("\n".getBytes());
|
||||
@@ -580,9 +595,9 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
* This creates a procset and sets up the page to reference it
|
||||
*/
|
||||
private void addProcset() {
|
||||
if(procset==null) {
|
||||
if (procset == null) {
|
||||
pdfDocument.add(procset = new procset());
|
||||
resources.addElement("/ProcSet "+procset);
|
||||
resources.addElement("/ProcSet " + procset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -590,6 +605,7 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
* This defines a procset
|
||||
*/
|
||||
public class procset extends PDFObject {
|
||||
|
||||
private Vector<String> set;
|
||||
|
||||
/**
|
||||
@@ -608,7 +624,7 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
* @param proc Entry to add to the procset
|
||||
*/
|
||||
public void add(String proc) {
|
||||
set.addElement(" "+proc);
|
||||
set.addElement(" " + proc);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -624,8 +640,9 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
|
||||
// now the objects body
|
||||
os.write("[".getBytes());
|
||||
for(String str : set)
|
||||
for (String str : set) {
|
||||
os.write(str.getBytes());
|
||||
}
|
||||
os.write("]\n".getBytes());
|
||||
|
||||
// finish off with its footer
|
||||
@@ -637,33 +654,36 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
/**
|
||||
* This utility method converts the y coordinate from Java to User space
|
||||
* within the page.
|
||||
*
|
||||
* @param x Coordinate in Java space
|
||||
* @param y Coordinate in Java space
|
||||
* @return y Coordinate in User space
|
||||
*/
|
||||
public int cy(int x,int y) {
|
||||
return cxy(x,y)[1];
|
||||
public int cy(int x, int y) {
|
||||
return cxy(x, y)[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* This utility method converts the y coordinate from Java to User space
|
||||
* within the page.
|
||||
*
|
||||
* @param x Coordinate in Java space
|
||||
* @param y Coordinate in Java space
|
||||
* @return x Coordinate in User space
|
||||
*/
|
||||
public int cx(int x, int y) {
|
||||
return cxy(x,y)[0];
|
||||
return cxy(x, y)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* This utility method converts the Java coordinates to User space
|
||||
* within the page.
|
||||
* This utility method converts the Java coordinates to User space within
|
||||
* the page.
|
||||
*
|
||||
* @param x Coordinate in Java space
|
||||
* @param y Coordinate in Java space
|
||||
* @return array containing the x & y Coordinate in User space
|
||||
*/
|
||||
public int[] cxy(int x,int y) {
|
||||
public int[] cxy(int x, int y) {
|
||||
int r[] = new int[2];
|
||||
r[0] = x;
|
||||
r[1] = (int) pageFormat.getHeight() - y;
|
||||
|
||||
@@ -31,65 +31,64 @@ import java.util.*;
|
||||
* @author Eric Z. Beard, ericzbeard@hotmail.com
|
||||
* @version $Revision: 1.2 $, $Date: 2007/08/26 18:56:35 $
|
||||
*/
|
||||
public class PDFPageList extends PDFObject
|
||||
{
|
||||
|
||||
/**
|
||||
* This holds the pages
|
||||
*/
|
||||
private Vector<PDFPage> pages;
|
||||
|
||||
/**
|
||||
* This constructs a PDF Pages object.
|
||||
*/
|
||||
public PDFPageList() {
|
||||
super("/Pages");
|
||||
pages = new Vector<PDFPage>();
|
||||
}
|
||||
|
||||
/**
|
||||
* This adds a page to the document.
|
||||
*
|
||||
* @param page PDFPage to add
|
||||
*/
|
||||
public void add(PDFPage page) {
|
||||
pages.addElement(page);
|
||||
|
||||
// Tell the page of ourselves
|
||||
page.pdfPageList = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns a specific page. Used by the PDF class.
|
||||
* @param page page number to return
|
||||
* @return PDFPage at that position
|
||||
*/
|
||||
public PDFPage getPage(int page) {
|
||||
return (PDFPage)(pages.elementAt(page));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void write(OutputStream os) throws IOException {
|
||||
// Write the object header
|
||||
writeStart(os);
|
||||
|
||||
// now the objects body
|
||||
|
||||
// the Kids array
|
||||
os.write("/Kids ".getBytes());
|
||||
os.write(PDFObject.toArray(pages).getBytes());
|
||||
os.write("\n".getBytes());
|
||||
|
||||
// the number of Kids in this document
|
||||
os.write("/Count ".getBytes());
|
||||
os.write(Integer.toString(pages.size()).getBytes());
|
||||
os.write("\n".getBytes());
|
||||
|
||||
// finish off with its footer
|
||||
writeEnd(os);
|
||||
}
|
||||
|
||||
public class PDFPageList extends PDFObject {
|
||||
|
||||
/**
|
||||
* This holds the pages
|
||||
*/
|
||||
private Vector<PDFPage> pages;
|
||||
|
||||
/**
|
||||
* This constructs a PDF Pages object.
|
||||
*/
|
||||
public PDFPageList() {
|
||||
super("/Pages");
|
||||
pages = new Vector<PDFPage>();
|
||||
}
|
||||
|
||||
/**
|
||||
* This adds a page to the document.
|
||||
*
|
||||
* @param page PDFPage to add
|
||||
*/
|
||||
public void add(PDFPage page) {
|
||||
pages.addElement(page);
|
||||
|
||||
// Tell the page of ourselves
|
||||
page.pdfPageList = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns a specific page. Used by the PDF class.
|
||||
*
|
||||
* @param page page number to return
|
||||
* @return PDFPage at that position
|
||||
*/
|
||||
public PDFPage getPage(int page) {
|
||||
return (PDFPage) (pages.elementAt(page));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void write(OutputStream os) throws IOException {
|
||||
// Write the object header
|
||||
writeStart(os);
|
||||
|
||||
// now the objects body
|
||||
// the Kids array
|
||||
os.write("/Kids ".getBytes());
|
||||
os.write(PDFObject.toArray(pages).getBytes());
|
||||
os.write("\n".getBytes());
|
||||
|
||||
// the number of Kids in this document
|
||||
os.write("/Count ".getBytes());
|
||||
os.write(Integer.toString(pages.size()).getBytes());
|
||||
os.write("\n".getBytes());
|
||||
|
||||
// finish off with its footer
|
||||
writeEnd(os);
|
||||
}
|
||||
|
||||
} // end class PDFPageList
|
||||
|
||||
@@ -25,250 +25,249 @@ import javax.swing.JFileChooser;
|
||||
* This class extends awt's PrinterJob, to provide a simple method of writing
|
||||
* PDF documents.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* You can use this with any code that uses Java's printing mechanism. It does
|
||||
* include a few extra methods to provide access to some of PDF's features like
|
||||
* annotations, or outlines.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Gilbert DeLeeuw, gil1@users.sourceforge.net
|
||||
*/
|
||||
public class PDFPrinterJob extends PrinterJob {
|
||||
|
||||
/**
|
||||
* The file chooser
|
||||
*/
|
||||
private static JFileChooser fileChooser;
|
||||
/**
|
||||
* The file chooser
|
||||
*/
|
||||
private static JFileChooser fileChooser;
|
||||
|
||||
/**
|
||||
* Printing options;
|
||||
*/
|
||||
private PrintRequestAttributeSet attributes;
|
||||
/**
|
||||
* Printing options;
|
||||
*/
|
||||
private PrintRequestAttributeSet attributes;
|
||||
|
||||
/**
|
||||
* PDF document properties
|
||||
*/
|
||||
private PDFInfo info;
|
||||
/**
|
||||
* PDF document properties
|
||||
*/
|
||||
private PDFInfo info;
|
||||
|
||||
/**
|
||||
* A pageable, or null
|
||||
*/
|
||||
private Pageable pageable = null;
|
||||
/**
|
||||
* A pageable, or null
|
||||
*/
|
||||
private Pageable pageable = null;
|
||||
|
||||
/**
|
||||
* Page format.
|
||||
*/
|
||||
private PageFormat pageFormat;
|
||||
/**
|
||||
* Page format.
|
||||
*/
|
||||
private PageFormat pageFormat;
|
||||
|
||||
/**
|
||||
* The Printable object to print.
|
||||
*/
|
||||
private Printable printable;
|
||||
/**
|
||||
* The Printable object to print.
|
||||
*/
|
||||
private Printable printable;
|
||||
|
||||
/**
|
||||
* The actual print job.
|
||||
*/
|
||||
private PDFJob printJob;
|
||||
/**
|
||||
* The actual print job.
|
||||
*/
|
||||
private PDFJob printJob;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of <code>PDFPrinterJob</code>.
|
||||
*/
|
||||
public PDFPrinterJob() {
|
||||
attributes = new HashPrintRequestAttributeSet();
|
||||
info = new PDFInfo();
|
||||
pageFormat = new PageFormat(); // default page format.
|
||||
setJobName("Java Printing");
|
||||
}
|
||||
/**
|
||||
* Initializes a new instance of <code>PDFPrinterJob</code>.
|
||||
*/
|
||||
public PDFPrinterJob() {
|
||||
attributes = new HashPrintRequestAttributeSet();
|
||||
info = new PDFInfo();
|
||||
pageFormat = new PageFormat(); // default page format.
|
||||
setJobName("Java Printing");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
// Cancel is not an option
|
||||
}
|
||||
@Override
|
||||
public void cancel() {
|
||||
// Cancel is not an option
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageFormat defaultPage(PageFormat page) {
|
||||
return validatePage(page);
|
||||
}
|
||||
@Override
|
||||
public PageFormat defaultPage(PageFormat page) {
|
||||
return validatePage(page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCopies() {
|
||||
return ((IntegerSyntax) attributes.get(Copies.class)).getValue();
|
||||
}
|
||||
@Override
|
||||
public int getCopies() {
|
||||
return ((IntegerSyntax) attributes.get(Copies.class)).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJobName() {
|
||||
return ((TextSyntax) attributes.get(JobName.class)).getValue();
|
||||
}
|
||||
@Override
|
||||
public String getJobName() {
|
||||
return ((TextSyntax) attributes.get(JobName.class)).getValue();
|
||||
}
|
||||
|
||||
public static PrinterJob getPrinterJob() {
|
||||
return new PDFPrinterJob();
|
||||
}
|
||||
public static PrinterJob getPrinterJob() {
|
||||
return new PDFPrinterJob();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserName() {
|
||||
return ((TextSyntax) attributes.get(RequestingUserName.class))
|
||||
.getValue();
|
||||
}
|
||||
@Override
|
||||
public String getUserName() {
|
||||
return ((TextSyntax) attributes.get(RequestingUserName.class))
|
||||
.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageFormat pageDialog(PageFormat page) throws HeadlessException {
|
||||
// No page dialog is supported.
|
||||
return (PageFormat) page.clone();
|
||||
}
|
||||
@Override
|
||||
public PageFormat pageDialog(PageFormat page) throws HeadlessException {
|
||||
// No page dialog is supported.
|
||||
return (PageFormat) page.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a set of pages.
|
||||
*
|
||||
* @param pathname
|
||||
* the full path for the output PDF file.
|
||||
* @exception PrinterException
|
||||
* an error in the print system caused the job to be aborted.
|
||||
* @see Book
|
||||
* @see Pageable
|
||||
* @see Printable
|
||||
*/
|
||||
public void print(String pathname) throws PrinterException {
|
||||
int pageCount;
|
||||
File file = null;
|
||||
FileOutputStream fileOutputStream = null;
|
||||
/**
|
||||
* Prints a set of pages.
|
||||
*
|
||||
* @param pathname the full path for the output PDF file.
|
||||
* @exception PrinterException an error in the print system caused the job
|
||||
* to be aborted.
|
||||
* @see Book
|
||||
* @see Pageable
|
||||
* @see Printable
|
||||
*/
|
||||
public void print(String pathname) throws PrinterException {
|
||||
int pageCount;
|
||||
File file = null;
|
||||
FileOutputStream fileOutputStream = null;
|
||||
|
||||
try {
|
||||
file = new File(pathname);
|
||||
fileOutputStream = new FileOutputStream(file);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error!! - Invalid output file path: "
|
||||
+ pathname);
|
||||
}
|
||||
try {
|
||||
file = new File(pathname);
|
||||
fileOutputStream = new FileOutputStream(file);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error!! - Invalid output file path: "
|
||||
+ pathname);
|
||||
}
|
||||
|
||||
PDFGraphics pdfGraphics = null;
|
||||
printJob = new PDFJob(fileOutputStream);
|
||||
PDFGraphics pdfGraphics = null;
|
||||
printJob = new PDFJob(fileOutputStream);
|
||||
|
||||
if (info != null) {
|
||||
printJob.getPDFDocument().setPDFInfo(info);
|
||||
}
|
||||
if (info != null) {
|
||||
printJob.getPDFDocument().setPDFInfo(info);
|
||||
}
|
||||
|
||||
pageCount = pageable.getNumberOfPages();
|
||||
for (int pageIndex = 0; pageIndex < pageCount; pageIndex++) {
|
||||
pageFormat = pageable.getPageFormat(pageIndex);
|
||||
pageCount = pageable.getNumberOfPages();
|
||||
for (int pageIndex = 0; pageIndex < pageCount; pageIndex++) {
|
||||
pageFormat = pageable.getPageFormat(pageIndex);
|
||||
|
||||
pdfGraphics = (PDFGraphics) printJob.getGraphics(pageFormat);
|
||||
printable = pageable.getPrintable(pageIndex);
|
||||
printable.print(pdfGraphics, pageFormat, pageIndex);
|
||||
pdfGraphics.dispose();
|
||||
}
|
||||
pdfGraphics = (PDFGraphics) printJob.getGraphics(pageFormat);
|
||||
printable = pageable.getPrintable(pageIndex);
|
||||
printable.print(pdfGraphics, pageFormat, pageIndex);
|
||||
pdfGraphics.dispose();
|
||||
}
|
||||
|
||||
printJob.end();
|
||||
printJob.end();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print() throws PrinterException {
|
||||
File file;
|
||||
File path;
|
||||
String jobName = getJobName();
|
||||
@Override
|
||||
public void print() throws PrinterException {
|
||||
File file;
|
||||
File path;
|
||||
String jobName = getJobName();
|
||||
|
||||
if (fileChooser == null) {
|
||||
fileChooser = new JFileChooser();
|
||||
fileChooser.setMultiSelectionEnabled(false);
|
||||
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
}
|
||||
if (fileChooser == null) {
|
||||
fileChooser = new JFileChooser();
|
||||
fileChooser.setMultiSelectionEnabled(false);
|
||||
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
}
|
||||
|
||||
// Make sure job name is not blank
|
||||
if (jobName.equals("")) {
|
||||
jobName = "Java Printing";
|
||||
}
|
||||
// Eliminate invalid characters from job name.
|
||||
jobName = jobName.replaceAll("\\\\", "-");
|
||||
jobName = jobName.replaceAll("/", "-");
|
||||
// Make sure job name is not blank
|
||||
if (jobName.equals("")) {
|
||||
jobName = "Java Printing";
|
||||
}
|
||||
// Eliminate invalid characters from job name.
|
||||
jobName = jobName.replaceAll("\\\\", "-");
|
||||
jobName = jobName.replaceAll("/", "-");
|
||||
|
||||
path = fileChooser.getCurrentDirectory();
|
||||
file = new File(path, jobName + ".pdf");
|
||||
path = fileChooser.getCurrentDirectory();
|
||||
file = new File(path, jobName + ".pdf");
|
||||
|
||||
// Dialog to get file name...
|
||||
fileChooser.setSelectedFile(file);
|
||||
// Dialog to get file name...
|
||||
fileChooser.setSelectedFile(file);
|
||||
|
||||
// Print
|
||||
if (fileChooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
|
||||
file = fileChooser.getSelectedFile();
|
||||
print(file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
// Print
|
||||
if (fileChooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
|
||||
file = fileChooser.getSelectedFile();
|
||||
print(file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean printDialog() throws HeadlessException {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean printDialog() throws HeadlessException {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the author for this document.
|
||||
*
|
||||
* @param author the author's name.
|
||||
*/
|
||||
public void setAuthor(String author) {
|
||||
info.setAuthor(author);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCopies(int copies) {
|
||||
// Will be ignored, but add attribute anyway
|
||||
attributes.add(new Copies(copies));
|
||||
}
|
||||
/**
|
||||
* Sets the author for this document.
|
||||
*
|
||||
* @param author the author's name.
|
||||
*/
|
||||
public void setAuthor(String author) {
|
||||
info.setAuthor(author);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the creator for this document.
|
||||
*
|
||||
* @param creator the application name.
|
||||
*/
|
||||
public void setCreator(String creator) {
|
||||
info.setCreator(creator);
|
||||
}
|
||||
@Override
|
||||
public void setCopies(int copies) {
|
||||
// Will be ignored, but add attribute anyway
|
||||
attributes.add(new Copies(copies));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setJobName(String jobName) {
|
||||
attributes.add(new JobName(jobName, Locale.getDefault()));
|
||||
/**
|
||||
* Sets the creator for this document.
|
||||
*
|
||||
* @param creator the application name.
|
||||
*/
|
||||
public void setCreator(String creator) {
|
||||
info.setCreator(creator);
|
||||
}
|
||||
|
||||
if (info.getTitle() == null) {
|
||||
info.setTitle(jobName);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void setJobName(String jobName) {
|
||||
attributes.add(new JobName(jobName, Locale.getDefault()));
|
||||
|
||||
@Override
|
||||
public void setPageable(Pageable document) throws NullPointerException {
|
||||
if (document == null) {
|
||||
throw new NullPointerException("Pageable cannot be null.");
|
||||
}
|
||||
this.pageable = document;
|
||||
}
|
||||
if (info.getTitle() == null) {
|
||||
info.setTitle(jobName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrintable(Printable painter) {
|
||||
this.printable = painter;
|
||||
}
|
||||
@Override
|
||||
public void setPageable(Pageable document) throws NullPointerException {
|
||||
if (document == null) {
|
||||
throw new NullPointerException("Pageable cannot be null.");
|
||||
}
|
||||
this.pageable = document;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrintable(Printable painter, PageFormat format) {
|
||||
this.printable = painter;
|
||||
this.pageFormat = format;
|
||||
}
|
||||
@Override
|
||||
public void setPrintable(Printable painter) {
|
||||
this.printable = painter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title for this document.
|
||||
*
|
||||
* @param title the document title.
|
||||
*/
|
||||
public void setTitle(String title) {
|
||||
info.setTitle(title);
|
||||
}
|
||||
@Override
|
||||
public void setPrintable(Printable painter, PageFormat format) {
|
||||
this.printable = painter;
|
||||
this.pageFormat = format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageFormat validatePage(PageFormat page) {
|
||||
return (PageFormat) page.clone();
|
||||
}
|
||||
/**
|
||||
* Sets the title for this document.
|
||||
*
|
||||
* @param title the document title.
|
||||
*/
|
||||
public void setTitle(String title) {
|
||||
info.setTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageFormat validatePage(PageFormat page) {
|
||||
return (PageFormat) page.clone();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,105 +27,111 @@ import java.io.Serializable;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
|
||||
/**
|
||||
* This class implements a PDF stream object. In PDF, streams contain data
|
||||
* like the graphic operators that render a page, or the pixels of an image.
|
||||
* This class implements a PDF stream object. In PDF, streams contain data like
|
||||
* the graphic operators that render a page, or the pixels of an image.
|
||||
*
|
||||
* <p>In PDF, a stream can be compressed using several different methods, or
|
||||
* left uncompressed. Here we support both uncompressed, and FlateDecode as
|
||||
* it's supported by the java core.
|
||||
* <p>
|
||||
* In PDF, a stream can be compressed using several different methods, or left
|
||||
* uncompressed. Here we support both uncompressed, and FlateDecode as it's
|
||||
* supported by the java core.
|
||||
*
|
||||
* @author Peter T Mount http://www.retep.org.uk/pdf/
|
||||
* @author Eric Z. Beard, ericzbeard@hotmail.com
|
||||
* @version $Revision: 1.2 $, $Date: 2007/08/26 18:56:35 $
|
||||
*
|
||||
*/
|
||||
public class PDFStream extends PDFObject implements Serializable
|
||||
{
|
||||
public class PDFStream extends PDFObject implements Serializable {
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* NOTE: The original class is the work of Peter T. Mount, who released it
|
||||
* in the uk.org.retep.pdf package. It was modified by Eric Z. Beard as
|
||||
* follows:
|
||||
* The package name was changed to gnu.jpdf.
|
||||
* The formatting was changed a little bit.
|
||||
* It is still licensed under the LGPL.
|
||||
*/
|
||||
|
||||
*/
|
||||
/**
|
||||
* This holds the stream's content.
|
||||
*/
|
||||
transient ByteArrayOutputStream buf;
|
||||
|
||||
|
||||
/**
|
||||
* True if we will compress the stream in the pdf file
|
||||
*/
|
||||
boolean deflate;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a plain stream.
|
||||
* <p>By default, the stream will be compressed.
|
||||
* <p>
|
||||
* By default, the stream will be compressed.
|
||||
*/
|
||||
public PDFStream() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a stream. The supplied type is stored in the stream's header
|
||||
* and is used by other objects that extend the PDFStream class (like
|
||||
* PDFImage).
|
||||
* <p>By default, the stream will be compressed.
|
||||
* <p>
|
||||
* By default, the stream will be compressed.
|
||||
*
|
||||
* @param type type for the stream
|
||||
* @see PDFImage
|
||||
*/
|
||||
public PDFStream(String type) {
|
||||
super(type);
|
||||
buf = new ByteArrayOutputStream();
|
||||
|
||||
|
||||
// default deflate mode
|
||||
deflate = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mode true will FlatDecode the stream
|
||||
*/
|
||||
public void setDeflate(boolean mode) {
|
||||
// TODO: Restore the next line of code to allow deflate to occur.
|
||||
// TODO: Restore the next line of code to allow deflate to occur.
|
||||
deflate = mode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returs true if the stream will be compressed.
|
||||
*
|
||||
* @return true if compression is enabled
|
||||
*/
|
||||
public boolean getDeflate() {
|
||||
return deflate;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the OutputStream that will append to this stream.
|
||||
*
|
||||
* @return The stream for this object
|
||||
*/
|
||||
public OutputStream getOutputStream() {
|
||||
return (OutputStream)buf;
|
||||
return (OutputStream) buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a PrintWriter that will append to this stream.
|
||||
*
|
||||
* @return a PrintWriter to write to the stream
|
||||
*/
|
||||
public PrintWriter getWriter() {
|
||||
return new PrintWriter(buf,true);
|
||||
return new PrintWriter(buf, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is for extenders, and provides access to the stream.
|
||||
*
|
||||
* @return ByteArrayOutputStream containing the contents.
|
||||
*/
|
||||
public ByteArrayOutputStream getStream() {
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
@@ -136,31 +142,32 @@ public class PDFStream extends PDFObject implements Serializable
|
||||
// Unlike most PDF objects, we dont call writeEnd(os) because we
|
||||
// contain a stream
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This inserts the Streams length, then the actual stream, finally
|
||||
* the end of stream/object markers.
|
||||
* This inserts the Streams length, then the actual stream, finally the end
|
||||
* of stream/object markers.
|
||||
*
|
||||
* <p>This is intended for anyone extending PDFStream, as objects
|
||||
* containing streams do no use writeEnd(), and they must be able
|
||||
* to write the actual stream.
|
||||
* <p>
|
||||
* This is intended for anyone extending PDFStream, as objects containing
|
||||
* streams do no use writeEnd(), and they must be able to write the actual
|
||||
* stream.
|
||||
*
|
||||
* @param os OutputStream to send the object to
|
||||
* @exception IOException on error
|
||||
*/
|
||||
public void writeStream(OutputStream os) throws IOException {
|
||||
if(deflate) {
|
||||
if (deflate) {
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
DeflaterOutputStream dos = new DeflaterOutputStream(b);
|
||||
//,new Deflater(Deflater.BEST_COMPRESSION,true));
|
||||
buf.writeTo(dos);
|
||||
dos.finish();
|
||||
dos.close();
|
||||
|
||||
|
||||
// FlatDecode is compatible with the java.util.zip.Deflater class
|
||||
os.write("/Filter /FlateDecode\n".getBytes());
|
||||
os.write("/Length ".getBytes());
|
||||
os.write(Integer.toString(b.size()+1).getBytes());
|
||||
os.write(Integer.toString(b.size() + 1).getBytes());
|
||||
os.write("\n>>\nstream\n".getBytes());
|
||||
b.writeTo(os);
|
||||
os.write("\n".getBytes());
|
||||
@@ -171,48 +178,44 @@ public class PDFStream extends PDFObject implements Serializable
|
||||
os.write("\n>>\nstream\n".getBytes());
|
||||
buf.writeTo(os);
|
||||
}
|
||||
|
||||
|
||||
os.write("endstream\nendobj\n".getBytes());
|
||||
|
||||
|
||||
// Unlike most PDF objects, we dont call writeEnd(os) because we
|
||||
// contain a stream
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Why is this here? Did it have a specific purpose?
|
||||
|
||||
|
||||
// Why is this here? Did it have a specific purpose?
|
||||
/**
|
||||
* This implements our own special Serialization for this object.
|
||||
*
|
||||
* <p>Here we write the length of the stream's contents, then a byte
|
||||
* array of the contents. We have to do this, as ByteArrayOutputStream
|
||||
* is not serializable (hence the transient tag).
|
||||
* <p>
|
||||
* Here we write the length of the stream's contents, then a byte array of
|
||||
* the contents. We have to do this, as ByteArrayOutputStream is not
|
||||
* serializable (hence the transient tag).
|
||||
*
|
||||
*/
|
||||
private void writeObject(java.io.ObjectOutputStream out) throws IOException
|
||||
{
|
||||
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
|
||||
out.writeInt(buf.size());
|
||||
out.write(buf.toByteArray());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This implements our own special Serialization for this object
|
||||
*
|
||||
* <p>Here we read the length of the stream's contents, then a byte
|
||||
* array of the contents. Then we recreate a new ByteArrayOutputStream.
|
||||
* We have to do this, as ByteArrayOutputStream is not serializable
|
||||
* (hence the transient tag).
|
||||
* <p>
|
||||
* Here we read the length of the stream's contents, then a byte array of
|
||||
* the contents. Then we recreate a new ByteArrayOutputStream. We have to do
|
||||
* this, as ByteArrayOutputStream is not serializable (hence the transient
|
||||
* tag).
|
||||
*
|
||||
*/
|
||||
private void readObject(java.io.ObjectInputStream in) throws IOException
|
||||
{
|
||||
private void readObject(java.io.ObjectInputStream in) throws IOException {
|
||||
int l = in.readInt();
|
||||
byte b[] = new byte[l];
|
||||
in.read(b,0,l);
|
||||
buf=new ByteArrayOutputStream(l);
|
||||
in.read(b, 0, l);
|
||||
buf = new ByteArrayOutputStream(l);
|
||||
buf.write(b);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
package gnu.jpdf;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
@@ -37,22 +36,25 @@ import java.util.logging.Logger;
|
||||
* @version $Revision: 1.2 $, $Date: 2007/08/26 18:56:35 $
|
||||
*
|
||||
*/
|
||||
public class PDFStringHelper
|
||||
{
|
||||
/**
|
||||
* This converts a string into PDF. It prefixes ( or ) with \
|
||||
* and wraps the string in a ( ) pair.
|
||||
* @param s String to convert
|
||||
* @return String that can be placed in a PDF (or Postscript) stream
|
||||
*/
|
||||
public static String makePDFString(String s) {
|
||||
if(s.indexOf("(")>-1)
|
||||
s = replace(s,"(","\\(");
|
||||
|
||||
if(s.indexOf(")")>-1)
|
||||
s = replace(s,")","\\)");
|
||||
|
||||
return "("+s+")";
|
||||
public class PDFStringHelper {
|
||||
|
||||
/**
|
||||
* This converts a string into PDF. It prefixes ( or ) with \ and wraps the
|
||||
* string in a ( ) pair.
|
||||
*
|
||||
* @param s String to convert
|
||||
* @return String that can be placed in a PDF (or Postscript) stream
|
||||
*/
|
||||
public static String makePDFString(String s) {
|
||||
if (s.indexOf("(") > -1) {
|
||||
s = replace(s, "(", "\\(");
|
||||
}
|
||||
|
||||
if (s.indexOf(")") > -1) {
|
||||
s = replace(s, ")", "\\)");
|
||||
}
|
||||
|
||||
return "(" + s + ")";
|
||||
}
|
||||
|
||||
public static byte[] makeRawPDFString(String s) {
|
||||
@@ -84,32 +86,34 @@ public class PDFStringHelper
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for toString()
|
||||
* @param s source string
|
||||
* @param f string to remove
|
||||
* @param t string to replace f
|
||||
* @return string with f replaced by t
|
||||
*/
|
||||
private static String replace(String source,
|
||||
String removeThis,
|
||||
String replaceWith) {
|
||||
StringBuffer b = new StringBuffer();
|
||||
int p = 0, c=0;
|
||||
|
||||
while(c>-1) {
|
||||
if((c = source.indexOf(removeThis,p)) > -1) {
|
||||
b.append(source.substring(p,c));
|
||||
b.append(replaceWith);
|
||||
p=c+1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for toString()
|
||||
*
|
||||
* @param s source string
|
||||
* @param f string to remove
|
||||
* @param t string to replace f
|
||||
* @return string with f replaced by t
|
||||
*/
|
||||
private static String replace(String source,
|
||||
String removeThis,
|
||||
String replaceWith) {
|
||||
StringBuffer b = new StringBuffer();
|
||||
int p = 0, c = 0;
|
||||
|
||||
while (c > -1) {
|
||||
if ((c = source.indexOf(removeThis, p)) > -1) {
|
||||
b.append(source.substring(p, c));
|
||||
b.append(replaceWith);
|
||||
p = c + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// include any remaining text
|
||||
if (p < source.length()) {
|
||||
b.append(source.substring(p));
|
||||
}
|
||||
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
// include any remaining text
|
||||
if(p<source.length())
|
||||
b.append(source.substring(p));
|
||||
|
||||
return b.toString();
|
||||
}
|
||||
} // end class PDFStringHelper
|
||||
|
||||
@@ -24,81 +24,80 @@
|
||||
package gnu.jpdf;
|
||||
|
||||
/**
|
||||
* <p>This class is used to hold the xref information in the PDF
|
||||
* Trailer block.</p>
|
||||
* <p>
|
||||
* This class is used to hold the xref information in the PDF Trailer block.</p>
|
||||
*
|
||||
* <p>Basically, each object has an id, and an offset in the end file.</p>
|
||||
* <p>
|
||||
* Basically, each object has an id, and an offset in the end file.</p>
|
||||
*
|
||||
* <p>See the Adobe PDF Manual for more information. This class will
|
||||
* normally not be used directly by a developer</p>
|
||||
* <p>
|
||||
* See the Adobe PDF Manual for more information. This class will normally not
|
||||
* be used directly by a developer</p>
|
||||
*
|
||||
* @author Peter T. Mount
|
||||
* @author Eric Z. Beard, ericzbeard@hotmail.com
|
||||
* @version $Revision: 1.2 $, $Date: 2007/08/26 18:56:35 $
|
||||
*
|
||||
*/
|
||||
public class PDFXref
|
||||
{
|
||||
public class PDFXref {
|
||||
|
||||
/*
|
||||
/*
|
||||
* NOTE: Originally an inner class in PDF.java (now PDFDocument) written
|
||||
* by Peter Mount for uk.org.retep.pdf
|
||||
*/
|
||||
*/
|
||||
/**
|
||||
* The id of a PDF Object
|
||||
*/
|
||||
public int id;
|
||||
|
||||
/**
|
||||
* The id of a PDF Object
|
||||
*/
|
||||
public int id;
|
||||
/**
|
||||
* The offset within the PDF file
|
||||
*/
|
||||
public int offset;
|
||||
|
||||
/**
|
||||
* The offset within the PDF file
|
||||
*/
|
||||
public int offset;
|
||||
|
||||
/**
|
||||
* The generation of the object, usually 0
|
||||
*/
|
||||
public int generation;
|
||||
|
||||
/**
|
||||
* Creates a crossreference for a PDF Object
|
||||
* @param id The object's ID
|
||||
* @param offset The object's position in the file
|
||||
*/
|
||||
public PDFXref(int id,int offset)
|
||||
{
|
||||
this(id,offset,0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a crossreference for a PDF Object
|
||||
*
|
||||
* @param id The object's ID
|
||||
* @param offset The object's position in the file
|
||||
* @param generation The object's generation, usually 0
|
||||
*/
|
||||
public PDFXref(int id,int offset,int generation)
|
||||
{
|
||||
this.id = id;
|
||||
this.offset = offset;
|
||||
this.generation = generation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The xref in the format of the xref section in the PDF file
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
String of = Integer.toString(offset);
|
||||
String ge = Integer.toString(generation);
|
||||
String rs = "0000000000".substring(0, 10-of.length()) +
|
||||
of +
|
||||
" " +
|
||||
"00000".substring(0,5-ge.length())+ge;
|
||||
if(generation==65535)
|
||||
return rs+" f ";
|
||||
return rs+" n ";
|
||||
}
|
||||
/**
|
||||
* The generation of the object, usually 0
|
||||
*/
|
||||
public int generation;
|
||||
|
||||
/**
|
||||
* Creates a crossreference for a PDF Object
|
||||
*
|
||||
* @param id The object's ID
|
||||
* @param offset The object's position in the file
|
||||
*/
|
||||
public PDFXref(int id, int offset) {
|
||||
this(id, offset, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a crossreference for a PDF Object
|
||||
*
|
||||
* @param id The object's ID
|
||||
* @param offset The object's position in the file
|
||||
* @param generation The object's generation, usually 0
|
||||
*/
|
||||
public PDFXref(int id, int offset, int generation) {
|
||||
this.id = id;
|
||||
this.offset = offset;
|
||||
this.generation = generation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The xref in the format of the xref section in the PDF file
|
||||
*/
|
||||
public String toString() {
|
||||
String of = Integer.toString(offset);
|
||||
String ge = Integer.toString(generation);
|
||||
String rs = "0000000000".substring(0, 10 - of.length())
|
||||
+ of
|
||||
+ " "
|
||||
+ "00000".substring(0, 5 - ge.length()) + ge;
|
||||
if (generation == 65535) {
|
||||
return rs + " f ";
|
||||
}
|
||||
return rs + " n ";
|
||||
}
|
||||
|
||||
} // end class PDFXref
|
||||
|
||||
|
||||
|
||||
@@ -20,34 +20,35 @@
|
||||
*/
|
||||
package gnu.jpdf;
|
||||
|
||||
|
||||
/**
|
||||
* <p>This exception is thrown from {@link gnu.jpdf.BoundingBox} if the
|
||||
* string won't fit into the box</p>
|
||||
* <p>
|
||||
* This exception is thrown from {@link gnu.jpdf.BoundingBox} if the string
|
||||
* won't fit into the box</p>
|
||||
*
|
||||
* @author Eric Z. Beard, erizbeard@hotmail.com
|
||||
* @version $Revision: 1.1 $ $Date: 2007/08/22 01:02:32 $
|
||||
*/
|
||||
public class StringTooLongException extends Exception {
|
||||
private String msg;
|
||||
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* <p>Normally this exception is constructed with a message containing
|
||||
* information about the sizes of the parent and child box, and maybe the
|
||||
* string that caused the overflow.</p>
|
||||
*
|
||||
* @param msg a <code>String</code>, some informative message for the logs
|
||||
*/
|
||||
public StringTooLongException(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* Normally this exception is constructed with a message containing
|
||||
* information about the sizes of the parent and child box, and maybe the
|
||||
* string that caused the overflow.</p>
|
||||
*
|
||||
* @param msg a <code>String</code>, some informative message for the logs
|
||||
*/
|
||||
public StringTooLongException(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return msg;
|
||||
}
|
||||
public String toString() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return msg;
|
||||
}
|
||||
public String getMessage() {
|
||||
return msg;
|
||||
}
|
||||
} // end class StringTooLongException
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package gnu.jpdf;
|
||||
|
||||
|
||||
import gnu.jpdf.PDFJob;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.image.BufferedImage;
|
||||
@@ -10,31 +9,30 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class Test {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
PDFJob job=new PDFJob(new FileOutputStream("test.pdf"));
|
||||
PageFormat pf=new PageFormat();
|
||||
PDFJob job = new PDFJob(new FileOutputStream("test.pdf"));
|
||||
PageFormat pf = new PageFormat();
|
||||
pf.setOrientation(PageFormat.PORTRAIT);
|
||||
Paper p = new Paper();
|
||||
p.setSize(210,297); //A4
|
||||
p.setSize(210, 297); //A4
|
||||
pf.setPaper(p);
|
||||
|
||||
|
||||
BufferedImage img = ImageIO.read(new File("earth.jpg"));
|
||||
|
||||
|
||||
int w = 200;
|
||||
|
||||
for(int i=0;i<10;i++){
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Graphics g = job.getGraphics();
|
||||
g.drawImage(img, 0, 0,w,w, null);
|
||||
g.drawImage(img, 0, 0, w, w, null);
|
||||
g.dispose();
|
||||
}
|
||||
|
||||
|
||||
job.end();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,6 @@ public class TtfParser {
|
||||
|
||||
private byte[] cidtogidmap = new byte[131072];
|
||||
|
||||
|
||||
public void loadFromTTF(File file) throws IOException, FontFormatException {
|
||||
RandomAccessFile input = new RandomAccessFile(file, "r");
|
||||
readTableDirectory(input);
|
||||
@@ -171,7 +170,6 @@ public class TtfParser {
|
||||
return dw;
|
||||
}
|
||||
|
||||
|
||||
private void readTableDirectory(RandomAccessFile input) throws IOException {
|
||||
skip(input, 4);
|
||||
int tableCount = readUnsignedShort(input);
|
||||
|
||||
Reference in New Issue
Block a user