diff --git a/libsrc/gnujpdf/src/gnu/jpdf/BoundingBox.java b/libsrc/gnujpdf/src/gnu/jpdf/BoundingBox.java index d1eed5f6b..ea0af2802 100644 --- a/libsrc/gnujpdf/src/gnu/jpdf/BoundingBox.java +++ b/libsrc/gnujpdf/src/gnu/jpdf/BoundingBox.java @@ -26,1000 +26,980 @@ import java.awt.*; import java.util.*; /** - *
This class simplifies the placement of Strings within - * a canvas area where the placement of objects is absolute
+ *+ * This class simplifies the placement of Strings within a canvas area where the + * placement of objects is absolute
* - *A BoundingBox is just a Rectangle that knows how to
- * find the coordinates for a String based on the desired alignment and
- * FontMetrics. For each new String, a new child
- * BoundingBox is made that can be subtracted from the
- * original box so new Strings can be added
+ * A BoundingBox is just a Rectangle that knows how to find the
+ * coordinates for a String based on the desired alignment and
+ * FontMetrics. For each new String, a new child
+ * BoundingBox is made that can be subtracted from the original box
+ * so new Strings can be added
One of the more helpful features of this class is the string wrap
- * feature of getStringBounds. The box returned by that method
- * will contain an array of strings that have been broken down to fit the
- * box. The box's coordinates and size will reflect the size of the
- * entire group of strings if it is laid out as expected. Using the
- * returned box and iterating through the array of strings from top to
- * bottom, getting new bounding boxes for each one (with upper left
- * alignment and no padding) will result in the correct string wrap.
+ * One of the more helpful features of this class is the string wrap feature of
+ * getStringBounds. The box returned by that method will contain an
+ * array of strings that have been broken down to fit the box. The box's
+ * coordinates and size will reflect the size of the entire group of strings if
+ * it is laid out as expected. Using the returned box and iterating through the
+ * array of strings from top to bottom, getting new bounding boxes for each one
+ * (with upper left alignment and no padding) will result in the correct string
+ * wrap.
Note that you will need to have Xvfb running on a Unix server to - * use this class
+ *+ * Note that you will need to have Xvfb running on a Unix server to use this + * class
* * @author Eric Z. Beard, ericzbeard@hotmail.com * @version $Revision: 1.2 $, $Date: 2007/08/26 18:56:35 $ */ -public class BoundingBox extends Rectangle -{ - /** Percent f line height to space lines */ - public static final int LINE_SPACING_PERCENTAGE = 20; +public class BoundingBox extends Rectangle { - /** Used to a align a String centered vertically */ - public static final int VERT_ALIGN_CENTER = 0; + /** + * Percent f line height to space lines + */ + public static final int LINE_SPACING_PERCENTAGE = 20; - /** Used to align a String at the top of the box */ - public static final int VERT_ALIGN_TOP = 1; + /** + * Used to a align a String centered vertically + */ + public static final int VERT_ALIGN_CENTER = 0; - /** Used to align a String at the bottom of the box */ - public static final int VERT_ALIGN_BOTTOM = 2; + /** + * Used to align a String at the top of the box + */ + public static final int VERT_ALIGN_TOP = 1; - /** Used to align a String horizontally in the center of the box */ - public static final int HORIZ_ALIGN_CENTER = 3; + /** + * Used to align a String at the bottom of the box + */ + public static final int VERT_ALIGN_BOTTOM = 2; - /** Used to align a String to the left in the box */ - public static final int HORIZ_ALIGN_LEFT = 4; + /** + * Used to align a String horizontally in the center of the box + */ + public static final int HORIZ_ALIGN_CENTER = 3; - /** Used to aling a String to the right in a box */ - public static final int HORIZ_ALIGN_RIGHT = 5; + /** + * Used to align a String to the left in the box + */ + public static final int HORIZ_ALIGN_LEFT = 4; - /** Used to subtract a child from a box, *leaving* the top portion */ - public static final int SUBTRACT_FROM_TOP = 6; + /** + * Used to aling a String to the right in a box + */ + public static final int HORIZ_ALIGN_RIGHT = 5; - /** Used to subtract a child from a box, *leaving* the bottom portion */ - public static final int SUBTRACT_FROM_BOTTOM = 7; + /** + * Used to subtract a child from a box, *leaving* the top portion + */ + public static final int SUBTRACT_FROM_TOP = 6; - /** Used to subtract a child from a box, *leaving* the left portion */ - public static final int SUBTRACT_FROM_LEFT = 8; + /** + * Used to subtract a child from a box, *leaving* the bottom portion + */ + public static final int SUBTRACT_FROM_BOTTOM = 7; - /** Used to subtract a child from a box, *leaving" the right portion */ - public static final int SUBTRACT_FROM_RIGHT = 9; + /** + * Used to subtract a child from a box, *leaving* the left portion + */ + public static final int SUBTRACT_FROM_LEFT = 8; - private static final int[] VERT_ALIGNS = {VERT_ALIGN_CENTER, - VERT_ALIGN_TOP, - VERT_ALIGN_BOTTOM}; + /** + * Used to subtract a child from a box, *leaving" the right portion + */ + public static final int SUBTRACT_FROM_RIGHT = 9; - private static final int[] HORIZ_ALIGNS = {HORIZ_ALIGN_CENTER, - HORIZ_ALIGN_LEFT, - HORIZ_ALIGN_RIGHT}; + private static final int[] VERT_ALIGNS = {VERT_ALIGN_CENTER, + VERT_ALIGN_TOP, + VERT_ALIGN_BOTTOM}; - private static final int[] SUBTRACTS = {SUBTRACT_FROM_TOP, - SUBTRACT_FROM_BOTTOM, - SUBTRACT_FROM_LEFT, - SUBTRACT_FROM_RIGHT}; + private static final int[] HORIZ_ALIGNS = {HORIZ_ALIGN_CENTER, + HORIZ_ALIGN_LEFT, + HORIZ_ALIGN_RIGHT}; - /** The point to use for Graphics.drawString() */ - private Point drawingPoint; + private static final int[] SUBTRACTS = {SUBTRACT_FROM_TOP, + SUBTRACT_FROM_BOTTOM, + SUBTRACT_FROM_LEFT, + SUBTRACT_FROM_RIGHT}; - /** The absolute, world location of the box */ - private Point absoluteLocation; + /** + * The point to use for Graphics.drawString() + */ + private Point drawingPoint; - /** Link to parent box */ - private BoundingBox parent; - - /** - * If this box was the result of a getStringBounds call, this - * array will hold the broken strings - */ - private String[] stringArray; + /** + * The absolute, world location of the box + */ + private Point absoluteLocation; - /** The string specified in getStringBounds */ - private String fullString; - - /** - * Creates a newBoundingBox instance.
- *
- * @param p a Point, upper left coords
- * @param d a Dimension, used to determine height and width
- */
- public BoundingBox(Point p, Dimension d) {
- super(p, d);
- this.drawingPoint = this.getLocation();
- this.absoluteLocation = this.getLocation();
- }
+ /**
+ * Link to parent box
+ */
+ private BoundingBox parent;
-
+ /**
+ * If this box was the result of a getStringBounds call, this array will
+ * hold the broken strings
+ */
+ private String[] stringArray;
- /**
- * Returns true if this box has a parent. The 'world', or - * enclosing canvas is not considered a parent
- * - * @return aboolean value
- */
- public boolean hasParent() {
- return parent != null;
- }
+ /**
+ * The string specified in getStringBounds
+ */
+ private String fullString;
- /**
- * Get this box's parent box
- * - * @return aBoundingBox value
- */
- public BoundingBox getParent() {
- return parent;
- }
-
-
-
- /**
- * Make the specified box this box's child. Equivalent to
- * child.setParent(parent) where the specified 'parent' is
- * this instance
BoundingBox, any box that can fit inside
- * this one. The results of calling
- * getAbsoluteLocation() on the child will be
- * altered after this to take into account the child's
- * new location in the 'world'
- *
- */
- public void add(BoundingBox child) {
- child.setParent(this);
- }
-
-
-
- /**
- * Make the specified box this box's parent
- * - * @param parent aBoundingBox value
- */
- public void setParent(BoundingBox parent) {
- // Prevent infinite recursion
- if (this == parent) {
- return;
+ /**
+ * Creates a new BoundingBox instance.
+ *
+ * @param p a Point, upper left coords
+ * @param d a Dimension, used to determine height and width
+ */
+ public BoundingBox(Point p, Dimension d) {
+ super(p, d);
+ this.drawingPoint = this.getLocation();
+ this.absoluteLocation = this.getLocation();
}
- this.parent = parent;
- // If this box was created empty, without a String inside,
- // determine its absolute location
- if (this.getLocation().equals(this.getAbsoluteLocation())) {
- int ancestorTranslateX = 0;
- int ancestorTranslateY = 0;
+ /**
+ * + * Returns true if this box has a parent. The 'world', or enclosing canvas + * is not considered a parent
+ * + * @return aboolean value
+ */
+ public boolean hasParent() {
+ return parent != null;
+ }
- BoundingBox ancestor = this;
- while (ancestor.hasParent()) {
- BoundingBox oldRef = ancestor;
- ancestor = ancestor.getParent();
+ /**
+ * + * Get this box's parent box
+ * + * @return aBoundingBox value
+ */
+ public BoundingBox getParent() {
+ return parent;
+ }
+
+ /**
+ *
+ * Make the specified box this box's child. Equivalent to
+ * child.setParent(parent) where the specified 'parent' is this
+ * instance
BoundingBox, any box that can fit inside this
+ * one. The results of calling getAbsoluteLocation() on the
+ * child will be altered after this to take into account the child's new
+ * location in the 'world'
+ *
+ */
+ public void add(BoundingBox child) {
+ child.setParent(this);
+ }
+
+ /**
+ * + * Make the specified box this box's parent
+ * + * @param parent aBoundingBox value
+ */
+ public void setParent(BoundingBox parent) {
// Prevent infinite recursion
- if (ancestor == oldRef) {
- break;
+ if (this == parent) {
+ return;
}
- ancestorTranslateX += (int)ancestor.getLocation().getX();
- ancestorTranslateY += (int)ancestor.getLocation().getY();
- }
+ this.parent = parent;
- this.getAbsoluteLocation().translate(ancestorTranslateX,
- ancestorTranslateY);
- } // end if
- } // end setParent
+ // If this box was created empty, without a String inside,
+ // determine its absolute location
+ if (this.getLocation().equals(this.getAbsoluteLocation())) {
+ int ancestorTranslateX = 0;
+ int ancestorTranslateY = 0;
-
-
-
-
- /**
- * Get the wrapped strings if this box was from a call to getStringBounds, - * otherwise this method returns null
- * - * @return aString[] array of strings, top to bottom in layout
- */
- public String[] getStringArray() {
- return stringArray;
- } // end getStringArray
-
-
-
- /**
- * Set the value of the string array
- * - * @param strArray aString array
- *
- */
- public void setStringArray(String[] strArray) {
- this.stringArray = strArray;
- }
-
-
- /**
- * Set the absolute upper left world location point for this box
- * - * @param point aPoint value
- */
- public void setAbsoluteLocation(Point point) {
- this.absoluteLocation = point;
- }
-
-
-
- /**
- * Returns false if for any reason this box has negative dimensions
- * - * @return true if the box has positive height and width, false otherwise. - */ - public boolean boxExists() { - return (this.getHeight() > 0 && this.getWidth() > 0); - } // end boxExists - - - - - /** - *Get the absolute upper left location point for this box
- * - * @return aPoint value
- */
- public Point getAbsoluteLocation() {
- return absoluteLocation;
- }
-
-
- /**
- * Returns the full string associated with a call to
- * getStringBounds
Sets the full string associated with getStringBounds
String
- */
- public void setFullString(String string) {
- this.fullString = string;
- }
-
- /**
- * Gets the location of a String after it is adjusted for - * alignment within this box. The point's coordinates are - * either within this box or within the enclosing area.
- * - * @param string aString, the String to be placed
- * @param hAlign an int, HORIZ_ALIGN_CENTER,
- * HORIZ_ALIGN_LEFT, HORIX_ALIGN_RIGHT
- * @param vAlign an int, VERT_ALIGN_CENTER,
- * VERT_ALIGN_TOP, VERT_ALIGN_BOTTOM
- * @param fm a FontMetrics object for this String
- * @param padding an int, the padding around the String
- * @param enforce a boolean, if true the method will throw
- * an exception when the string is too big, if not true it will break
- * the string down and overrun the bottom of the box. If the box
- * is too small for even one word, the exception will be thrown
- * @return a Point, the coords to use in drawString()
- * @see #HORIZ_ALIGN_LEFT
- * @see #HORIZ_ALIGN_CENTER
- * @see #HORIZ_ALIGN_RIGHT
- * @see #VERT_ALIGN_TOP
- * @see #VERT_ALIGN_CENTER
- * @see #VERT_ALIGN_BOTTOM
- * @throws IllegalArgumentException if the args are invalid
- * @throws StringTooLongException if the string won't fit
- * and enforce is set to true. The exception can still be thrown
- * if enforce is false, but only in cases such as the box having
- * no height or width
- */
- public BoundingBox getStringBounds(String string,
- int hAlign,
- int vAlign,
- FontMetrics fm,
- int padding,
- boolean enforce)
- throws IllegalArgumentException, StringTooLongException {
- // Check to make sure the values passed in are valid
- if (!checkHAlign(hAlign)) {
- throw new IllegalArgumentException("BoundingBox.getStringBounds, " +
- "hAlign invalid : " + hAlign);
- }
- if (!checkVAlign(vAlign)) {
- throw new IllegalArgumentException("BoundingBox.getStringBounds, " +
- "vAlign invalid : " + hAlign);
- }
- if (fm == null) {
- throw new IllegalArgumentException("BoundingBox.getStringBounds, " +
- "FontMetrics null");
- }
- if (string == null) {
- throw new IllegalArgumentException("BoundingBox.getStringBounds, " +
- "String null");
- }
-
- // NOTE: For this portion of the method, parent refers
- // to this object and child refers to the object about
- // to be created. When the absolute point for drawing the
- // String is determined, this object's ancestors are checked.
- Dimension parentSize = this.getSize();
-
- Point childLocation;
- Dimension childSize;
-
- // String ascent, width, height, parent, child width, height
- int sa, sw, sh, pw, ph, cw, ch;
-
- // Child, parent x, y coords for upper left
- int cx, cy, px, py;
-
- sa = fm.getMaxAscent();
- sw = fm.stringWidth(string);
- sh = sa + fm.getMaxDescent();
- pw = (int)parentSize.getWidth();
- ph = (int)parentSize.getHeight();
- if (pw < 0) {
- throw new StringTooLongException("The parent box has a negative width " +
- " (" + pw + ")");
- }
- if (ph < 0) {
- throw new StringTooLongException("The parent box has a negative height"+
- " (" + ph + ")");
- }
- cw = sw + padding*2;
- ch = sh + padding*2;
- px = (int)this.getX();
- py = (int)this.getY();
-
- String[] childStrArray = null;
-
- if ((cw > pw) || (string.indexOf("\n") != -1)) {
- cw = pw - (padding * 2);
- childStrArray = createStringArray(string, fm, padding, pw);
- ch = getWrappedHeight(childStrArray, fm, padding);
- if (ch > ph) {
- // If enforce is not true, it means we want the box to
- // be returned anyway (along with the strings in the array)
- // so we can chop them manually and try again
- if (enforce) {
- throw new StringTooLongException("The wrapped strings do not " +
- "fit into the parent box, pw=" + pw +
- ", ph=" + ph + ", ch=" + ch + ", cw=" + cw +
- ", string: " + string);
- }
- }
- }
-
- // Need to have child width and height, and string array set
-
- // Child location is relative to this (parent) box, not the world
- if (vAlign == VERT_ALIGN_TOP) {
- cy = 0;
- }
- else if (vAlign == VERT_ALIGN_CENTER) {
- cy = (ph/2) - (ch/2);
- }
- else {
- cy = ph - ch;
- }
-
- if (hAlign == HORIZ_ALIGN_LEFT) {
- cx = 0;
- }
- else if (hAlign == HORIZ_ALIGN_CENTER) {
- cx = (pw/2) - (cw/2);
- }
- else {
- cx = pw - cw;
- }
-
- childLocation = new Point(cx, cy);
- childSize = new Dimension(cw, ch);
-
- // Drawing location is based on the baseline of the String, and
- // relative to the world, not this box. The drawing point differs
- // from the absolute box location because of padding and ascent
- int dpx, dpy, abx, aby;
-
- // If this object also has a parent (maybe grandparents), iterate
- // through them and find the absolute 'world' location
- int ancestorTranslateX = 0;
- int ancestorTranslateY = 0;
-
- BoundingBox ancestor = this;
- while (ancestor.hasParent()) {
- BoundingBox oldRef = ancestor;
- ancestor = ancestor.getParent();
- // Prevent infinite recursion
- if (ancestor == oldRef) {
- break;
- }
- ancestorTranslateX += (int)ancestor.getLocation().getX();
- ancestorTranslateY += (int)ancestor.getLocation().getY();
- }
-
- // Determine the absolute location for the box
- abx = px + cx + ancestorTranslateX;
- aby = py + cy + ancestorTranslateY;
-
- // Determine the absolute drawing point for the String
- dpx = abx + padding;
- dpy = aby + padding + sa;
-
- Point drawingPoint = new Point(dpx, dpy);
- BoundingBox returnChild = new BoundingBox(childLocation,
- childSize,
- drawingPoint,
- new Point(abx, aby));
- this.add(returnChild);
- returnChild.setFullString(string);
- returnChild.setStringArray(childStrArray);
- return returnChild;
-
- } // end getStringBounds
-
-
- /**
- * Gets the location of a String after it is adjusted for - * alignment within this box. The point's coordinates are - * either within this box or within the enclosing area.
- * - *By default, this method enforces string length and throws the - * exception if it is too long
- * - * @param string aString, the String to be placed
- * @param hAlign an int, HORIZ_ALIGN_CENTER,
- * HORIZ_ALIGN_LEFT, HORIX_ALIGN_RIGHT
- * @param vAlign an int, VERT_ALIGN_CENTER,
- * VERT_ALIGN_TOP, VERT_ALIGN_BOTTOM
- * @param fm a FontMetrics object for this String
- * @param padding an int, the padding around the String
- * @return a Point, the coords to use in drawString()
- * @throws IllegalArgumentException if the args are invalid
- * @throws StringTooLongException if the string won't fit
- */
- public BoundingBox getStringBounds(String string,
- int hAlign,
- int vAlign,
- FontMetrics fm,
- int padding)
- throws StringTooLongException, IllegalArgumentException {
- return getStringBounds(string, hAlign, vAlign, fm, padding, true);
- } // end getStringBounds (enforce true by default)
-
-
-
- /**
- * This method is called after getting the box by calling
- * getStringBounds on the parent. Wraps the string at
- * word boundaries and draws it to the specified Graphics
- * context. Make sure padding is the same as specified for the
- * getStringBounds call, or you may get an unexpected
- * {@link gnu.jpdf.StringTooLongException}
Graphics object
- * @param fm the FontMetrics to use for sizing
- * @param padding an int, the padding around the strings
- * @param hAlign the int horizontal alignment
- * @throws IllegalArgumentException if the args are invalid
- * @throws StringTooLongException if the string
- * won't fit this will only happen if the fm or padding has
- * been changed since getStringBounds was called succesfully
- */
- public void drawWrappedString(Graphics g,
- FontMetrics fm,
- int padding,
- int hAlign)
- throws IllegalArgumentException, StringTooLongException {
- if (getStringArray() == null) {
- Point p = getDrawingPoint();
- int xx = (int)p.getX();
- int yy = (int)p.getY();
- g.drawString(getFullString(), xx, yy);
- }
- else {
- int len = stringArray.length;
- for (int i = 0; i < len; i++) {
- BoundingBox wrappedBox = null;
- wrappedBox = getStringBounds(stringArray[i],
- hAlign,
- BoundingBox.VERT_ALIGN_TOP,
- fm,
- 0);
- Point pp = wrappedBox.getDrawingPoint();
- int xx = (int)pp.getX();
- if (hAlign == BoundingBox.HORIZ_ALIGN_RIGHT) {
- xx -= padding;
- }
- if (hAlign == BoundingBox.HORIZ_ALIGN_LEFT) {
- xx += padding;
- }
- int yy = (int)pp.getY() + padding;
- g.drawString(stringArray[i], xx, yy);
- subtract(wrappedBox, BoundingBox.SUBTRACT_FROM_BOTTOM);
- }
- }
- } // end drawWrappedString
-
-
- /**
- * Draws lines from the wrapped string until there is no more room and - * then stops. If there is no string or the box is too small for - * anything to be drawn, does nothing
- * - * @param g theGraphics object to draw to
- * @param fm the FontMetrics object to use for string sizing
- * @param padding the int amount of padding around the string
- * @param hAlign the int horizontal alignment
- *
- */
- public void drawWrappedStringTruncate(Graphics g,
- FontMetrics fm,
- int padding,
- int hAlign) {
-
- if (getStringArray() == null) {
- Point p = getDrawingPoint();
- int xx = (int)p.getX();
- int yy = (int)p.getY();
- if (getFullString() != null) {
- g.drawString(getFullString(), xx, yy);
- }
- else {
- System.err.println("getStringArray and getFullString are null");
- }
- }
- else {
- int totalHeight = 0;
- int len = stringArray.length;
- for (int i = 0; i < len; i++) {
- BoundingBox wrappedBox = null;
- try {
- wrappedBox = getStringBounds(stringArray[i],
- hAlign,
- BoundingBox.VERT_ALIGN_TOP,
- fm,
- 0,
- false);
- totalHeight += (int)wrappedBox.getHeight();
- if (getParent() != null) {
- if (totalHeight > (int)(getParent().getHeight())) {
- return;
+ BoundingBox ancestor = this;
+ while (ancestor.hasParent()) {
+ BoundingBox oldRef = ancestor;
+ ancestor = ancestor.getParent();
+ // Prevent infinite recursion
+ if (ancestor == oldRef) {
+ break;
+ }
+ ancestorTranslateX += (int) ancestor.getLocation().getX();
+ ancestorTranslateY += (int) ancestor.getLocation().getY();
}
- }
+
+ this.getAbsoluteLocation().translate(ancestorTranslateX,
+ ancestorTranslateY);
+ } // end if
+ } // end setParent
+
+ /**
+ * + * Get the wrapped strings if this box was from a call to getStringBounds, + * otherwise this method returns null
+ * + * @return aString[] array of strings, top to bottom in layout
+ */
+ public String[] getStringArray() {
+ return stringArray;
+ } // end getStringArray
+
+ /**
+ * + * Set the value of the string array
+ * + * @param strArray aString array
+ *
+ */
+ public void setStringArray(String[] strArray) {
+ this.stringArray = strArray;
+ }
+
+ /**
+ * + * Set the absolute upper left world location point for this box
+ * + * @param point aPoint value
+ */
+ public void setAbsoluteLocation(Point point) {
+ this.absoluteLocation = point;
+ }
+
+ /**
+ * + * Returns false if for any reason this box has negative dimensions
+ * + * @return true if the box has positive height and width, false otherwise. + */ + public boolean boxExists() { + return (this.getHeight() > 0 && this.getWidth() > 0); + } // end boxExists + + /** + *+ * Get the absolute upper left location point for this box
+ * + * @return aPoint value
+ */
+ public Point getAbsoluteLocation() {
+ return absoluteLocation;
+ }
+
+ /**
+ *
+ * Returns the full string associated with a call to
+ * getStringBounds
+ * Sets the full string associated with getStringBounds
String
+ */
+ public void setFullString(String string) {
+ this.fullString = string;
+ }
+
+ /**
+ * + * Gets the location of a String after it is adjusted for alignment within + * this box. The point's coordinates are either within this box or within + * the enclosing area.
+ * + * @param string aString, the String to be placed
+ * @param hAlign an int, HORIZ_ALIGN_CENTER, HORIZ_ALIGN_LEFT,
+ * HORIX_ALIGN_RIGHT
+ * @param vAlign an int, VERT_ALIGN_CENTER, VERT_ALIGN_TOP,
+ * VERT_ALIGN_BOTTOM
+ * @param fm a FontMetrics object for this String
+ * @param padding an int, the padding around the String
+ * @param enforce a boolean, if true the method will throw an
+ * exception when the string is too big, if not true it will break the
+ * string down and overrun the bottom of the box. If the box is too small
+ * for even one word, the exception will be thrown
+ * @return a Point, the coords to use in drawString()
+ * @see #HORIZ_ALIGN_LEFT
+ * @see #HORIZ_ALIGN_CENTER
+ * @see #HORIZ_ALIGN_RIGHT
+ * @see #VERT_ALIGN_TOP
+ * @see #VERT_ALIGN_CENTER
+ * @see #VERT_ALIGN_BOTTOM
+ * @throws IllegalArgumentException if the args are invalid
+ * @throws StringTooLongException if the string won't fit and enforce is set
+ * to true. The exception can still be thrown if enforce is false, but only
+ * in cases such as the box having no height or width
+ */
+ public BoundingBox getStringBounds(String string,
+ int hAlign,
+ int vAlign,
+ FontMetrics fm,
+ int padding,
+ boolean enforce)
+ throws IllegalArgumentException, StringTooLongException {
+ // Check to make sure the values passed in are valid
+ if (!checkHAlign(hAlign)) {
+ throw new IllegalArgumentException("BoundingBox.getStringBounds, "
+ + "hAlign invalid : " + hAlign);
}
- catch (StringTooLongException stle) {
- stle.printStackTrace();
- return;
+ if (!checkVAlign(vAlign)) {
+ throw new IllegalArgumentException("BoundingBox.getStringBounds, "
+ + "vAlign invalid : " + hAlign);
+ }
+ if (fm == null) {
+ throw new IllegalArgumentException("BoundingBox.getStringBounds, "
+ + "FontMetrics null");
+ }
+ if (string == null) {
+ throw new IllegalArgumentException("BoundingBox.getStringBounds, "
+ + "String null");
}
- wrappedBox.drawChoppedString(g, fm, padding, hAlign);
- subtract(wrappedBox, BoundingBox.SUBTRACT_FROM_BOTTOM);
- }
- }
- } // end drawWrappedStringTruncate
+ // NOTE: For this portion of the method, parent refers
+ // to this object and child refers to the object about
+ // to be created. When the absolute point for drawing the
+ // String is determined, this object's ancestors are checked.
+ Dimension parentSize = this.getSize();
- /**
- * Take the first line of the string (if it is wrapped, otherwise just - * take the whole string) and chop the end of it off to make it fit in the - * box. If the box is smaller than one letter, draw nothing
- * - * @param g theGraphics object to draw to
- * @param fm the FontMetrics object to use for string sizing
- * @param padding the int amount of padding around the string
- * @param hAlign the int horizontal alignment
- */
- public void drawChoppedString(Graphics g,
- FontMetrics fm,
- int padding,
- int hAlign) {
+ Point childLocation;
+ Dimension childSize;
- String string = "";
- if (getStringArray() != null) {
- string = new String(getStringArray()[0]);
- }
- else {
- string = new String(getFullString());
- }
- BoundingBox choppedBox = null;
- try {
- choppedBox = getStringBounds(string,
- hAlign,
- VERT_ALIGN_TOP,
- fm,
- padding);
- Point p = choppedBox.getDrawingPoint();
- int x = (int)p.getX();
- int y = (int)p.getY();
- g.drawString(string, x, y);
- }
- catch (StringTooLongException stle) {
- // Doesn't fit - start cutting from the end until it does
- StringBuffer buf = new StringBuffer().append(string);
- if (buf.length() == 0) {
- System.out.println("BoundingBox.drawChoppedString, buf len 0 ??");
- //return;
- throw new RuntimeException();
- }
- buf.deleteCharAt(buf.length()-1);
- while ((fm.stringWidth(buf.toString()) > (int)getWidth()) &&
- (buf.length() > 0)) {
- buf.deleteCharAt(buf.length()-1);
- }
-
- try {
- choppedBox = getStringBounds(buf.toString(),
- hAlign,
- VERT_ALIGN_TOP,
- fm,
- padding);
- Point pp = choppedBox.getDrawingPoint();
- int xx = (int)pp.getX();
- int yy = (int)pp.getY();
- g.drawString(string, xx, yy);
- }
- catch (StringTooLongException sstle) {
- // Must be a really small box!
- sstle.printStackTrace();
- }
- }
- } // end drawChoppedString
+ // String ascent, width, height, parent, child width, height
+ int sa, sw, sh, pw, ph, cw, ch;
+ // Child, parent x, y coords for upper left
+ int cx, cy, px, py;
+ sa = fm.getMaxAscent();
+ sw = fm.stringWidth(string);
+ sh = sa + fm.getMaxDescent();
+ pw = (int) parentSize.getWidth();
+ ph = (int) parentSize.getHeight();
+ if (pw < 0) {
+ throw new StringTooLongException("The parent box has a negative width "
+ + " (" + pw + ")");
+ }
+ if (ph < 0) {
+ throw new StringTooLongException("The parent box has a negative height"
+ + " (" + ph + ")");
+ }
+ cw = sw + padding * 2;
+ ch = sh + padding * 2;
+ px = (int) this.getX();
+ py = (int) this.getY();
+ String[] childStrArray = null;
+ if ((cw > pw) || (string.indexOf("\n") != -1)) {
+ cw = pw - (padding * 2);
+ childStrArray = createStringArray(string, fm, padding, pw);
+ ch = getWrappedHeight(childStrArray, fm, padding);
+ if (ch > ph) {
+ // If enforce is not true, it means we want the box to
+ // be returned anyway (along with the strings in the array)
+ // so we can chop them manually and try again
+ if (enforce) {
+ throw new StringTooLongException("The wrapped strings do not "
+ + "fit into the parent box, pw=" + pw
+ + ", ph=" + ph + ", ch=" + ch + ", cw=" + cw
+ + ", string: " + string);
+ }
+ }
+ }
+ // Need to have child width and height, and string array set
+ // Child location is relative to this (parent) box, not the world
+ if (vAlign == VERT_ALIGN_TOP) {
+ cy = 0;
+ } else if (vAlign == VERT_ALIGN_CENTER) {
+ cy = (ph / 2) - (ch / 2);
+ } else {
+ cy = ph - ch;
+ }
+ if (hAlign == HORIZ_ALIGN_LEFT) {
+ cx = 0;
+ } else if (hAlign == HORIZ_ALIGN_CENTER) {
+ cx = (pw / 2) - (cw / 2);
+ } else {
+ cx = pw - cw;
+ }
+ childLocation = new Point(cx, cy);
+ childSize = new Dimension(cw, ch);
+ // Drawing location is based on the baseline of the String, and
+ // relative to the world, not this box. The drawing point differs
+ // from the absolute box location because of padding and ascent
+ int dpx, dpy, abx, aby;
- /**
- * Get the total height of the box needed to contain the strings in - * the specified array
- */ - private int getWrappedHeight(String[] strings, FontMetrics fm, int padding) { - int ma = fm.getMaxAscent(); - int md = fm.getMaxDescent(); - int sh = ma + md; - int hPad = sh / LINE_SPACING_PERCENTAGE; - sh += hPad; - int total = sh * strings.length; + // If this object also has a parent (maybe grandparents), iterate + // through them and find the absolute 'world' location + int ancestorTranslateX = 0; + int ancestorTranslateY = 0; - return total + (padding*2); - } // end getWrappedHeight + BoundingBox ancestor = this; + while (ancestor.hasParent()) { + BoundingBox oldRef = ancestor; + ancestor = ancestor.getParent(); + // Prevent infinite recursion + if (ancestor == oldRef) { + break; + } + ancestorTranslateX += (int) ancestor.getLocation().getX(); + ancestorTranslateY += (int) ancestor.getLocation().getY(); + } + // Determine the absolute location for the box + abx = px + cx + ancestorTranslateX; + aby = py + cy + ancestorTranslateY; + // Determine the absolute drawing point for the String + dpx = abx + padding; + dpy = aby + padding + sa; - /** - * - *Make a string array from a string, wrapped to fit the box
- * - *If the line width is too short, the array is just a - * tokenized version of the string
- * - * @param string - theString to convert to an array
- * @param
- */
- private String[] createStringArray(String string,
- FontMetrics fm,
- int padding,
- int pw) {
- if (string == null) {
- System.err.println("Tried createStringArray with null String");
- return null;
- }
- if (fm == null) {
- System.err.println("Tried createStringArray with null FontMetrics");
- }
+ Point drawingPoint = new Point(dpx, dpy);
+ BoundingBox returnChild = new BoundingBox(childLocation,
+ childSize,
+ drawingPoint,
+ new Point(abx, aby));
+ this.add(returnChild);
+ returnChild.setFullString(string);
+ returnChild.setStringArray(childStrArray);
+ return returnChild;
- int lw = pw - (padding*2);
+ } // end getStringBounds
-
+ /**
+ * + * Gets the location of a String after it is adjusted for alignment within + * this box. The point's coordinates are either within this box or within + * the enclosing area.
+ * + *+ * By default, this method enforces string length and throws the exception + * if it is too long
+ * + * @param string aString, the String to be placed
+ * @param hAlign an int, HORIZ_ALIGN_CENTER, HORIZ_ALIGN_LEFT,
+ * HORIX_ALIGN_RIGHT
+ * @param vAlign an int, VERT_ALIGN_CENTER, VERT_ALIGN_TOP,
+ * VERT_ALIGN_BOTTOM
+ * @param fm a FontMetrics object for this String
+ * @param padding an int, the padding around the String
+ * @return a Point, the coords to use in drawString()
+ * @throws IllegalArgumentException if the args are invalid
+ * @throws StringTooLongException if the string won't fit
+ */
+ public BoundingBox getStringBounds(String string,
+ int hAlign,
+ int vAlign,
+ FontMetrics fm,
+ int padding)
+ throws StringTooLongException, IllegalArgumentException {
+ return getStringBounds(string, hAlign, vAlign, fm, padding, true);
+ } // end getStringBounds (enforce true by default)
- Vector
+ * This method is called after getting the box by calling
+ * getStringBounds on the parent. Wraps the string at word
+ * boundaries and draws it to the specified Graphics context.
+ * Make sure padding is the same as specified for the
+ * getStringBounds call, or you may get an unexpected
+ * {@link gnu.jpdf.StringTooLongException}
Graphics object
+ * @param fm the FontMetrics to use for sizing
+ * @param padding an int, the padding around the strings
+ * @param hAlign the int horizontal alignment
+ * @throws IllegalArgumentException if the args are invalid
+ * @throws StringTooLongException if the string won't fit this will only
+ * happen if the fm or padding has been changed since getStringBounds was
+ * called succesfully
+ */
+ public void drawWrappedString(Graphics g,
+ FontMetrics fm,
+ int padding,
+ int hAlign)
+ throws IllegalArgumentException, StringTooLongException {
+ if (getStringArray() == null) {
+ Point p = getDrawingPoint();
+ int xx = (int) p.getX();
+ int yy = (int) p.getY();
+ g.drawString(getFullString(), xx, yy);
+ } else {
+ int len = stringArray.length;
+ for (int i = 0; i < len; i++) {
+ BoundingBox wrappedBox = null;
+ wrappedBox = getStringBounds(stringArray[i],
+ hAlign,
+ BoundingBox.VERT_ALIGN_TOP,
+ fm,
+ 0);
+ Point pp = wrappedBox.getDrawingPoint();
+ int xx = (int) pp.getX();
+ if (hAlign == BoundingBox.HORIZ_ALIGN_RIGHT) {
+ xx -= padding;
+ }
+ if (hAlign == BoundingBox.HORIZ_ALIGN_LEFT) {
+ xx += padding;
+ }
+ int yy = (int) pp.getY() + padding;
+ g.drawString(stringArray[i], xx, yy);
+ subtract(wrappedBox, BoundingBox.SUBTRACT_FROM_BOTTOM);
+ }
+ }
+ } // end drawWrappedString
- while(st.hasMoreTokens()) {
- // Get the next word and add a space after it
- String tempString = st.nextToken();
- tempBuffer.append(tempString);
+ /**
+ * + * Draws lines from the wrapped string until there is no more room and then + * stops. If there is no string or the box is too small for anything to be + * drawn, does nothing
+ * + * @param g theGraphics object to draw to
+ * @param fm the FontMetrics object to use for string sizing
+ * @param padding the int amount of padding around the string
+ * @param hAlign the int horizontal alignment
+ *
+ */
+ public void drawWrappedStringTruncate(Graphics g,
+ FontMetrics fm,
+ int padding,
+ int hAlign) {
- // If we haven't reached the width with our current
- // line, keep adding tokens. Also, check for hard returns
- if ((fm.stringWidth(tempBuffer.toString()) < lw) &&
- (tempBuffer.toString()
- .charAt(tempBuffer.toString().length() - 1) != '\n') &&
- (tempBuffer.toString()
- .charAt(tempBuffer.toString().length() - 1) != '\r')) {
- finalBuffer.append(tempString);
- continue;
- }
+ if (getStringArray() == null) {
+ Point p = getDrawingPoint();
+ int xx = (int) p.getX();
+ int yy = (int) p.getY();
+ if (getFullString() != null) {
+ g.drawString(getFullString(), xx, yy);
+ } else {
+ System.err.println("getStringArray and getFullString are null");
+ }
+ } else {
+ int totalHeight = 0;
+ int len = stringArray.length;
+ for (int i = 0; i < len; i++) {
+ BoundingBox wrappedBox = null;
+ try {
+ wrappedBox = getStringBounds(stringArray[i],
+ hAlign,
+ BoundingBox.VERT_ALIGN_TOP,
+ fm,
+ 0,
+ false);
+ totalHeight += (int) wrappedBox.getHeight();
+ if (getParent() != null) {
+ if (totalHeight > (int) (getParent().getHeight())) {
+ return;
+ }
+ }
+ } catch (StringTooLongException stle) {
+ stle.printStackTrace();
+ return;
+ }
+ wrappedBox.drawChoppedString(g, fm, padding, hAlign);
+ subtract(wrappedBox, BoundingBox.SUBTRACT_FROM_BOTTOM);
+ }
+ }
+ } // end drawWrappedStringTruncate
+
+ /**
+ * + * Take the first line of the string (if it is wrapped, otherwise just take + * the whole string) and chop the end of it off to make it fit in the box. + * If the box is smaller than one letter, draw nothing
+ * + * @param g theGraphics object to draw to
+ * @param fm the FontMetrics object to use for string sizing
+ * @param padding the int amount of padding around the string
+ * @param hAlign the int horizontal alignment
+ */
+ public void drawChoppedString(Graphics g,
+ FontMetrics fm,
+ int padding,
+ int hAlign) {
+
+ String string = "";
+ if (getStringArray() != null) {
+ string = new String(getStringArray()[0]);
+ } else {
+ string = new String(getFullString());
+ }
+ BoundingBox choppedBox = null;
+ try {
+ choppedBox = getStringBounds(string,
+ hAlign,
+ VERT_ALIGN_TOP,
+ fm,
+ padding);
+ Point p = choppedBox.getDrawingPoint();
+ int x = (int) p.getX();
+ int y = (int) p.getY();
+ g.drawString(string, x, y);
+ } catch (StringTooLongException stle) {
+ // Doesn't fit - start cutting from the end until it does
+ StringBuffer buf = new StringBuffer().append(string);
+ if (buf.length() == 0) {
+ System.out.println("BoundingBox.drawChoppedString, buf len 0 ??");
+ //return;
+ throw new RuntimeException();
+ }
+ buf.deleteCharAt(buf.length() - 1);
+ while ((fm.stringWidth(buf.toString()) > (int) getWidth())
+ && (buf.length() > 0)) {
+ buf.deleteCharAt(buf.length() - 1);
+ }
+
+ try {
+ choppedBox = getStringBounds(buf.toString(),
+ hAlign,
+ VERT_ALIGN_TOP,
+ fm,
+ padding);
+ Point pp = choppedBox.getDrawingPoint();
+ int xx = (int) pp.getX();
+ int yy = (int) pp.getY();
+ g.drawString(string, xx, yy);
+ } catch (StringTooLongException sstle) {
+ // Must be a really small box!
+ sstle.printStackTrace();
+ }
+ }
+ } // end drawChoppedString
+
+ /**
+ * + * Get the total height of the box needed to contain the strings in the + * specified array
+ */ + private int getWrappedHeight(String[] strings, FontMetrics fm, int padding) { + int ma = fm.getMaxAscent(); + int md = fm.getMaxDescent(); + int sh = ma + md; + int hPad = sh / LINE_SPACING_PERCENTAGE; + sh += hPad; + int total = sh * strings.length; + + return total + (padding * 2); + } // end getWrappedHeight + + /** + * + *+ * Make a string array from a string, wrapped to fit the box
+ * + *+ * If the line width is too short, the array is just a tokenized version of + * the string
+ * + * @param string - theString to convert to an array
+ * @param
+ */
+ private String[] createStringArray(String string,
+ FontMetrics fm,
+ int padding,
+ int pw) {
+ if (string == null) {
+ System.err.println("Tried createStringArray with null String");
+ return null;
+ }
+ if (fm == null) {
+ System.err.println("Tried createStringArray with null FontMetrics");
+ }
+
+ int lw = pw - (padding * 2);
+
+ Vector+ * Removes the child box from this parent box. The child must have this + * object as its parent or the method does nothing. The BoundingBox returned + * will be cut by an area equal to the child area plus the horizontal or + * vertical strip in which it sits, depending on the 'subtractFrom' value + * passed in
+ * + * @param child aBoundingBox value
+ * @param subtractFrom an int, SUBTRACT_FROM_LEFT,
+ * SUBTRACT_FROM_RIGHT, SUBTRACT_FROM_TOP, SUBTRACT_FROM_BOTTOM
+ * @return a BoundingBox value
+ * @see #SUBTRACT_FROM_LEFT
+ * @see #SUBTRACT_FROM_RIGHT
+ * @see #SUBTRACT_FROM_TOP
+ * @see #SUBTRACT_FROM_BOTTOM
+ */
+ public BoundingBox subtract(BoundingBox child, int subtractFrom) {
+ // First, check to see if the params are valid
+ if (child == null) {
+ throw new IllegalArgumentException("BoundingBox.subtract, "
+ + "BoundingBox child is null");
+ }
+ if (!child.hasParent()) {
+ throw new IllegalArgumentException("BoundingBox.subtract, "
+ + "BoundingBox child has no parent");
+ }
+ if (!(child.getParent() == this)) {
+ throw new IllegalArgumentException("BoundingBox.subtract, "
+ + "this is not BoundingBox child's parent");
+ }
+ // Now that we know the child is this object's child, we continue
+ // and check the subtractFrom param
+ int len = SUBTRACTS.length;
+ boolean valid = false;
+ for (int i = 0; i < len; i++) {
+ if (subtractFrom == SUBTRACTS[i]) {
+ valid = true;
+ }
+ }
+ if (!valid) {
+ throw new IllegalArgumentException("BoundingBox.subtract, "
+ + "subtractFrom invalid: " + subtractFrom);
+ }
+
+ // Now we know the child is valid, and if the subtractFrom
+ // preference was invalid, we subtract from the bottom
+ // The child should no longer be used, since the parent
+ // reference will be invalid
+ child.setParent(null);
+
+ int cx = (int) child.getLocation().getX();
+ int cy = (int) child.getLocation().getY();
+ int cw = (int) child.getSize().getWidth();
+ int ch = (int) child.getSize().getHeight();
+ int px = (int) this.getLocation().getX();
+ int py = (int) this.getLocation().getY();
+ int pw = (int) this.getSize().getWidth();
+ int ph = (int) this.getSize().getHeight();
+
+ switch (subtractFrom) {
+ case SUBTRACT_FROM_LEFT:
+ // This will be useful for right-justified Strings in tables
+ pw = cx;
+ this.setSize(new Dimension(pw, ph));
+ return this;
+
+ case SUBTRACT_FROM_RIGHT:
+ // This will be useful for left justified Strings in tables
+ px = px + cw + cx;
+ pw = pw - cw - cx;
+ this.setLocation(new Point(px, py));
+ this.setSize(new Dimension(pw, ph));
+ return this;
+
+ case SUBTRACT_FROM_BOTTOM:
+ py = py + ch + cy;
+ ph = ph - ch - cy;
+ this.setLocation(new Point(px, py));
+ this.setSize(new Dimension(pw, ph));
+ return this;
+
+ case SUBTRACT_FROM_TOP:
+ ph = cy;
+ this.setSize(new Dimension(pw, ph));
+ return this;
+
+ default: // Should never happen
+ break;
+ } // end switch
+ return this;
+ } // end subtract
+
+ /**
+ * + * Gets the drawing point to use in Graphics drawing methods. After getting + * a new BoundingBox with getStringBounds(), calling this method will give + * you an absolute point, accounting for alignment and padding, etc, from + * which to start drawing the String + *
+ * + *+ * If getStringBounds was not called (this is a parent box), the upper left + * coordinates will be returned (this.getLocation()) + *
+ * + * @return aPoint
+ */
+ public Point getDrawingPoint() {
+ return drawingPoint;
}
- return childStrArray;
-
- } // end createStringArray
-
-
-
- /**
- * Removes the child box from this parent box. The child must - * have this object as its parent or the method does nothing. - * The BoundingBox returned will be cut by an area equal to - * the child area plus the horizontal or vertical strip in - * which it sits, depending on the 'subtractFrom' value passed - * in
- * - * @param child aBoundingBox value
- * @param subtractFrom an int, SUBTRACT_FROM_LEFT,
- SUBTRACT_FROM_RIGHT, SUBTRACT_FROM_TOP,
- SUBTRACT_FROM_BOTTOM
- * @return a BoundingBox value
- * @see #SUBTRACT_FROM_LEFT
- * @see #SUBTRACT_FROM_RIGHT
- * @see #SUBTRACT_FROM_TOP
- * @see #SUBTRACT_FROM_BOTTOM
- */
- public BoundingBox subtract(BoundingBox child, int subtractFrom) {
- // First, check to see if the params are valid
- if (child == null) {
- throw new IllegalArgumentException("BoundingBox.subtract, "
- + "BoundingBox child is null");
- }
- if (!child.hasParent()) {
- throw new IllegalArgumentException("BoundingBox.subtract, "
- + "BoundingBox child has no parent");
- }
- if (!(child.getParent() == this)) {
- throw new IllegalArgumentException("BoundingBox.subtract, "
- + "this is not BoundingBox child's parent");
- }
- // Now that we know the child is this object's child, we continue
- // and check the subtractFrom param
- int len = SUBTRACTS.length;
- boolean valid = false;
- for (int i = 0; i < len; i++) {
- if (subtractFrom == SUBTRACTS[i]) {
- valid = true;
- }
- }
- if (!valid) {
- throw new IllegalArgumentException("BoundingBox.subtract, "
- + "subtractFrom invalid: " + subtractFrom);
- }
-
- // Now we know the child is valid, and if the subtractFrom
- // preference was invalid, we subtract from the bottom
-
- // The child should no longer be used, since the parent
- // reference will be invalid
- child.setParent(null);
-
- int cx = (int) child.getLocation().getX();
- int cy = (int) child.getLocation().getY();
- int cw = (int) child.getSize().getWidth();
- int ch = (int) child.getSize().getHeight();
- int px = (int) this.getLocation().getX();
- int py = (int) this.getLocation().getY();
- int pw = (int) this.getSize().getWidth();
- int ph = (int) this.getSize().getHeight();
-
- switch (subtractFrom) {
- case SUBTRACT_FROM_LEFT:
- // This will be useful for right-justified Strings in tables
- pw = cx;
- this.setSize(new Dimension(pw, ph));
- return this;
-
- case SUBTRACT_FROM_RIGHT:
- // This will be useful for left justified Strings in tables
- px = px + cw + cx;
- pw = pw - cw - cx;
- this.setLocation(new Point(px, py));
- this.setSize(new Dimension(pw, ph));
- return this;
-
- case SUBTRACT_FROM_BOTTOM:
- py = py + ch + cy;
- ph = ph - ch - cy;
- this.setLocation(new Point(px, py));
- this.setSize(new Dimension(pw, ph));
- return this;
-
- case SUBTRACT_FROM_TOP:
- ph = cy;
- this.setSize(new Dimension(pw, ph));
- return this;
-
- default: // Should never happen
- break;
- } // end switch
- return this;
- } // end subtract
-
-
-
-
- /**
- * - * Gets the drawing point to use in Graphics drawing methods. After getting - * a new BoundingBox with getStringBounds(), calling this method will give - * you an absolute point, accounting for alignment and padding, etc, from - * which to start drawing the String - *
- * - *- * If getStringBounds was not called (this is a parent box), the upper left - * coordinates will be returned (this.getLocation()) - *
- * - * @return aPoint
- */
- public Point getDrawingPoint() {
- return drawingPoint;
- }
-
-
-
-
-
- // main method is for testing /////////////////
-
-
-
+ // main method is for testing /////////////////
/**
* For testing
*
* @param args a String[] value
*/
public static void main(String[] args) {
- Point upperLeft = new Point(5, 5);
- Dimension bounds = new Dimension(100, 100);
- BoundingBox parent = new BoundingBox(upperLeft, bounds);
- String string = "Hello World!";
- Font font = new Font("SansSerif", Font.PLAIN, 12);
- Frame frame = new Frame();
- frame.addNotify();
- try {
- Image image = frame.createImage(100, 100);
- if (image == null) {
- System.err.println("image is null");
- }
- Graphics graphics = image.getGraphics();
- FontMetrics fm = graphics.getFontMetrics(font);
- BoundingBox child = parent
- .getStringBounds(string,
- BoundingBox.HORIZ_ALIGN_LEFT,
- BoundingBox.VERT_ALIGN_TOP,
- fm,
- 5);
- System.out.println("Drawing Point: " +
- child.getDrawingPoint().toString());
- System.out.println("Now testing subtract() method...");
+ Point upperLeft = new Point(5, 5);
+ Dimension bounds = new Dimension(100, 100);
+ BoundingBox parent = new BoundingBox(upperLeft, bounds);
+ String string = "Hello World!";
+ Font font = new Font("SansSerif", Font.PLAIN, 12);
+ Frame frame = new Frame();
+ frame.addNotify();
+ try {
+ Image image = frame.createImage(100, 100);
+ if (image == null) {
+ System.err.println("image is null");
+ }
+ Graphics graphics = image.getGraphics();
+ FontMetrics fm = graphics.getFontMetrics(font);
+ BoundingBox child = parent
+ .getStringBounds(string,
+ BoundingBox.HORIZ_ALIGN_LEFT,
+ BoundingBox.VERT_ALIGN_TOP,
+ fm,
+ 5);
+ System.out.println("Drawing Point: "
+ + child.getDrawingPoint().toString());
+ System.out.println("Now testing subtract() method...");
- parent = new BoundingBox(new Point(10, 10), new Dimension(300, 300));
- System.out.println("parent: " + parent.toString());
- child = new BoundingBox(new Point(90, 110), new Dimension(100, 100));
- parent.add(child);
- System.out.println("child: " + child.toString());
- System.out.println();
- System.out.println("subtracting the child from the parent");
- System.out.println("SUBTRACT_FROM_TOP: ");
- parent = parent.subtract(child, SUBTRACT_FROM_TOP);
- System.out.println("new parent: " + parent.toString());
- System.out.println();
- System.out.println("Resetting parent");
- parent = new BoundingBox(new Point(10, 10), new Dimension(300, 300));
- parent.add(child);
- System.out.println("SUBTRACT_FROM_BOTTOM");
- parent.subtract(child, SUBTRACT_FROM_BOTTOM);
- System.out.println("new parent: " + parent.toString());
- System.out.println();
- System.out.println("Resetting parent");
- parent = new BoundingBox(new Point(10, 10), new Dimension(300, 300));
- parent.add(child);
- System.out.println("SUBTRACT_FROM_LEFT");
- parent.subtract(child, SUBTRACT_FROM_LEFT);
- System.out.println("new parent: " + parent.toString());
- System.out.println();
- System.out.println("Resetting parent");
- parent = new BoundingBox(new Point(10, 10), new Dimension(300, 300));
- parent.add(child);
- System.out.println("SUBTRACT_FROM_RIGHT");
- parent.subtract(child, SUBTRACT_FROM_RIGHT);
- System.out.println("new parent: " + parent.toString());
- System.out.println();
+ parent = new BoundingBox(new Point(10, 10), new Dimension(300, 300));
+ System.out.println("parent: " + parent.toString());
+ child = new BoundingBox(new Point(90, 110), new Dimension(100, 100));
+ parent.add(child);
+ System.out.println("child: " + child.toString());
+ System.out.println();
+ System.out.println("subtracting the child from the parent");
+ System.out.println("SUBTRACT_FROM_TOP: ");
+ parent = parent.subtract(child, SUBTRACT_FROM_TOP);
+ System.out.println("new parent: " + parent.toString());
+ System.out.println();
+ System.out.println("Resetting parent");
+ parent = new BoundingBox(new Point(10, 10), new Dimension(300, 300));
+ parent.add(child);
+ System.out.println("SUBTRACT_FROM_BOTTOM");
+ parent.subtract(child, SUBTRACT_FROM_BOTTOM);
+ System.out.println("new parent: " + parent.toString());
+ System.out.println();
+ System.out.println("Resetting parent");
+ parent = new BoundingBox(new Point(10, 10), new Dimension(300, 300));
+ parent.add(child);
+ System.out.println("SUBTRACT_FROM_LEFT");
+ parent.subtract(child, SUBTRACT_FROM_LEFT);
+ System.out.println("new parent: " + parent.toString());
+ System.out.println();
+ System.out.println("Resetting parent");
+ parent = new BoundingBox(new Point(10, 10), new Dimension(300, 300));
+ parent.add(child);
+ System.out.println("SUBTRACT_FROM_RIGHT");
+ parent.subtract(child, SUBTRACT_FROM_RIGHT);
+ System.out.println("new parent: " + parent.toString());
+ System.out.println();
-
-
- System.exit(0);
+ System.exit(0);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
}
- catch (Exception e) {
- e.printStackTrace();
- System.exit(1);
+
+ // Private methods /////////////////////////////
+ /**
+ * Creates a new BoundingBox instance.
+ *
+ * @param p a Point value
+ * @param d a Dimension value
+ * @param drawingPoint a Point value
+ */
+ private BoundingBox(Point p,
+ Dimension d,
+ Point drawingPoint,
+ Point absolute) {
+ super(p, d);
+ this.drawingPoint = drawingPoint;
+ this.absoluteLocation = absolute;
}
- }
-
- // Private methods /////////////////////////////
-
- /**
- * Creates a new BoundingBox instance.
- *
- * @param p a Point value
- * @param d a Dimension value
- * @param drawingPoint a Point value
- */
- private BoundingBox(Point p,
- Dimension d,
- Point drawingPoint,
- Point absolute) {
- super(p, d);
- this.drawingPoint = drawingPoint;
- this.absoluteLocation = absolute;
- }
-
-
- /**
- * Checks the horizontal alignment passed into a - * method to make sure it is one of the valid values
- * - * @param hAlign anint value
- * @return a boolean value
- */
- private boolean checkHAlign(int hAlign) {
- int len = HORIZ_ALIGNS.length;
- for (int i = 0; i < len; i++) {
- if (hAlign == HORIZ_ALIGNS[i]) {
- return true;
- }
+ /**
+ * + * Checks the horizontal alignment passed into a method to make sure it is + * one of the valid values
+ * + * @param hAlign anint value
+ * @return a boolean value
+ */
+ private boolean checkHAlign(int hAlign) {
+ int len = HORIZ_ALIGNS.length;
+ for (int i = 0; i < len; i++) {
+ if (hAlign == HORIZ_ALIGNS[i]) {
+ return true;
+ }
+ }
+ return false;
}
- return false;
- }
-
-
- /**
- * Checks the vertical alignment passed into a - * method to make sure it is one of the valid values
- * - * @param vAlign anint value
- * @return a boolean value
- */
- private boolean checkVAlign(int vAlign) {
- int len = VERT_ALIGNS.length;
- for (int i = 0; i < len; i++) {
- if (vAlign == VERT_ALIGNS[i]) {
- return true;
- }
+ /**
+ * + * Checks the vertical alignment passed into a method to make sure it is one + * of the valid values
+ * + * @param vAlign anint value
+ * @return a boolean value
+ */
+ private boolean checkVAlign(int vAlign) {
+ int len = VERT_ALIGNS.length;
+ for (int i = 0; i < len; i++) {
+ if (vAlign == VERT_ALIGNS[i]) {
+ return true;
+ }
+ }
+ return false;
}
- return false;
- }
} // end class BoundingBox
-
-
-
diff --git a/libsrc/gnujpdf/src/gnu/jpdf/MyRect.java b/libsrc/gnujpdf/src/gnu/jpdf/MyRect.java
index ae5e3f697..28e2f5e75 100644
--- a/libsrc/gnujpdf/src/gnu/jpdf/MyRect.java
+++ b/libsrc/gnujpdf/src/gnu/jpdf/MyRect.java
@@ -5,6 +5,7 @@ package gnu.jpdf;
* @author JPEXS
*/
public class MyRect {
+
public int xMin;
public int yMin;
public int xMax;
diff --git a/libsrc/gnujpdf/src/gnu/jpdf/PDFAnnot.java b/libsrc/gnujpdf/src/gnu/jpdf/PDFAnnot.java
index 6ad0c9076..9c9122853 100644
--- a/libsrc/gnujpdf/src/gnu/jpdf/PDFAnnot.java
+++ b/libsrc/gnujpdf/src/gnu/jpdf/PDFAnnot.java
@@ -24,249 +24,257 @@ import java.io.OutputStream;
import java.io.Serializable;
/**
- * This class defines an annotation (commonly known as a Bookmark).
+ *+ * This class defines an annotation (commonly known as a Bookmark).
* * @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 - *If the style is DASHED, then this method uses PDF's default dash - * scheme {3} - * - *
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. - * - *
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
+ *
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.
+ *
+ *
+ * If the style is DASHED, then this method uses PDF's default dash scheme + * {3} + * + *
+ * 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. + * + *
+ * 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); - } } diff --git a/libsrc/gnujpdf/src/gnu/jpdf/PDFBorder.java b/libsrc/gnujpdf/src/gnu/jpdf/PDFBorder.java index 48f73c74a..f723869ab 100644 --- a/libsrc/gnujpdf/src/gnu/jpdf/PDFBorder.java +++ b/libsrc/gnujpdf/src/gnu/jpdf/PDFBorder.java @@ -23,65 +23,67 @@ import java.io.IOException; import java.io.OutputStream; /** - *
A border around an annotation
+ *+ * A border around an annotation
* * * @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. - *Note: Do not use PDFAnnot.DASHED with this method. - * Use the other constructor. + *
+ * 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
+ * This class implements the PDF Catalog, also known as the root node
* * @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 - + diff --git a/libsrc/gnujpdf/src/gnu/jpdf/PDFDocument.java b/libsrc/gnujpdf/src/gnu/jpdf/PDFDocument.java index 472276417..33c15f032 100644 --- a/libsrc/gnujpdf/src/gnu/jpdf/PDFDocument.java +++ b/libsrc/gnujpdf/src/gnu/jpdf/PDFDocument.java @@ -37,230 +37,234 @@ import java.util.logging.Level; import java.util.logging.Logger; /** - *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.
+ *+ * 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.
* - *Note that most programmers using this package will NEVER access
- * one of these objects directly. Most everything can be done using
- * PDFJob and PDFGraphics, so you don't need
- * to directly instantiate a PDFDocument
+ * Note that most programmers using this package will NEVER access one of these
+ * objects directly. Most everything can be done using PDFJob and
+ * PDFGraphics, so you don't need to directly instantiate a
+ * PDFDocument
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?
+ *+ * 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?
* * @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 VectorThis page mode indicates that the document - * should be opened just with the page visible. This is the default
- */ - public static final int USENONE = 0; - - /** - *This page mode indicates that the Outlines - * should also be displayed when the document is opened.
- */ - public static final int USEOUTLINES = 1; - - /** - *This page mode indicates that the Thumbnails should be visible when the - * document first opens.
- */ - public static final int USETHUMBS = 2; - - /** - *- * 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.
- */ - public static final int FULLSCREEN = 3; - - /** - *- * These map the page modes just defined to the pagemodes setting of PDF. - *
- */ - 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; - - /** - *This is used to provide a unique name for an image
- */ - private int imageid = 0; - - /** - * This holds the current fonts - */ - private VectorThis creates a PDF document with the default pagemode
- */ - public PDFDocument() { - this(USENONE); - } - - /** - *This creates a PDF document
- * @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 VectorOnce added, it is allocated a unique serial number. - * - *
Note: 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; - } - - /** - *
This returns a specific page. It's used mainly when using a - * Serialized template file.
- * - * ?? 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; + + /** + *+ * This page mode indicates that the document should be opened just with the + * page visible. This is the default
+ */ + public static final int USENONE = 0; + + /** + *+ * This page mode indicates that the Outlines should also be displayed when + * the document is opened.
+ */ + public static final int USEOUTLINES = 1; + + /** + *+ * This page mode indicates that the Thumbnails should be visible when the + * document first opens.
+ */ + public static final int USETHUMBS = 2; + + /** + *+ * 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.
+ */ + public static final int FULLSCREEN = 3; + + /** + *+ * These map the page modes just defined to the pagemodes setting of PDF. + *
+ */ + 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; + + /** + *+ * This is used to provide a unique name for an image
+ */ + private int imageid = 0; + + /** + * This holds the current fonts + */ + private Vector+ * This creates a PDF document with the default pagemode
+ */ + 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)) + + /** + *+ * This creates a PDF document
+ * + * @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+ * Once added, it is allocated a unique serial number. + * + *
+ * Note: 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; + } + + /** + *
+ * This returns a specific page. It's used mainly when using a Serialized + * template file.
+ * + * ?? 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(); - } - - /** - *Set the PDFInfo object, which contains author, title, - * keywords, etc
- * @param info a PDFInof object - */ - public void setPDFInfo(PDFInfo info) { - this.info = info; - } - - - /** - *Get the PDFInfo object, which contains author, title, keywords, - * etc
- * @return the PDFInfo object for this document. - */ - public PDFInfo getPDFInfo() { - return this.info; - } - - - /** - * This writes the document to an OutputStream. - * - *Note: You can call this as many times as you wish, as long as - * the calls are not running at the same time. - * - *
Also, objects can be added or amended between these calls. - * - *
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(); - } - + + /** + *
+ * Set the PDFInfo object, which contains author, title, keywords, etc
+ * + * @param info a PDFInof object + */ + public void setPDFInfo(PDFInfo info) { + this.info = info; + } + + /** + *+ * Get the PDFInfo object, which contains author, title, keywords, etc
+ * + * @return the PDFInfo object for this document. + */ + public PDFInfo getPDFInfo() { + return this.info; + } + + /** + * This writes the document to an OutputStream. + * + *+ * Note: You can call this as many times as you wish, as long as the + * calls are not running at the same time. + * + *
+ * Also, objects can be added or amended between these calls. + * + *
+ * 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
diff --git a/libsrc/gnujpdf/src/gnu/jpdf/PDFEmbeddedFont.java b/libsrc/gnujpdf/src/gnu/jpdf/PDFEmbeddedFont.java
index c2ba06b93..9b4a30102 100644
--- a/libsrc/gnujpdf/src/gnu/jpdf/PDFEmbeddedFont.java
+++ b/libsrc/gnujpdf/src/gnu/jpdf/PDFEmbeddedFont.java
@@ -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
diff --git a/libsrc/gnujpdf/src/gnu/jpdf/PDFFont.java b/libsrc/gnujpdf/src/gnu/jpdf/PDFFont.java
index 93be6adc4..404f50b93 100644
--- a/libsrc/gnujpdf/src/gnu/jpdf/PDFFont.java
+++ b/libsrc/gnujpdf/src/gnu/jpdf/PDFFont.java
@@ -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 In theory you could use setClip(), except that java.awt.Graphics
* only supports Rectangle with that method, so we will have an extra
* method.
* @param p Polygon to clip to
*/
public void clipPolygon(Polygon p) {
closeBlock(); // finish off any existing path
polygon(p.xpoints,p.ypoints,p.npoints);
closeBlock("W"); // clip to current path
clipRectangle = p.getBounds();
}
/**
* Clips to a set of coordinates
* @param x coordinate
* @param y coordinate
* @param w width
* @param h height
*/
public void clipRect(int x,int y,int w,int h) {
setClip(x,y,w,h);
}
/**
* All functions should call this to close any existing optimized blocks.
*/
void closeBlock() {
closeBlock("S");
}
/**
* This is used by code that use the path in any way other than Stroke
* (like Fill, close path & Stroke etc). Usually this is used internally. 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. Once complete, the child should be released with it's dispose()
* method which will restore the graphics state to it's parent. The new current point is (x2,y2)
*
* @param x1 Second control point
* @param y1 Second control point
* @param x2 Destination point
* @param y2 Destination point
*/
public void curveto(double x1,double y1,double x2,double y2) {
newPath();
pw.println(cxy(x1,y1)+cxy(x2,y2)+"v");
lx=(float)x2;
ly=(float)y2;
}
/**
* This extension appends a Bezier curve to the path. The curve
* extends from the current point to (x3,y3) using (x1,y1) and
* (x2,y2) as the Bezier control points.
* The new current point is (x3,y3)
*
* @param x1 First control point
* @param y1 First control point
* @param x2 Second control point
* @param y2 Second control point
* @param x3 Destination point
* @param y3 Destination point
*/
public void curveto(double x1,double y1,double x2,double y2,double x3,double y3) {
newPath();
pw.println(cxy(x1,y1)+cxy(x2,y2)+cxy(x3,y3)+"c");
lx=(float)x3;
ly=(float)y3;
}
/**
* This extension appends a Bezier curve to the path. The curve
* extends from the current point to (x2,y2) using the current
* point and (x1,y1) as the Bezier control points.
* The new current point is (x2,y2)
*
* @param x1 Second control point
* @param y1 Second control point
* @param x2 Destination point
* @param y2 Destination point
*/
public void curveto(int x1,int y1,int x2,int y2) {
newPath();
pw.println(cxy(x1,y1)+cxy(x2,y2)+"v");
lx=x2;
ly=y2;
}
/**
* This extension appends a Bezier curve to the path. The curve
* extends from the current point to (x3,y3) using (x1,y1) and
* (x2,y2) as the Bezier control points.
* The new current point is (x3,y3)
*
* @param x1 First control point
* @param y1 First control point
* @param x2 Second control point
* @param y2 Second control point
* @param x3 Destination point
* @param y3 Destination point
*/
public void curveto(int x1,int y1,int x2,int y2,int x3,int y3) {
newPath();
pw.println(cxy(x1,y1)+cxy(x2,y2)+cxy(x3,y3)+"c");
lx=x3;
ly=y3;
}
/**
* This extension appends a Bezier curve to the path. The curve
* extends from the current point to (x2,y2) using (x1,y1) and
* the end point as the Bezier control points.
* The new current point is (x2,y2)
*
* @param x1 Second control point
* @param y1 Second control point
* @param x2 Destination point
* @param y2 Destination point
*/
public void curveto2(double x1,double y1,double x2,double y2) {
newPath();
pw.println(cxy(x1,y1)+cxy(x2,y2)+"y");
lx=(float)x2;
ly=(float)y2;
}
// Arcs are horrible and complex. They are at the end of the
// file, because they are the largest. This is because, unlike
// Postscript, PDF doesn't have any arc operators, so we must
// implement them by converting into one or more Bezier curves
// (which is how Postscript does them internally).
/**
* This extension appends a Bezier curve to the path. The curve
* extends from the current point to (x2,y2) using (x1,y1) and
* the end point as the Bezier control points.
* The new current point is (x2,y2)
*
* @param x1 Second control point
* @param y1 Second control point
* @param x2 Destination point
* @param y2 Destination point
*/
public void curveto2(int x1,int y1,int x2,int y2) {
newPath();
pw.println(cxy(x1,y1)+cxy(x2,y2)+"y");
lx=x2;
ly=y2;
}
/**
* Converts the Java space dimension into pdf.
* @param w width
* @param h height
* @return String containing the coordinates in PDF space
*/
private String cwh(double w,double h) {
double nw=w,nh=h; // scratch
// switch(mediaRot) {
// case PageFormat.PORTRAIT:
// Portrait
//nw = w;
nh = -h;
// break;
//
// case PageFormat.LANDSCAPE:
// // Landscape
// nw = h;
// nh = w;
// break;
//
//// case 180:
//// // Inverse Portrait
//// nw = -w;
//// //nh = h;
//// break;
//
// case PageFormat.REVERSE_LANDSCAPE:
// // Seascape
// nw = -h;
// nh = -w;
// break;
// }
return ""+df.format(nw)+" "+df.format(nh)+" ";
}
/**
* Converts the Java space dimension into pdf.
* @param w width
* @param h height
* @return String containing the coordinates in PDF space
*/
private String cwh(int w,int h) {
return cwh((double)w,(double)h);
}
/**
* Converts the Java space coordinates into pdf.
* @param x coordinate
* @param y coordinate
* @return String containing the coordinates in PDF space
*/
private String cxy(double x, double y) {
return "" + df.format(x) + " " + df.format(y) + " ";
}
/**
* Converts the Java space coordinates into pdf.
* @param x coordinate
* @param y coordinate
* @return String containing the coordinates in PDF space
*/
private String cxy(int x,int y) {
return cxy((double)x,(double)y);
}
/**
* This releases any resources used by this Graphics object. You must use
* this method once finished with it. Leaving it open will leave the PDF
* stream in an inconsistent state, and will produce errors. If this was created with Graphics.create() then the parent instance
* can be used again. If not, then this closes the graphics operations for
* this page when used with PDFJob. When using PDFPage, you can create another fresh Graphics instance,
* which will draw over this one. Not implemented Draws a 3-D highlighted outline of the specified rectangle.
* The edges of the rectangle are highlighted so that they appear
* to be beveled and lit from the upper left corner.
* The colors used for the highlighting effect are determined based on
* the current color. The resulting rectangle covers an area that
* is width + 1 pixels wide by height + 1 pixels tall.
* Not implemented Draw's an image onto the page, with a backing colour. Draw's an image onto the page, with a backing colour. Draws an image onto the page. This method is implemented with ASCIIbase85 encoding and the
* zip stream deflater. It results in a stream that is anywhere
* from 3 to 10 times as big as the image. This obviously needs some
* improvement, but it works well for small images This is not yet supported.
*
* @param img The java.awt.Image
* @param dx1 coordinate on page
* @param dy1 coordinate on page
* @param dx2 coordinate on page
* @param dy2 coordinate on page
* @param sx1 coordinate on image
* @param sy1 coordinate on image
* @param sx2 coordinate on image
* @param sy2 coordinate on image
* @param bgcolor Background colour
* @param obs ImageObserver
* @return true if drawn
*/
public boolean drawImage(Image img,int dx1,int dy1,int dx2,
int dy2,int sx1,int sy1,int sx2,int sy2,
Color bgcolor,ImageObserver obs) {
return false;
}
//============ Clipping operations =======================
/**
* Draw's an image onto the page, with scaling
* This is not yet supported.
*
* @param img The java.awt.Image
* @param dx1 coordinate on page
* @param dy1 coordinate on page
* @param dx2 coordinate on page
* @param dy2 coordinate on page
* @param sx1 coordinate on image
* @param sy1 coordinate on image
* @param sx2 coordinate on image
* @param sy2 coordinate on image
* @param obs ImageObserver
* @return true if drawn
*/
public boolean drawImage(Image img,int dx1,int dy1,int dx2,
int dy2,int sx1,int sy1,int sx2,int sy2,
ImageObserver obs) {
// This shouldn't be too bad, just change the coordinate matrix
return false;
}
/**
* Draws a line between two coordinates.
*
* If the first coordinate is the same as the last one drawn
* (i.e. a previous drawLine, moveto, etc) it is ignored.
* @param x1 coordinate
* @param y1 coordinate
* @param x2 coordinate
* @param y2 coordinate
*/
public void drawLine(int x1,int y1,int x2,int y2) {
moveto(x1,y1);
lineto(x2,y2);
}
//============ Arcs operations ==============================
// These are the standard Graphics operators. They use the
// arc extension operators to achieve the affect.
/**
* Draws an oval This is not supported yet, as I have no idea what an
* AttributedCharacterIterator is.
* This method is new to the Java2 API.
*/
public void drawString(java.text.AttributedCharacterIterator aci,
float x,float y) {
}
/**
* Draws a string using a AttributedCharacterIterator.
* This is not supported yet, as I have no idea what an
* AttributedCharacterIterator is.
* This method is new to the Java2 API.
*/
public void drawString(java.text.AttributedCharacterIterator aci,
int x,int y) {
}
public void drawStringWithMode(String s, float x, float y, int mode) {
newTextBlock(x, y);
if (mode > -1) {
pw.println("" + mode + " Tr");
}
if (pdffont instanceof PDFEmbeddedFont) {
pw.print("[(");
pw.printRaw(PDFStringHelper.makeRawPDFString(s));
pw.println(")] TJ");
} else {
pw.print(PDFStringHelper.makePDFString(s));
pw.println(" Tj");
}
closeBlock();
}
@Override
public void drawString(String s, float x, float y) {
drawStringWithMode(s, x, y, -1);
}
/**
* This draws a string.
*
* @param s
* @oaran s String to draw
* @param x coordinate
* @param y coordinate
*/
@Override
public void drawString(String s,int x,int y) {
drawString(s, (float) x, (float) y);
}
public void drawTransparentString(String s, float x, float y) {
drawStringWithMode(s, x, y, 3);
}
/**
* This draws a transparent string.
*
* @oaran s String to draw
* @param x coordinate
* @param y coordinate
*/
public void drawTransparentString(String s, int x, int y) {
drawTransparentString(s, (float) x, (float) y);
}
/**
* @see Graphics2D#fill(Shape)
*/
public void fill(Shape s) {
followPath(s, FILL);
}
/**
* Not implemented Draws a filled oval This doesn't work correctly. Perhaps having some way of mapping
* the base 14 fonts to our own FontMetrics implementation?
* @param font The java.awt.Font to return the metrics for
* @return FontMetrics for a font
*/
public FontMetrics getFontMetrics(Font font) {
Frame dummy = new Frame();
dummy.addNotify();
Image image = dummy.createImage(100, 100);
if (image == null) {
System.err.println("getFontMetrics: image is null");
}
Graphics graphics = image.getGraphics();
return graphics.getFontMetrics(font);
}
/**
* @see Graphics2D#getFontRenderContext()
*/
public FontRenderContext getFontRenderContext() {
boolean antialias = RenderingHints.VALUE_TEXT_ANTIALIAS_ON.equals(getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING));
boolean fractions = RenderingHints.VALUE_FRACTIONALMETRICS_ON.equals(getRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS));
return new FontRenderContext(new AffineTransform(), antialias, fractions);
}
/**
* Returns the associated PDFPage for this graphic
* @return the associated PDFPage for this graphic
*/
public PDFPage getPage() {
return page;
}
/**
* Returns the current pen Colour
* @return the current pen Colour
*/
public Paint getPaint() {
return paint;
}
/**
* @param arg0 a key
* @return the rendering hint
*/
public Object getRenderingHint(Key arg0) {
return rhints.get(arg0);
}
/**
* @see Graphics2D#getRenderingHints()
*/
public RenderingHints getRenderingHints() {
return rhints;
}
/**
* @see Graphics2D#getStroke()
*/
public Stroke getStroke() {
return stroke;
}
/**
* @see Graphics2D#getTransform()
*/
public AffineTransform getTransform() {
return new AffineTransform(transform);
}
/**
* Returns the PrintWriter handling the underlying stream
* @return the PrintWriter handling the underlying stream
*/
public RawPrintWriter getWriter() {
return pw;
}
/**
* @see Graphics2D#hit(Rectangle, Shape, boolean)
*/
public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
if (onStroke) {
s = stroke.createStrokedShape(s);
}
Area area = new Area(s);
if (clip != null)
area.intersect(clip);
return area.intersects(rect.x, rect.y, rect.width, rect.height);
}
/**
* This initialises the stream by saving the current graphics state, and
* setting up the default line width (for us).
*
* It also sets up the instance ready for graphic operations and any
* optimisations.
*
* For child instances, the stream is already open, so this should keep
* things happy.
*/
private void init() {
PageFormat pf = page.getPageFormat();
// save graphics state (restored by dispose)
if(child) {
pw.print("q ");
}
// now initialise the instance
//setColor(Color.black);
paint = Color.black;
// possible: if parent.color is not black, then force black?
// must check to see what AWT does?
// Original User Space Transform (identity)
// Transform from Java Space to PDF Space
pTransform = new AffineTransform();
pTransform.translate(0, pf.getHeight());
pTransform.scale(1d, -1d);
// Combined Transform User->Java->PDF
setNewTranform(new AffineTransform());
// Set the line width
setStroke(DEF_STROKE);
}
/**
* This is called by PDFPage when creating a Graphcis instance.
* @param page The PDFPage to draw onto.
*/
protected void init(PDFPage page) {
this.page = page;
// We are the parent instance
child = false;
// Now create a stream to store the graphics in
PDFStream stream = new PDFStream();
// To view detail in uncompressed format comment out the next line
stream.setDeflate(true);
page.getPDFDocument().add(stream);
page.add(stream);
pw = new RawPrintWriter(stream.getOutputStream());
// initially, we are limited to the page size
clipRectangle = page.getImageableArea();
// finally initialise the stream
init();
}
/**
* This method is used internally by create() and by the PDFJob class
* @param page PDFPage to draw into
* @param pw PrintWriter to use
*/
protected void init(PDFPage page, RawPrintWriter pw) {
this.page = page;
this.pw = pw;
// In this case, we didn't create the stream (our parent did)
// so child is true (see dispose)
child = true;
// finally initialise the stream
init();
}
/**
* This adds a line segment to the current path
* @param x coordinate
* @param y coordinate
*/
public void lineto(double x,double y) {
newPath();
// no optimisation here as it may introduce errors on decimal coordinates.
pw.print(cxy(x,y)+"l ");
lx=(float)x;
ly=(float)y;
}
/**
* This adds a line segment to the current path
* @param x coordinate
* @param y coordinate
*/
public void lineto(int x,int y) {
newPath();
if(lx!=x && ly!=y)
pw.print(cxy(x,y)+"l ");
lx=x;
ly=y;
}
/**
* This moves the current drawing point.
* @param x coordinate
* @param y coordinate
*/
public void moveto(double x,double y) {
newPath();
// no optimisation here as it may introduce errors on decimal coordinates.
pw.print(cxy(x,y)+"m ");
lx=(float)x;
ly=(float)y;
}
/**
* This moves the current drawing point.
* @param x coordinate
* @param y coordinate
*/
public void moveto(int x,int y) {
newPath();
if(lx!=x || ly!=y)
pw.print(cxy(x,y)+"m ");
lx=x;
ly=y;
}
/**
* Functions that draw lines should start by calling this. It starts a
* new path unless inStroke is set, in that case it uses the existing path
*/
void newPath() {
if(inText) {
closeBlock();
}
if(!inStroke) {
if(pre_np!=null) {
pw.print(pre_np); // this is the prefix set by setOrientation()
pre_np = null;
}
pw.print("n ");
}
inText=false;
inStroke=true;
// an unlikely coordinate to fool the moveto() optimizer
lx = ly = -9999;
}
/**
* Functions that draw text should start by calling this. It starts a text
* block (accounting for media orientation) unless we are already in a Text
* block. It also handles if the font has been changed since the current text
* block was started, so your function will be current.
* In theory you could use setClip(), except that java.awt.Graphics only
* supports Rectangle with that method, so we will have an extra method.
*
* @param p Polygon to clip to
*/
public void clipPolygon(Polygon p) {
closeBlock(); // finish off any existing path
polygon(p.xpoints, p.ypoints, p.npoints);
closeBlock("W"); // clip to current path
clipRectangle = p.getBounds();
}
/**
* Clips to a set of coordinates
*
* @param x coordinate
* @param y coordinate
* @param w width
* @param h height
*/
public void clipRect(int x, int y, int w, int h) {
setClip(x, y, w, h);
}
/**
* All functions should call this to close any existing optimized blocks.
*/
void closeBlock() {
closeBlock("S");
}
/**
*
* This is used by code that use the path in any way other than Stroke (like
* Fill, close path & Stroke etc). Usually this is used internally.
* 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.
* Once complete, the child should be released with it's dispose() method
* which will restore the graphics state to it's parent.
* The new current point is (x2,y2)
*
* @param x1 Second control point
* @param y1 Second control point
* @param x2 Destination point
* @param y2 Destination point
*/
public void curveto(double x1, double y1, double x2, double y2) {
newPath();
pw.println(cxy(x1, y1) + cxy(x2, y2) + "v");
lx = (float) x2;
ly = (float) y2;
}
/**
* This extension appends a Bezier curve to the path. The curve extends from
* the current point to (x3,y3) using (x1,y1) and (x2,y2) as the Bezier
* control points.
*
* The new current point is (x3,y3)
*
* @param x1 First control point
* @param y1 First control point
* @param x2 Second control point
* @param y2 Second control point
* @param x3 Destination point
* @param y3 Destination point
*/
public void curveto(double x1, double y1, double x2, double y2, double x3, double y3) {
newPath();
pw.println(cxy(x1, y1) + cxy(x2, y2) + cxy(x3, y3) + "c");
lx = (float) x3;
ly = (float) y3;
}
/**
* This extension appends a Bezier curve to the path. The curve extends from
* the current point to (x2,y2) using the current point and (x1,y1) as the
* Bezier control points.
*
* The new current point is (x2,y2)
*
* @param x1 Second control point
* @param y1 Second control point
* @param x2 Destination point
* @param y2 Destination point
*/
public void curveto(int x1, int y1, int x2, int y2) {
newPath();
pw.println(cxy(x1, y1) + cxy(x2, y2) + "v");
lx = x2;
ly = y2;
}
/**
* This extension appends a Bezier curve to the path. The curve extends from
* the current point to (x3,y3) using (x1,y1) and (x2,y2) as the Bezier
* control points.
*
* The new current point is (x3,y3)
*
* @param x1 First control point
* @param y1 First control point
* @param x2 Second control point
* @param y2 Second control point
* @param x3 Destination point
* @param y3 Destination point
*/
public void curveto(int x1, int y1, int x2, int y2, int x3, int y3) {
newPath();
pw.println(cxy(x1, y1) + cxy(x2, y2) + cxy(x3, y3) + "c");
lx = x3;
ly = y3;
}
/**
* This extension appends a Bezier curve to the path. The curve extends from
* the current point to (x2,y2) using (x1,y1) and the end point as the
* Bezier control points.
*
* The new current point is (x2,y2)
*
* @param x1 Second control point
* @param y1 Second control point
* @param x2 Destination point
* @param y2 Destination point
*/
public void curveto2(double x1, double y1, double x2, double y2) {
newPath();
pw.println(cxy(x1, y1) + cxy(x2, y2) + "y");
lx = (float) x2;
ly = (float) y2;
}
// Arcs are horrible and complex. They are at the end of the
// file, because they are the largest. This is because, unlike
// Postscript, PDF doesn't have any arc operators, so we must
// implement them by converting into one or more Bezier curves
// (which is how Postscript does them internally).
/**
* This extension appends a Bezier curve to the path. The curve extends from
* the current point to (x2,y2) using (x1,y1) and the end point as the
* Bezier control points.
*
* The new current point is (x2,y2)
*
* @param x1 Second control point
* @param y1 Second control point
* @param x2 Destination point
* @param y2 Destination point
*/
public void curveto2(int x1, int y1, int x2, int y2) {
newPath();
pw.println(cxy(x1, y1) + cxy(x2, y2) + "y");
lx = x2;
ly = y2;
}
/**
* Converts the Java space dimension into pdf.
*
* @param w width
* @param h height
* @return String containing the coordinates in PDF space
*/
private String cwh(double w, double h) {
double nw = w, nh = h; // scratch
// switch(mediaRot) {
// case PageFormat.PORTRAIT:
// Portrait
//nw = w;
nh = -h;
// break;
//
// case PageFormat.LANDSCAPE:
// // Landscape
// nw = h;
// nh = w;
// break;
//
//// case 180:
//// // Inverse Portrait
//// nw = -w;
//// //nh = h;
//// break;
//
// case PageFormat.REVERSE_LANDSCAPE:
// // Seascape
// nw = -h;
// nh = -w;
// break;
// }
return "" + df.format(nw) + " " + df.format(nh) + " ";
}
/**
* Converts the Java space dimension into pdf.
*
* @param w width
* @param h height
* @return String containing the coordinates in PDF space
*/
private String cwh(int w, int h) {
return cwh((double) w, (double) h);
}
/**
* Converts the Java space coordinates into pdf.
*
* @param x coordinate
* @param y coordinate
* @return String containing the coordinates in PDF space
*/
private String cxy(double x, double y) {
return "" + df.format(x) + " " + df.format(y) + " ";
}
/**
* Converts the Java space coordinates into pdf.
*
* @param x coordinate
* @param y coordinate
* @return String containing the coordinates in PDF space
*/
private String cxy(int x, int y) {
return cxy((double) x, (double) y);
}
/**
*
* This releases any resources used by this Graphics object. You must use
* this method once finished with it. Leaving it open will leave the PDF
* stream in an inconsistent state, and will produce errors.
* If this was created with Graphics.create() then the parent instance can
* be used again. If not, then this closes the graphics operations for this
* page when used with PDFJob.
* When using PDFPage, you can create another fresh Graphics instance, which
* will draw over this one.
* Not implemented
* Draws a 3-D highlighted outline of the specified rectangle. The edges of
* the rectangle are highlighted so that they appear to be beveled and lit
* from the upper left corner. The colors used for the highlighting effect
* are determined based on the current color. The resulting rectangle covers
* an area that is width + 1 pixels wide by height + 1 pixels tall.
*
* Not implemented
* Draw's an image onto the page, with a backing colour.
* Draw's an image onto the page, with a backing colour.
* Draws an image onto the page.
* This method is implemented with ASCIIbase85 encoding and the zip stream
* deflater. It results in a stream that is anywhere from 3 to 10 times as
* big as the image. This obviously needs some improvement, but it works
* well for small images
* This is not yet supported.
*
* @param img The java.awt.Image
* @param dx1 coordinate on page
* @param dy1 coordinate on page
* @param dx2 coordinate on page
* @param dy2 coordinate on page
* @param sx1 coordinate on image
* @param sy1 coordinate on image
* @param sx2 coordinate on image
* @param sy2 coordinate on image
* @param bgcolor Background colour
* @param obs ImageObserver
* @return true if drawn
*/
public boolean drawImage(Image img, int dx1, int dy1, int dx2,
int dy2, int sx1, int sy1, int sx2, int sy2,
Color bgcolor, ImageObserver obs) {
return false;
}
//============ Clipping operations =======================
/**
* Draw's an image onto the page, with scaling
*
* This is not yet supported.
*
* @param img The java.awt.Image
* @param dx1 coordinate on page
* @param dy1 coordinate on page
* @param dx2 coordinate on page
* @param dy2 coordinate on page
* @param sx1 coordinate on image
* @param sy1 coordinate on image
* @param sx2 coordinate on image
* @param sy2 coordinate on image
* @param obs ImageObserver
* @return true if drawn
*/
public boolean drawImage(Image img, int dx1, int dy1, int dx2,
int dy2, int sx1, int sy1, int sx2, int sy2,
ImageObserver obs) {
// This shouldn't be too bad, just change the coordinate matrix
return false;
}
/**
* Draws a line between two coordinates.
*
* If the first coordinate is the same as the last one drawn (i.e. a
* previous drawLine, moveto, etc) it is ignored.
*
* @param x1 coordinate
* @param y1 coordinate
* @param x2 coordinate
* @param y2 coordinate
*/
public void drawLine(int x1, int y1, int x2, int y2) {
moveto(x1, y1);
lineto(x2, y2);
}
//============ Arcs operations ==============================
// These are the standard Graphics operators. They use the
// arc extension operators to achieve the affect.
/**
*
* Draws an oval
* This is not supported yet, as I have no idea what an
* AttributedCharacterIterator is.
*
* This method is new to the Java2 API.
*/
public void drawString(java.text.AttributedCharacterIterator aci,
float x, float y) {
}
/**
* Draws a string using a AttributedCharacterIterator.
*
* This is not supported yet, as I have no idea what an
* AttributedCharacterIterator is.
*
* This method is new to the Java2 API.
*/
public void drawString(java.text.AttributedCharacterIterator aci,
int x, int y) {
}
public void drawStringWithMode(String s, float x, float y, int mode) {
newTextBlock(x, y);
if (mode > -1) {
pw.println("" + mode + " Tr");
}
if (pdffont instanceof PDFEmbeddedFont) {
pw.print("[(");
pw.printRaw(PDFStringHelper.makeRawPDFString(s));
pw.println(")] TJ");
} else {
pw.print(PDFStringHelper.makePDFString(s));
pw.println(" Tj");
}
closeBlock();
}
@Override
public void drawString(String s, float x, float y) {
drawStringWithMode(s, x, y, -1);
}
/**
* This draws a string.
*
* @param s
* @oaran s String to draw
* @param x coordinate
* @param y coordinate
*/
@Override
public void drawString(String s, int x, int y) {
drawString(s, (float) x, (float) y);
}
public void drawTransparentString(String s, float x, float y) {
drawStringWithMode(s, x, y, 3);
}
/**
* This draws a transparent string.
*
* @oaran s String to draw
* @param x coordinate
* @param y coordinate
*/
public void drawTransparentString(String s, int x, int y) {
drawTransparentString(s, (float) x, (float) y);
}
/**
* @see Graphics2D#fill(Shape)
*/
public void fill(Shape s) {
followPath(s, FILL);
}
/**
*
* Not implemented
* Draws a filled oval
* This doesn't work correctly. Perhaps having some way of mapping the base
* 14 fonts to our own FontMetrics implementation?
*
* @param font The java.awt.Font to return the metrics for
* @return FontMetrics for a font
*/
public FontMetrics getFontMetrics(Font font) {
Frame dummy = new Frame();
dummy.addNotify();
Image image = dummy.createImage(100, 100);
if (image == null) {
System.err.println("getFontMetrics: image is null");
}
Graphics graphics = image.getGraphics();
return graphics.getFontMetrics(font);
}
/**
* @see Graphics2D#getFontRenderContext()
*/
public FontRenderContext getFontRenderContext() {
boolean antialias = RenderingHints.VALUE_TEXT_ANTIALIAS_ON.equals(getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING));
boolean fractions = RenderingHints.VALUE_FRACTIONALMETRICS_ON.equals(getRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS));
return new FontRenderContext(new AffineTransform(), antialias, fractions);
}
/**
* Returns the associated PDFPage for this graphic
*
* @return the associated PDFPage for this graphic
*/
public PDFPage getPage() {
return page;
}
/**
* Returns the current pen Colour
*
* @return the current pen Colour
*/
public Paint getPaint() {
return paint;
}
/**
* @param arg0 a key
* @return the rendering hint
*/
public Object getRenderingHint(Key arg0) {
return rhints.get(arg0);
}
/**
* @see Graphics2D#getRenderingHints()
*/
public RenderingHints getRenderingHints() {
return rhints;
}
/**
* @see Graphics2D#getStroke()
*/
public Stroke getStroke() {
return stroke;
}
/**
* @see Graphics2D#getTransform()
*/
public AffineTransform getTransform() {
return new AffineTransform(transform);
}
/**
* Returns the PrintWriter handling the underlying stream
*
* @return the PrintWriter handling the underlying stream
*/
public RawPrintWriter getWriter() {
return pw;
}
/**
* @see Graphics2D#hit(Rectangle, Shape, boolean)
*/
public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
if (onStroke) {
s = stroke.createStrokedShape(s);
}
Area area = new Area(s);
if (clip != null) {
area.intersect(clip);
}
return area.intersects(rect.x, rect.y, rect.width, rect.height);
}
/**
* This initialises the stream by saving the current graphics state, and
* setting up the default line width (for us).
*
* It also sets up the instance ready for graphic operations and any
* optimisations.
*
*
* For child instances, the stream is already open, so this should keep
* things happy.
*/
private void init() {
PageFormat pf = page.getPageFormat();
// save graphics state (restored by dispose)
if (child) {
pw.print("q ");
}
// now initialise the instance
//setColor(Color.black);
paint = Color.black;
// possible: if parent.color is not black, then force black?
// must check to see what AWT does?
// Original User Space Transform (identity)
// Transform from Java Space to PDF Space
pTransform = new AffineTransform();
pTransform.translate(0, pf.getHeight());
pTransform.scale(1d, -1d);
// Combined Transform User->Java->PDF
setNewTranform(new AffineTransform());
// Set the line width
setStroke(DEF_STROKE);
}
/**
* This is called by PDFPage when creating a Graphcis instance.
*
* @param page The PDFPage to draw onto.
*/
protected void init(PDFPage page) {
this.page = page;
// We are the parent instance
child = false;
// Now create a stream to store the graphics in
PDFStream stream = new PDFStream();
// To view detail in uncompressed format comment out the next line
stream.setDeflate(true);
page.getPDFDocument().add(stream);
page.add(stream);
pw = new RawPrintWriter(stream.getOutputStream());
// initially, we are limited to the page size
clipRectangle = page.getImageableArea();
// finally initialise the stream
init();
}
/**
* This method is used internally by create() and by the PDFJob class
*
* @param page PDFPage to draw into
* @param pw PrintWriter to use
*/
protected void init(PDFPage page, RawPrintWriter pw) {
this.page = page;
this.pw = pw;
// In this case, we didn't create the stream (our parent did)
// so child is true (see dispose)
child = true;
// finally initialise the stream
init();
}
/**
* This adds a line segment to the current path
*
* @param x coordinate
* @param y coordinate
*/
public void lineto(double x, double y) {
newPath();
// no optimisation here as it may introduce errors on decimal coordinates.
pw.print(cxy(x, y) + "l ");
lx = (float) x;
ly = (float) y;
}
/**
* This adds a line segment to the current path
*
* @param x coordinate
* @param y coordinate
*/
public void lineto(int x, int y) {
newPath();
if (lx != x && ly != y) {
pw.print(cxy(x, y) + "l ");
}
lx = x;
ly = y;
}
/**
* This moves the current drawing point.
*
* @param x coordinate
* @param y coordinate
*/
public void moveto(double x, double y) {
newPath();
// no optimisation here as it may introduce errors on decimal coordinates.
pw.print(cxy(x, y) + "m ");
lx = (float) x;
ly = (float) y;
}
/**
* This moves the current drawing point.
*
* @param x coordinate
* @param y coordinate
*/
public void moveto(int x, int y) {
newPath();
if (lx != x || ly != y) {
pw.print(cxy(x, y) + "m ");
}
lx = x;
ly = y;
}
/**
* Functions that draw lines should start by calling this. It starts a new
* path unless inStroke is set, in that case it uses the existing path
*/
void newPath() {
if (inText) {
closeBlock();
}
if (!inStroke) {
if (pre_np != null) {
pw.print(pre_np); // this is the prefix set by setOrientation()
pre_np = null;
}
pw.print("n ");
}
inText = false;
inStroke = true;
// an unlikely coordinate to fool the moveto() optimizer
lx = ly = -9999;
}
/**
*
* Functions that draw text should start by calling this. It starts a text
* block (accounting for media orientation) unless we are already in a Text
* block.
* It also handles if the font has been changed since the current text block
* was started, so your function will be current.
* Sets the clipping region to that of a Shape.
*
* @param s Shape to clip to.
*/
public void setClip(Shape s) {
Rectangle r = s.getBounds();
setClip(r.x, r.y, r.width, r.height);
}
/**
* Sets the color for drawing
*
* @param c Color to use
*/
public void setColor(Color c) {
setPaint(c);
}
/**
* @see Graphics2D#setComposite(Composite)
*/
public void setComposite(Composite comp) {
this.composite = comp;
}
/**
* This extension sets the line width to the default of 1mm which is what
* Java uses when drawing to a PrintJob.
*/
public void setDefaultLineWidth() {
closeBlock(); // draw any path before we change the line width
pw.println("1 w");
}
/**
* This sets the font.
*
* @param f java.awt.Font to set to.
*/
public void setFont(Font f) {
// optimize: Save some space if the font is already the current one.
if (font != f) {
font = f;
pdffont = page.getFont("/Type1", f.getName(), f.getStyle());
// mark the font as changed
newFont = true;
}
}
public void setExistingTtfFont(Font f) {
if (font != f) {
font = f;
pdffont = page.getFont("/TrueType", f.getName(), f.getStyle());
// mark the font as changed
newFont = true;
}
}
public void setTtfFont(Font f, File file) throws IOException {
if (font != f) {
font = f;
pdffont = page.getEmbeddedFont(f.getName(), f.getStyle(), file);
// mark the font as changed
newFont = true;
}
}
private void setLineCap(int cap) {
int lineCap = 0;
switch (cap) {
case BasicStroke.JOIN_MITER:
lineCap = 0;
break;
case BasicStroke.JOIN_ROUND:
lineCap = 1;
break;
case BasicStroke.JOIN_BEVEL:
lineCap = 2;
break;
}
if (this.lineCap != lineCap) {
closeBlock(); // draw any path before we change the line width
this.lineCap = lineCap;
pw.println("" + lineCap + " J");
}
}
private void setLineJoin(int join) {
int lineJoin = 0;
switch (join) {
case BasicStroke.JOIN_MITER:
lineJoin = 0;
break;
case BasicStroke.JOIN_ROUND:
lineJoin = 1;
break;
case BasicStroke.JOIN_BEVEL:
lineJoin = 2;
break;
}
if (this.lineJoin != lineJoin) {
closeBlock(); // draw any path before we change the line width
this.lineJoin = lineJoin;
pw.println("" + lineJoin + " j");
}
}
/**
* This extension allows the width of the drawn line to be set
*
* @param width Line width in pdf graphic units (points)
*/
public void setLineWidth(float width) {
if (width != this.lineWidth) {
closeBlock(); // draw any path before we change the line width
this.lineWidth = width;
pw.println("" + width + " w");
}
}
private void setMiterLimit(float limit) {
if (limit != this.miterLimit) {
closeBlock(); // draw any path before we change the line width
this.miterLimit = limit;
pw.println("" + limit + " M");
}
}
/**
* Sets the paint for drawing
*
* @param paint Paint to use
*/
public void setPaint(Paint paint) {
this.paint = paint;
if (paint instanceof Color) {
Color c = (Color) paint;
double r = ((double) c.getRed()) / 255.0;
double g = ((double) c.getGreen()) / 255.0;
double b = ((double) c.getBlue()) / 255.0;
closeBlock(); // This ensures any paths are drawn in the previous
// colours
pw.println("" + r + " " + g + " " + b + " rg "
+ r + " " + g + " " + b + " RG");
}
}
/**
* Not implemented, as this is not supported in the PDF specification.
*/
public void setPaintMode() {
}
/**
* Sets a rendering hint
*
* @param arg0
* @param arg1
*/
public void setRenderingHint(Key arg0, Object arg1) {
if (arg1 != null) {
rhints.put(arg0, arg1);
} else {
rhints.remove(arg0);
}
}
// Add Graphics2D methods.
/**
* @see Graphics2D#setRenderingHints(Map)
*/
public void setRenderingHints(Map, ?> hints) {
rhints.clear();
rhints.putAll(hints);
}
/**
* @see Graphics2D#setStroke(Stroke)
*/
public void setStroke(Stroke s) {
this.stroke = s;
if (stroke instanceof BasicStroke) {
BasicStroke bs = (BasicStroke) stroke;
setLineCap(bs.getEndCap());
setLineJoin(bs.getLineJoin());
setLineWidth(bs.getLineWidth());
setMiterLimit(bs.getMiterLimit());
// TODO: Line dash pattern
}
}
/**
* @see Graphics2D#setTransform(AffineTransform)
*/
public void setTransform(AffineTransform t) {
setNewTranform(new AffineTransform(t));
}
/**
* Not implemented, as this is not supported in the PDF specification.
*
* @param c1 Color to xor with
*/
public void setXORMode(Color c1) {
}
//============ Text operations =======================
/**
* @see Graphics2D#shear(double, double)
*/
public void shear(double shx, double shy) {
AffineTransform newTransform = new AffineTransform(transform);
newTransform.shear(shx, shy);
setNewTranform(newTransform);
}
/**
* @see Graphics2D#transform(AffineTransform)
*/
public void transform(AffineTransform tx) {
AffineTransform newTransform = new AffineTransform(transform);
newTransform.concatenate(tx);
setNewTranform(newTransform);
}
/**
* @see Graphics2D#translate(double, double)
*/
public void translate(double tx, double ty) {
AffineTransform newTransform = new AffineTransform(transform);
newTransform.translate(tx, ty);
setNewTranform(newTransform);
}
/**
* @see Graphics#translate(int, int)
*/
public void translate(int x, int y) {
translate((double) x, (double) y);
}
/**
* Converts the Java space coordinates into pdf text space.
*
* @param x coordinate
* @param y coordinate
* @param tx coordinate
* @param ty coordinate
* @return String containing the coordinates in PDF text space
*/
private String twh(float x, float y, float tx, float ty) {
float nx = x, ny = y;
float ntx = tx, nty = ty;
nx = (float) (x - tx);
ny = (float) (y - ty);
return "" + df.format(nx) + " " + df.format(ny) + " ";
}
/**
* Converts the Java space coordinates into pdf text space.
*
* @param x coordinate
* @param y coordinate
* @return String containing the coordinates in PDF text space
*/
private String txy(float x, float y) {
Point2D ptSrc = new Point2D.Float(x, y);
Point2D ptDst = new Point2D.Float();
pTransform.transform(ptSrc, ptDst);
return "" + df.format(ptDst.getX()) + " " + df.format(ptDst.getY()) + " ";
}
private void setNewTranform(AffineTransform t) {
closeBlock();
AffineTransform newTransform = new AffineTransform(t);
AffineTransform transformToSet = new AffineTransform(newTransform);
if (transform != null) {
AffineTransform realTransformWithPTransform = new AffineTransform(transform);
realTransformWithPTransform.preConcatenate(pTransform);
AffineTransform inverted = new AffineTransform(realTransformWithPTransform);
try {
inverted.invert();
} catch (NoninvertibleTransformException ex) {
Logger.getLogger(PDFGraphics.class.getName()).log(Level.SEVERE, null, ex);
}
AffineTransform newTransformWithPTransform = new AffineTransform(newTransform);
newTransformWithPTransform.preConcatenate(pTransform);
transformToSet = newTransformWithPTransform;
transformToSet.preConcatenate(inverted);
} else {
transformToSet.preConcatenate(pTransform);
}
transform = newTransform;
pw.println("" + df.format(transformToSet.getScaleX()) + " "
+ "" + df.format(transformToSet.getShearY()) + " "
+ "" + df.format(transformToSet.getShearX()) + " "
+ "" + df.format(transformToSet.getScaleY()) + " "
+ "" + df.format(transformToSet.getTranslateX()) + " "
+ "" + df.format(transformToSet.getTranslateY()) + " cm"
);
}
private void saveState() {
pw.println("q");
}
private void restoreState() {
pw.println("Q");
}
} // end class PDFGraphics
\ No newline at end of file
diff --git a/libsrc/gnujpdf/src/gnu/jpdf/PDFImage.java b/libsrc/gnujpdf/src/gnu/jpdf/PDFImage.java
index 79ac9ebf1..4888df7d3 100644
--- a/libsrc/gnujpdf/src/gnu/jpdf/PDFImage.java
+++ b/libsrc/gnujpdf/src/gnu/jpdf/PDFImage.java
@@ -26,18 +26,19 @@ import java.util.*;
import java.util.zip.*;
/**
- * This implements the Image XObject. Calling one of the
- *
+ * This implements the Image XObject. Calling one of the 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 Parts of this method contributed by Mathew Hreljac
+ * 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
+ * Parts of this method contributed by Mathew Hreljac
+ * Compression needs to be improved here Compression needs to be improved here
+ * Converts a pixel to a hex string Converts a pixel to a hex string This class stores details of the author, the PDF generator etc.
- * The values are accessible via the PDFDocument class.
+ * This class stores details of the author, the PDF generator etc. The values
+ * are accessible via the PDFDocument class. This class extends awt's PrintJob, to provide a simple method of writing
- * PDF documents.
+ * This class extends awt's PrintJob, to provide a simple method of writing PDF
+ * documents. 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.
+ * 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. 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. ezb 20011115 - Haven't done anything with templates yet, don't know
- * how/if they are implemented 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. 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. Use this constructor if you want to give the pdf document a name
- * other than the default of "PDF Doc" 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. 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. This writes the PDF document to the OutputStream, finishing the
- * document. 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. This new page will by default be oriented as a portrait Returns the page dimension How about a setPageDimension(Rectangle media) ?? This is the PDF (and Postscript) device resolution of 72 dpi
- * (equivalent to 1 point). 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. Returns the current PDFPage being worked on. Useful for working on
- * Annotations (like links), etc. Returns the current page number.
- * Useful if you need to include one in the document 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 specified region. This inner class extends PDFGraphics for the PrintJob. 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.
+ * 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. This method is used to make a new Graphics object without
- * going to a new page 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
+ *
+ * ezb 20011115 - Haven't done anything with templates yet, don't know
+ * how/if they are implemented
+ * 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.
+ * 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.
+ * Use this constructor if you want to give the pdf document a name other
+ * than the default of "PDF Doc"
+ * 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.
+ * 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.
+ * This writes the PDF document to the OutputStream, finishing the
+ * document.
+ * 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.
+ * This new page will by default be oriented as a portrait
+ * Returns the page dimension
+ * How about a setPageDimension(Rectangle media) ??
+ * This is the PDF (and Postscript) device resolution of 72 dpi (equivalent
+ * to 1 point).
+ * 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.
+ * Returns the current PDFPage being worked on. Useful for working on
+ * Annotations (like links), etc.
+ * Returns the current page number. Useful if you need to include one in the
+ * document
+ * 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 specified region.
+ * This inner class extends PDFGraphics for the PrintJob.
+ * 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.
+ * This method is used to make a new Graphics object without going to a
+ * new page
+ * 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
diff --git a/libsrc/gnujpdf/src/gnu/jpdf/PDFObject.java b/libsrc/gnujpdf/src/gnu/jpdf/PDFObject.java
index ce771ed2a..11c835e20 100644
--- a/libsrc/gnujpdf/src/gnu/jpdf/PDFObject.java
+++ b/libsrc/gnujpdf/src/gnu/jpdf/PDFObject.java
@@ -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;
- }
-
- /**
- * Writes the object to the output stream.
- * This method must be overidden. Note: It should not write any other objects, even if they are
- * it's Kids, as they will be written by the calling routine. 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.
- *
- * 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;
+ }
+
+ /**
+ *
+ * Writes the object to the output stream. This method must be
+ * overidden.
+ * Note: It should not write any other objects, even if they are it's
+ * Kids, as they will be written by the calling routine.
+ * 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.
+ *
+ *
+ * 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();
- }
}
diff --git a/libsrc/gnujpdf/src/gnu/jpdf/PDFOutline.java b/libsrc/gnujpdf/src/gnu/jpdf/PDFOutline.java
index e3546ad82..cb8034d73 100644
--- a/libsrc/gnujpdf/src/gnu/jpdf/PDFOutline.java
+++ b/libsrc/gnujpdf/src/gnu/jpdf/PDFOutline.java
@@ -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 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.
+ *
+ * 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.
*
- * Note: the coordiates are in Java space. They are converted to User
- * space.
+ *
+ * Note: the coordiates are in Java space. They are converted to User space.
*
- * 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.
+ *
+ * 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.
*
- * Note: the outline must have been added to the PDF document before
- * calling this method. Normally the other add methods are used.
+ *
+ * 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 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
+ * 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 This class defines a single page within a document. It is linked to a
- * single PDFGraphics object
+ * This class defines a single page within a document. It is linked to a single
+ * PDFGraphics object Once created, it is added to the document via the PDF.add() method.
- * (For Advanced use, via the PDFPages.add() method).
+ *
+ * Once created, it is added to the document via the PDF.add() method. (For
+ * Advanced use, via the PDFPages.add() method).
*
- * This defaults to a4 media.
+ *
+ * This defaults to a4 media.
*/
- public PDFPage()
- {
+ public PDFPage() {
super("/Page");
- pageFormat = DEF_FORMAT;
- contents = new Vector Normally, this should be done when the page is created, to avoid
+ *
+ * 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.
*
- * Note: Objects that describe contents must be added using this
+ *
+ * Note: 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.
*
- * As with other objects, the annotation must be added to the pdf
- * document using PDF.add() before adding to the page.
+ *
+ * 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 Note: The object must already exist in the PDF, as only the
- * object ID is stored.
+ *
+ * Note: 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.
*
- * Note: If the outline is not in the top level (ie below another
- * outline) then it must not be passed to this method.
+ *
+ * Note: If the outline is not in the top level (ie below another outline)
+ * then it must not 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
* 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.
* 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.
+ *
+ * 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.
- * By default, the stream will be compressed.
+ *
+ * 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).
- * By default, the stream will be compressed.
+ *
+ * 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.
*
- * 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.
+ *
+ * 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.
*
- * 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).
+ *
+ * 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
*
- * 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).
+ *
+ * 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);
}
-
+
}
diff --git a/libsrc/gnujpdf/src/gnu/jpdf/PDFStringHelper.java b/libsrc/gnujpdf/src/gnu/jpdf/PDFStringHelper.java
index 25b80b514..9a2fb9faf 100644
--- a/libsrc/gnujpdf/src/gnu/jpdf/PDFStringHelper.java
+++ b/libsrc/gnujpdf/src/gnu/jpdf/PDFStringHelper.java
@@ -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
+ * This class is used to hold the xref information in the PDF Trailer block. Basically, each object has an id, and an offset in the end file.
+ * Basically, each object has an id, and an offset in the end file. See the Adobe PDF Manual for more information. This class will
- * normally not be used directly by a developer
+ * See the Adobe PDF Manual for more information. This class will normally not
+ * be used directly by a developer This exception is thrown from {@link gnu.jpdf.BoundingBox} if the
- * string won't fit into the box
+ * This exception is thrown from {@link gnu.jpdf.BoundingBox} if the string
+ * won't fit into the box 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.
+ * 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.PrintWriter to attach to.
*/
protected PDFGraphics createGraphic(PDFPage page,
RawPrintWriter pw) {
PDFGraphics g = new PDFGraphics();
g.init(page,pw);
return g;
}
/**
* This extension appends a Bezier curve to the path. The curve
* extends from the current point to (x2,y2) using the current
* point and (x1,y1) as the Bezier control points.
* int value
* @param y an int value
* @param width an int value
* @param height an int value
* @param raised a boolean value
*/
public void draw3DRect(int x, int y,
int width, int height, boolean raised) {
// Not implemented
}
/**
* Draws an arc
* @param x coordinate
* @param y coordinate
* @param w width
* @param h height
* @param sa Start angle
* @param aa End angle
*/
public void drawArc(int x,int y,int w,int h,int sa,int aa) {
w=w>>1;
h=h>>1;
x+=w;
y+=h;
arc((double)x,(double)y,
(double)w,(double)h,
(double)-sa,(double)(-sa-aa),
false);
}
/**
* byte[] value
* @param offset an int value
* @param length an int value
* @param x an int value
* @param y an int value
*/
public void drawBytes(byte[] data, int offset, int length, int x, int y) {
}
//============ Optimizers =======================
/**
* @see Graphics2D#drawGlyphVector(GlyphVector, float, float)
*/
public void drawGlyphVector(GlyphVector g, float x, float y) {
Shape s = g.getOutline(x, y);
fill(s);
}
/**
* @see Graphics2D#drawImage(BufferedImage, BufferedImageOp, int, int)
*/
public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) {
BufferedImage result = img;
if (op != null) {
result = op.createCompatibleDestImage(img, img.getColorModel());
result = op.filter(img, result);
}
drawImage(result, x, y, null);
}
/**
* @see Graphics2D#drawImage(Image, AffineTransform, ImageObserver)
*/
public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) {
// return drawImage(img, null, xform, null, obs);
return true;
}
/**
* int value
* @param y an int value
* @param width an int value
* @param height an int value
* @param raised a boolean value
*/
public void fill3DRect(int x, int y,
int width, int height, boolean raised) {
// Not implemented
}
/**
* Fills an arc, joining the start and end coordinates
* @param x coordinate
* @param y coordinate
* @param w width
* @param h height
* @param sa Start angle
* @param aa End angle
*/
public void fillArc(int x,int y,int w,int h,int sa,int aa) {
// here we fool the optimizer. We force any open path to be closed,
// then draw the arc. Finally, as the optimizer hasn't stroke'd the
// path, we close and fill it, and mark the Stroke as closed.
//
// Note: The lineto to the centre of the object is required, because
// the fill only fills the arc. Skipping this includes an extra
// chord, which isn't correct. Peter May 31 2000
closeBlock();
drawArc(x,y,w,h,sa,aa);
lineto(x+(w>>1),y+(h>>1));
closeBlock("b"); // closepath and fill
}
//============ Extension operations ==============================
// These are extensions, and provide access to PDF Specific
// operators.
/**
* PrintWriter to attach to.
*/
protected PDFGraphics createGraphic(PDFPage page,
RawPrintWriter pw) {
PDFGraphics g = new PDFGraphics();
g.init(page, pw);
return g;
}
/**
* This extension appends a Bezier curve to the path. The curve extends from
* the current point to (x2,y2) using the current point and (x1,y1) as the
* Bezier control points.
* int value
* @param y an int value
* @param width an int value
* @param height an int value
* @param raised a boolean value
*/
public void draw3DRect(int x, int y,
int width, int height, boolean raised) {
// Not implemented
}
/**
* Draws an arc
*
* @param x coordinate
* @param y coordinate
* @param w width
* @param h height
* @param sa Start angle
* @param aa End angle
*/
public void drawArc(int x, int y, int w, int h, int sa, int aa) {
w = w >> 1;
h = h >> 1;
x += w;
y += h;
arc((double) x, (double) y,
(double) w, (double) h,
(double) -sa, (double) (-sa - aa),
false);
}
/**
* byte[] value
* @param offset an int value
* @param length an int value
* @param x an int value
* @param y an int value
*/
public void drawBytes(byte[] data, int offset, int length, int x, int y) {
}
//============ Optimizers =======================
/**
* @see Graphics2D#drawGlyphVector(GlyphVector, float, float)
*/
public void drawGlyphVector(GlyphVector g, float x, float y) {
Shape s = g.getOutline(x, y);
fill(s);
}
/**
* @see Graphics2D#drawImage(BufferedImage, BufferedImageOp, int, int)
*/
public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) {
BufferedImage result = img;
if (op != null) {
result = op.createCompatibleDestImage(img, img.getColorModel());
result = op.filter(img, result);
}
drawImage(result, x, y, null);
}
/**
* @see Graphics2D#drawImage(Image, AffineTransform, ImageObserver)
*/
public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) {
// return drawImage(img, null, xform, null, obs);
return true;
}
/**
* int value
* @param y an int value
* @param width an int value
* @param height an int value
* @param raised a boolean value
*/
public void fill3DRect(int x, int y,
int width, int height, boolean raised) {
// Not implemented
}
/**
* Fills an arc, joining the start and end coordinates
*
* @param x coordinate
* @param y coordinate
* @param w width
* @param h height
* @param sa Start angle
* @param aa End angle
*/
public void fillArc(int x, int y, int w, int h, int sa, int aa) {
// here we fool the optimizer. We force any open path to be closed,
// then draw the arc. Finally, as the optimizer hasn't stroke'd the
// path, we close and fill it, and mark the Stroke as closed.
//
// Note: The lineto to the centre of the object is required, because
// the fill only fills the arc. Skipping this includes an extra
// chord, which isn't correct. Peter May 31 2000
closeBlock();
drawArc(x, y, w, h, sa, aa);
lineto(x + (w >> 1), y + (h >> 1));
closeBlock("b"); // closepath and fill
}
//============ Extension operations ==============================
// These are extensions, and provide access to PDF Specific
// operators.
/**
* drawImage methods of PDFGraphics 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.drawImage
+ * methods of PDFGraphics 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.PDFImage instance.
- *
- */
- public PDFImage()
- {
- super("/XObject");
- }
-
- /**
- * Creates a new PDFImage instance.
- *
- * @param img an Image value
- */
- public PDFImage(Image img) {
- this();
- setImage(img, 0, 0, img.getWidth(this), img.getHeight(this), this);
- }
-
- /**
- * Creates a new PDFImage instance.
- *
- * @param img an Image value
- * @param x an int value
- * @param y an int value
- * @param w an int value
- * @param h an int value
- * @param obs an ImageObserver 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 String value
- */
- public void setName(String n) {
- name = n;
- }
-
- /**
- * Get the name
- *
- * @return a String value
- */
- public String getName() {
- return name;
- }
-
- /**
- * Set the image
- *
- * @param img an Image value
- * @param x an int value
- * @param y an int value
- * @param w an int value
- * @param h an int value
- * @param obs an ImageObserver value
- */
- public void setImage(Image img,int x,int y,int w,int h,ImageObserver obs) {
- this.img = img;
- width = w;
- height = h;
- }
-
-
-
- /**
- * String value
- * @return a String 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 PDFImage 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 PDFImage instance.
+ *
+ * @param img an Image 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 PDFImage instance.
+ *
+ * @param img an Image value
+ * @param x an int value
+ * @param y an int value
+ * @param w an int value
+ * @param h an int value
+ * @param obs an ImageObserver 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);
}
- VectorString value
+ */
+ public void setName(String n) {
+ name = n;
+ }
- /**
- * Writes the image to the stream
- *
- * @param os an OutputStream 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 String value
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Set the image
+ *
+ * @param img an Image value
+ * @param x an int value
+ * @param y an int value
+ * @param w an int value
+ * @param h an int value
+ * @param obs an ImageObserver value
+ */
+ public void setImage(Image img, int x, int y, int w, int h, ImageObserver obs) {
+ this.img = img;
+ width = w;
+ height = h;
+ }
+
+ /**
+ * String value
+ * @return a String 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";
+ }
+ VectorOutputStream 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
+ /**
+ * int value
+ * @param y an int value
+ * @param p an int value
+ * @return a String 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 imageUpdate method here.
+ *
+ * @param img an Image value
+ * @param infoflags an int value
+ * @param x an int value
+ * @param y an int value
+ * @param w an int value
+ * @param h an int value
+ * @return a boolean 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!
- }
-
-
-
- /**
- * int value
- * @param y an int value
- * @param p an int value
- * @return a String 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 imageUpdate method here.
- *
- * @param img an Image value
- * @param infoflags an int value
- * @param x an int value
- * @param y an int value
- * @param w an int value
- * @param h an int value
- * @return a boolean 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
diff --git a/libsrc/gnujpdf/src/gnu/jpdf/PDFInfo.java b/libsrc/gnujpdf/src/gnu/jpdf/PDFInfo.java
index 45b554b44..2f80b6a9d 100644
--- a/libsrc/gnujpdf/src/gnu/jpdf/PDFInfo.java
+++ b/libsrc/gnujpdf/src/gnu/jpdf/PDFInfo.java
@@ -24,170 +24,176 @@ package gnu.jpdf;
import java.io.*;
/**
- * OutputStream to use for the pdf output
- */
- public PDFJob(OutputStream os) {
- this(os, "PDF Doc");
- }
-
- /**
- * OutputStream to use for the pdf output
- * @param title a String value
- */
- public PDFJob(OutputStream os, String title) {
- this.os = os;
- this.pdfDocument = new PDFDocument();
- pagenum = 0;
- pdfDocument.getPDFInfo().setTitle(title);
- }
-
-
- /**
- * int Orientation of the new page,
- * as defined in PDFPage
- * @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);
- }
-
-
- /**
- * Graphics object to draw to.
- */
- public Graphics getGraphics() {
- return getGraphics(PageFormat.PORTRAIT);
- }
-
-
-
- /**
- * Dimension instance, the size of the page
- */
- public Dimension getPageDimension() {
- if (page == null) {
- System.err.println("PDFJob.getPageDimension(), page is null");
- }
- return page.getDimension();
- }
-
-
- /**
- * int, the resolution in pixels per inch
- */
- public int getPageResolution() {
- return 72;
- }
-
-
-
-
- /**
- * PDFPage currently being constructed
- */
- public PDFPage getCurrentPage() {
- return page;
- }
-
- /**
- * int current page number
- */
- public int getCurrentPageNumber() {
- return pagenum;
- }
-
-
-
- /**
- * String, the title of the Outline
- * @return a PDFOutline object that was created,
- * for adding sub-outline's if required.
- */
- public PDFOutline addOutline(String title) {
- return page.addOutline(title);
- }
-
- /**
- * PDFOutline 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);
- }
-
-
- /**
- * OutputStream to use for the pdf output
*/
- public PrintJob getPrintJob() {
- return (PrintJob)job;
+ public PDFJob(OutputStream os) {
+ this(os, "PDF Doc");
}
-
- } // end inner class graphic
-
+
+ /**
+ * OutputStream to use for the pdf output
+ * @param title a String value
+ */
+ public PDFJob(OutputStream os, String title) {
+ this.os = os;
+ this.pdfDocument = new PDFDocument();
+ pagenum = 0;
+ pdfDocument.getPDFInfo().setTitle(title);
+ }
+
+ /**
+ * int Orientation of the new page, as
+ * defined in PDFPage
+ * @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);
+ }
+
+ /**
+ * Graphics object to draw to.
+ */
+ public Graphics getGraphics() {
+ return getGraphics(PageFormat.PORTRAIT);
+ }
+
+ /**
+ * Dimension instance, the size of the page
+ */
+ public Dimension getPageDimension() {
+ if (page == null) {
+ System.err.println("PDFJob.getPageDimension(), page is null");
+ }
+ return page.getDimension();
+ }
+
+ /**
+ * int, the resolution in pixels per inch
+ */
+ public int getPageResolution() {
+ return 72;
+ }
+
+ /**
+ * PDFPage currently being constructed
+ */
+ public PDFPage getCurrentPage() {
+ return page;
+ }
+
+ /**
+ * int current page number
+ */
+ public int getCurrentPageNumber() {
+ return pagenum;
+ }
+
+ /**
+ * String, the title of the Outline
+ * @return a PDFOutline object that was created, for adding
+ * sub-outline's if required.
+ */
+ public PDFOutline addOutline(String title) {
+ return page.addOutline(title);
+ }
+
+ /**
+ * PDFOutline 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);
+ }
+
+ /**
+ * PDFPrinterJob.
- */
- public PDFPrinterJob() {
- attributes = new HashPrintRequestAttributeSet();
- info = new PDFInfo();
- pageFormat = new PageFormat(); // default page format.
- setJobName("Java Printing");
- }
+ /**
+ * Initializes a new instance of PDFPrinterJob.
+ */
+ 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();
+ }
}
diff --git a/libsrc/gnujpdf/src/gnu/jpdf/PDFStream.java b/libsrc/gnujpdf/src/gnu/jpdf/PDFStream.java
index 3c2162208..611b0673b 100644
--- a/libsrc/gnujpdf/src/gnu/jpdf/PDFStream.java
+++ b/libsrc/gnujpdf/src/gnu/jpdf/PDFStream.java
@@ -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.
*
- * String, some informative message for the logs
- */
- public StringTooLongException(String msg) {
- this.msg = msg;
- }
+ /**
+ * String, 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
diff --git a/libsrc/gnujpdf/src/gnu/jpdf/Test.java b/libsrc/gnujpdf/src/gnu/jpdf/Test.java
index ead5dbf11..ac1475d71 100644
--- a/libsrc/gnujpdf/src/gnu/jpdf/Test.java
+++ b/libsrc/gnujpdf/src/gnu/jpdf/Test.java
@@ -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();
}
}
diff --git a/libsrc/gnujpdf/src/gnu/jpdf/TtfParser.java b/libsrc/gnujpdf/src/gnu/jpdf/TtfParser.java
index 0fbdee710..ec3abe9e8 100644
--- a/libsrc/gnujpdf/src/gnu/jpdf/TtfParser.java
+++ b/libsrc/gnujpdf/src/gnu/jpdf/TtfParser.java
@@ -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);