/*\r
-Copyright Paul James Mutton, 2001-2004, http://www.jibble.org/\r
+ Copyright Paul James Mutton, 2001-2004, http://www.jibble.org/\r
\r
-This file is part of EpsGraphics2D.\r
+ This file is part of EpsGraphics2D.\r
\r
-This software is dual-licensed, allowing you to choose between the GNU\r
-General Public License (GPL) and the www.jibble.org Commercial License.\r
-Since the GPL may be too restrictive for use in a proprietary application,\r
-a commercial license is also provided. Full license information can be\r
-found at http://www.jibble.org/licenses/\r
+ This software is dual-licensed, allowing you to choose between the GNU\r
+ General Public License (GPL) and the www.jibble.org Commercial License.\r
+ Since the GPL may be too restrictive for use in a proprietary application,\r
+ a commercial license is also provided. Full license information can be\r
+ found at http://www.jibble.org/licenses/\r
\r
-$Author$\r
-$Id$\r
+ $Author$\r
+ $Id$\r
\r
-*/\r
+ */\r
\r
package org.jibble.epsgraphics;\r
\r
-import java.awt.*;\r
-import java.awt.image.*;\r
-import java.awt.image.renderable.*;\r
-import java.awt.geom.*;\r
import java.io.*;\r
import java.text.*;\r
-import java.awt.font.*;\r
import java.util.*;\r
\r
+import java.awt.*;\r
+import java.awt.font.*;\r
+import java.awt.geom.*;\r
+import java.awt.image.*;\r
+import java.awt.image.renderable.*;\r
\r
/**\r
* EpsGraphics2D is suitable for creating high quality EPS graphics for\r
* <a href="http://www.jibble.org/">http://www.jibble.org/</a>\r
*\r
*/\r
-public class EpsGraphics2D extends java.awt.Graphics2D {\r
-\r
-\r
- public static final String VERSION = "0.8.8";\r
-\r
-\r
- /**\r
- * Constructs a new EPS document that is initially empty and can be\r
- * drawn on like a Graphics2D object. The EPS document is stored in\r
- * memory.\r
- */\r
- public EpsGraphics2D() {\r
- this("Untitled");\r
- }\r
-\r
-\r
- /**\r
- * Constructs a new EPS document that is initially empty and can be\r
- * drawn on like a Graphics2D object. The EPS document is stored in\r
- * memory.\r
- */\r
- public EpsGraphics2D(String title) {\r
- _document = new EpsDocument(title);\r
- _backgroundColor = Color.white;\r
- _clip = null;\r
- _transform = new AffineTransform();\r
- _clipTransform = new AffineTransform();\r
- _accurateTextMode = true;\r
- setColor(Color.black);\r
- setPaint(Color.black);\r
- setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR));\r
- setFont(Font.decode(null));\r
- setStroke(new BasicStroke());\r
- }\r
-\r
-\r
- /**\r
- * Constructs a new EPS document that is initially empty and can be\r
- * drawn on like a Graphics2D object. The EPS document is written to\r
- * the file as it goes, which reduces memory usage. The bounding box of\r
- * the document is fixed and specified at construction time by\r
- * minX,minY,maxX,maxY. The file is flushed and closed when the close()\r
- * method is called.\r
- */\r
- public EpsGraphics2D(String title, File file, int minX, int minY, int maxX, int maxY) throws IOException {\r
- this(title, new FileOutputStream(file), minX, minY, maxX, maxY);\r
- }\r
-\r
-\r
- /**\r
- * Constructs a new EPS document that is initially empty and can be\r
- * drawn on like a Graphics2D object. The EPS document is written to\r
- * the output stream as it goes, which reduces memory usage. The\r
- * bounding box of the document is fixed and specified at construction\r
- * time by minX,minY,maxX,maxY. The output stream is flushed and closed\r
- * when the close() method is called.\r
- */\r
- public EpsGraphics2D(String title, OutputStream outputStream, int minX, int minY, int maxX, int maxY) throws IOException {\r
- this(title);\r
- _document = new EpsDocument(title, outputStream, minX, minY, maxX, maxY);\r
- }\r
-\r
-\r
- /**\r
- * Constructs a new EpsGraphics2D instance that is a copy of the\r
- * supplied argument and points at the same EpsDocument.\r
- */\r
- protected EpsGraphics2D(EpsGraphics2D g) {\r
- _document = g._document;\r
- _backgroundColor = g._backgroundColor;\r
- _clip = g._clip;\r
- _clipTransform = (AffineTransform) g._clipTransform.clone();\r
- _transform = (AffineTransform) g._transform.clone();\r
- _color = g._color;\r
- _paint = g._paint;\r
- _composite = g._composite;\r
- _font = g._font;\r
- _stroke = g._stroke;\r
- _accurateTextMode = g._accurateTextMode;\r
- }\r
-\r
-\r
- /**\r
- * This method is called to indicate that a particular method is not\r
- * supported yet. The stack trace is printed to the standard output.\r
- */\r
- private void methodNotSupported() {\r
- EpsException e = new EpsException("Method not currently supported by EpsGraphics2D version " + VERSION);\r
- e.printStackTrace(System.err);\r
- }\r
-\r
-\r
- /////////////// Specialist methods ///////////////////////\r
-\r
-\r
- /**\r
- * Sets whether to use accurate text mode when rendering text in EPS.\r
- * This is enabled (true) by default. When accurate text mode is used,\r
- * all text will be rendered in EPS to appear exactly the same as it\r
- * would do when drawn with a Graphics2D context. With accurate text\r
- * mode enabled, it is not necessary for the EPS viewer to have the\r
- * required font installed.\r
- * <p>\r
- * Turning off accurate text mode will require the EPS viewer to have\r
- * the necessary fonts installed. If you are using a lot of text, you\r
- * will find that this significantly reduces the file size of your EPS\r
- * documents. AffineTransforms can only affect the starting point of\r
- * text using this simpler text mode - all text will be horizontal.\r
- */\r
- public void setAccurateTextMode(boolean b) {\r
- _accurateTextMode = b;\r
- }\r
-\r
-\r
- /**\r
- * Returns whether accurate text mode is being used.\r
- */\r
- public boolean getAccurateTextMode() {\r
- return _accurateTextMode;\r
- }\r
-\r
-\r
- /**\r
- * Flushes the buffered contents of this EPS document to the underlying\r
- * OutputStream it is being written to.\r
- */\r
- public void flush() throws IOException {\r
- _document.flush();\r
- }\r
-\r
-\r
- /**\r
- * Closes the EPS file being output to the underlying OutputStream.\r
- * The OutputStream is automatically flushed before being closed.\r
- * If you forget to do this, the file may be incomplete.\r
- */\r
- public void close() throws IOException {\r
- flush();\r
- _document.close();\r
- }\r
-\r
-\r
- /**\r
- * Appends a line to the EpsDocument.\r
- */\r
- private void append(String line) {\r
- _document.append(this, line);\r
- }\r
-\r
-\r
- /**\r
- * Returns the point after it has been transformed by the transformation.\r
- */\r
- private Point2D transform(float x, float y) {\r
- Point2D result = new Point2D.Float(x, y);\r
- result = _transform.transform(result, result);\r
- result.setLocation(result.getX(), -result.getY());\r
- return result;\r
- }\r
-\r
-\r
- /**\r
- * Appends the commands required to draw a shape on the EPS document.\r
- */\r
- private void draw(Shape s, String action) {\r
-\r
- if (s != null) {\r
-\r
- //Rectangle2D userBounds = s.getBounds2D();\r
- if (!_transform.isIdentity()) {\r
- s = _transform.createTransformedShape(s);\r
- }\r
-\r
- // Update the bounds.\r
- if (!action.equals("clip")) {\r
- Rectangle2D shapeBounds = s.getBounds2D();\r
- Rectangle2D visibleBounds = shapeBounds;\r
- if (_clip != null) {\r
- Rectangle2D clipBounds = _clip.getBounds2D();\r
- visibleBounds = shapeBounds.createIntersection(clipBounds);\r
- }\r
- float lineRadius = _stroke.getLineWidth() / 2;\r
- float minX = (float) visibleBounds.getMinX() - lineRadius;\r
- float minY = (float) visibleBounds.getMinY() - lineRadius;\r
- float maxX = (float) visibleBounds.getMaxX() + lineRadius;\r
- float maxY = (float) visibleBounds.getMaxY() + lineRadius;\r
- _document.updateBounds(minX, -minY);\r
- _document.updateBounds(maxX, -maxY);\r
- }\r
-\r
- append("newpath");\r
- int type = 0;\r
- float[] coords = new float[6];\r
- PathIterator it = s.getPathIterator(null);\r
- float x0 = 0;\r
- float y0 = 0;\r
- int count = 0;\r
- while (!it.isDone()) {\r
- type = it.currentSegment(coords);\r
- float x1 = coords[0];\r
- float y1 = -coords[1];\r
- float x2 = coords[2];\r
- float y2 = -coords[3];\r
- float x3 = coords[4];\r
- float y3 = -coords[5];\r
-\r
- if (type == PathIterator.SEG_CLOSE) {\r
- append("closepath");\r
- count++;\r
- }\r
- else if (type == PathIterator.SEG_CUBICTO) {\r
- append(x1 + " " + y1 + " " + x2 + " " + y2 + " " + x3 + " " + y3 + " curveto");\r
- count++;\r
- x0 = x3;\r
- y0 = y3;\r
- }\r
- else if (type == PathIterator.SEG_LINETO) {\r
- append(x1 + " " + y1 + " lineto");\r
- count++;\r
- x0 = x1;\r
- y0 = y1;\r
- }\r
- else if (type == PathIterator.SEG_MOVETO) {\r
- append(x1 + " " + y1 + " moveto");\r
- count++;\r
- x0 = x1;\r
- y0 = y1;\r
- }\r
- else if (type == PathIterator.SEG_QUADTO) {\r
- // Convert the quad curve into a cubic.\r
- float _x1 = x0 + 2 / 3f * (x1 - x0);\r
- float _y1 = y0 + 2 / 3f * (y1 - y0);\r
- float _x2 = x1 + 1 / 3f * (x2 - x1);\r
- float _y2 = y1 + 1 / 3f * (y2 - y1);\r
- float _x3 = x2;\r
- float _y3 = y2;\r
- append(_x1 + " " + _y1 + " " + _x2 + " " + _y2 + " " + _x3 + " " + _y3 + " curveto");\r
- count++;\r
- x0 = _x3;\r
- y0 = _y3;\r
- }\r
- else if (type == PathIterator.WIND_EVEN_ODD) {\r
- // Ignore.\r
- }\r
- else if (type == PathIterator.WIND_NON_ZERO) {\r
- // Ignore.\r
- }\r
- it.next();\r
- }\r
- append(action);\r
- append("newpath");\r
+public class EpsGraphics2D\r
+ extends java.awt.Graphics2D\r
+{\r
+\r
+ public static final String VERSION = "0.8.8";\r
+\r
+ /**\r
+ * Constructs a new EPS document that is initially empty and can be\r
+ * drawn on like a Graphics2D object. The EPS document is stored in\r
+ * memory.\r
+ */\r
+ public EpsGraphics2D()\r
+ {\r
+ this("Untitled");\r
+ }\r
+\r
+ /**\r
+ * Constructs a new EPS document that is initially empty and can be\r
+ * drawn on like a Graphics2D object. The EPS document is stored in\r
+ * memory.\r
+ */\r
+ public EpsGraphics2D(String title)\r
+ {\r
+ _document = new EpsDocument(title);\r
+ _backgroundColor = Color.white;\r
+ _clip = null;\r
+ _transform = new AffineTransform();\r
+ _clipTransform = new AffineTransform();\r
+ _accurateTextMode = true;\r
+ setColor(Color.black);\r
+ setPaint(Color.black);\r
+ setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR));\r
+ setFont(Font.decode(null));\r
+ setStroke(new BasicStroke());\r
+ }\r
+\r
+ /**\r
+ * Constructs a new EPS document that is initially empty and can be\r
+ * drawn on like a Graphics2D object. The EPS document is written to\r
+ * the file as it goes, which reduces memory usage. The bounding box of\r
+ * the document is fixed and specified at construction time by\r
+ * minX,minY,maxX,maxY. The file is flushed and closed when the close()\r
+ * method is called.\r
+ */\r
+ public EpsGraphics2D(String title, File file, int minX, int minY, int maxX,\r
+ int maxY)\r
+ throws IOException\r
+ {\r
+ this(title, new FileOutputStream(file), minX, minY, maxX, maxY);\r
+ }\r
+\r
+ /**\r
+ * Constructs a new EPS document that is initially empty and can be\r
+ * drawn on like a Graphics2D object. The EPS document is written to\r
+ * the output stream as it goes, which reduces memory usage. The\r
+ * bounding box of the document is fixed and specified at construction\r
+ * time by minX,minY,maxX,maxY. The output stream is flushed and closed\r
+ * when the close() method is called.\r
+ */\r
+ public EpsGraphics2D(String title, OutputStream outputStream, int minX,\r
+ int minY, int maxX, int maxY)\r
+ throws IOException\r
+ {\r
+ this(title);\r
+ _document = new EpsDocument(title, outputStream, minX, minY, maxX, maxY);\r
+ }\r
+\r
+ /**\r
+ * Constructs a new EpsGraphics2D instance that is a copy of the\r
+ * supplied argument and points at the same EpsDocument.\r
+ */\r
+ protected EpsGraphics2D(EpsGraphics2D g)\r
+ {\r
+ _document = g._document;\r
+ _backgroundColor = g._backgroundColor;\r
+ _clip = g._clip;\r
+ _clipTransform = (AffineTransform) g._clipTransform.clone();\r
+ _transform = (AffineTransform) g._transform.clone();\r
+ _color = g._color;\r
+ _paint = g._paint;\r
+ _composite = g._composite;\r
+ _font = g._font;\r
+ _stroke = g._stroke;\r
+ _accurateTextMode = g._accurateTextMode;\r
+ }\r
+\r
+ /**\r
+ * This method is called to indicate that a particular method is not\r
+ * supported yet. The stack trace is printed to the standard output.\r
+ */\r
+ private void methodNotSupported()\r
+ {\r
+ EpsException e = new EpsException(\r
+ "Method not currently supported by EpsGraphics2D version " + VERSION);\r
+ e.printStackTrace(System.err);\r
+ }\r
+\r
+ /////////////// Specialist methods ///////////////////////\r
+\r
+\r
+ /**\r
+ * Sets whether to use accurate text mode when rendering text in EPS.\r
+ * This is enabled (true) by default. When accurate text mode is used,\r
+ * all text will be rendered in EPS to appear exactly the same as it\r
+ * would do when drawn with a Graphics2D context. With accurate text\r
+ * mode enabled, it is not necessary for the EPS viewer to have the\r
+ * required font installed.\r
+ * <p>\r
+ * Turning off accurate text mode will require the EPS viewer to have\r
+ * the necessary fonts installed. If you are using a lot of text, you\r
+ * will find that this significantly reduces the file size of your EPS\r
+ * documents. AffineTransforms can only affect the starting point of\r
+ * text using this simpler text mode - all text will be horizontal.\r
+ */\r
+ public void setAccurateTextMode(boolean b)\r
+ {\r
+ _accurateTextMode = b;\r
+ }\r
+\r
+ /**\r
+ * Returns whether accurate text mode is being used.\r
+ */\r
+ public boolean getAccurateTextMode()\r
+ {\r
+ return _accurateTextMode;\r
+ }\r
+\r
+ /**\r
+ * Flushes the buffered contents of this EPS document to the underlying\r
+ * OutputStream it is being written to.\r
+ */\r
+ public void flush()\r
+ throws IOException\r
+ {\r
+ _document.flush();\r
+ }\r
+\r
+ /**\r
+ * Closes the EPS file being output to the underlying OutputStream.\r
+ * The OutputStream is automatically flushed before being closed.\r
+ * If you forget to do this, the file may be incomplete.\r
+ */\r
+ public void close()\r
+ throws IOException\r
+ {\r
+ flush();\r
+ _document.close();\r
+ }\r
+\r
+ /**\r
+ * Appends a line to the EpsDocument.\r
+ */\r
+ private void append(String line)\r
+ {\r
+ _document.append(this, line);\r
+ }\r
+\r
+ /**\r
+ * Returns the point after it has been transformed by the transformation.\r
+ */\r
+ private Point2D transform(float x, float y)\r
+ {\r
+ Point2D result = new Point2D.Float(x, y);\r
+ result = _transform.transform(result, result);\r
+ result.setLocation(result.getX(), -result.getY());\r
+ return result;\r
+ }\r
+\r
+ /**\r
+ * Appends the commands required to draw a shape on the EPS document.\r
+ */\r
+ private void draw(Shape s, String action)\r
+ {\r
+\r
+ if (s != null)\r
+ {\r
+\r
+ //Rectangle2D userBounds = s.getBounds2D();\r
+ if (!_transform.isIdentity())\r
+ {\r
+ s = _transform.createTransformedShape(s);\r
+ }\r
+\r
+ // Update the bounds.\r
+ if (!action.equals("clip"))\r
+ {\r
+ Rectangle2D shapeBounds = s.getBounds2D();\r
+ Rectangle2D visibleBounds = shapeBounds;\r
+ if (_clip != null)\r
+ {\r
+ Rectangle2D clipBounds = _clip.getBounds2D();\r
+ visibleBounds = shapeBounds.createIntersection(clipBounds);\r
}\r
- }\r
-\r
-\r
- /**\r
- * Returns a hex string that always contains two characters.\r
- */\r
- private String toHexString(int n) {\r
- String result = Integer.toString(n, 16);\r
- while (result.length() < 2) {\r
- result = "0" + result;\r
+ float lineRadius = _stroke.getLineWidth() / 2;\r
+ float minX = (float) visibleBounds.getMinX() - lineRadius;\r
+ float minY = (float) visibleBounds.getMinY() - lineRadius;\r
+ float maxX = (float) visibleBounds.getMaxX() + lineRadius;\r
+ float maxY = (float) visibleBounds.getMaxY() + lineRadius;\r
+ _document.updateBounds(minX, -minY);\r
+ _document.updateBounds(maxX, -maxY);\r
+ }\r
+\r
+ append("newpath");\r
+ int type = 0;\r
+ float[] coords = new float[6];\r
+ PathIterator it = s.getPathIterator(null);\r
+ float x0 = 0;\r
+ float y0 = 0;\r
+ int count = 0;\r
+ while (!it.isDone())\r
+ {\r
+ type = it.currentSegment(coords);\r
+ float x1 = coords[0];\r
+ float y1 = -coords[1];\r
+ float x2 = coords[2];\r
+ float y2 = -coords[3];\r
+ float x3 = coords[4];\r
+ float y3 = -coords[5];\r
+\r
+ if (type == PathIterator.SEG_CLOSE)\r
+ {\r
+ append("closepath");\r
+ count++;\r
}\r
- return result;\r
- }\r
-\r
-\r
- /////////////// Graphics2D methods ///////////////////////\r
-\r
-\r
- /**\r
- * Draws a 3D rectangle outline. If it is raised, light appears to come\r
- * from the top left.\r
- */\r
- public void draw3DRect(int x, int y, int width, int height, boolean raised) {\r
- Color originalColor = getColor();\r
- Stroke originalStroke = getStroke();\r
-\r
- setStroke(new BasicStroke(1.0f));\r
-\r
- if (raised) {\r
- setColor(originalColor.brighter());\r
+ else if (type == PathIterator.SEG_CUBICTO)\r
+ {\r
+ append(x1 + " " + y1 + " " + x2 + " " + y2 + " " + x3 + " " + y3 +\r
+ " curveto");\r
+ count++;\r
+ x0 = x3;\r
+ y0 = y3;\r
}\r
- else {\r
- setColor(originalColor.darker());\r
+ else if (type == PathIterator.SEG_LINETO)\r
+ {\r
+ append(x1 + " " + y1 + " lineto");\r
+ count++;\r
+ x0 = x1;\r
+ y0 = y1;\r
}\r
-\r
- drawLine(x, y, x + width, y);\r
- drawLine(x, y, x, y + height);\r
-\r
- if (raised) {\r
- setColor(originalColor.darker());\r
+ else if (type == PathIterator.SEG_MOVETO)\r
+ {\r
+ append(x1 + " " + y1 + " moveto");\r
+ count++;\r
+ x0 = x1;\r
+ y0 = y1;\r
}\r
- else {\r
- setColor(originalColor.brighter());\r
+ else if (type == PathIterator.SEG_QUADTO)\r
+ {\r
+ // Convert the quad curve into a cubic.\r
+ float _x1 = x0 + 2 / 3f * (x1 - x0);\r
+ float _y1 = y0 + 2 / 3f * (y1 - y0);\r
+ float _x2 = x1 + 1 / 3f * (x2 - x1);\r
+ float _y2 = y1 + 1 / 3f * (y2 - y1);\r
+ float _x3 = x2;\r
+ float _y3 = y2;\r
+ append(_x1 + " " + _y1 + " " + _x2 + " " + _y2 + " " + _x3 + " " +\r
+ _y3 + " curveto");\r
+ count++;\r
+ x0 = _x3;\r
+ y0 = _y3;\r
}\r
-\r
- drawLine(x + width, y + height, x, y + height);\r
- drawLine(x + width, y + height, x + width, y);\r
-\r
- setColor(originalColor);\r
- setStroke(originalStroke);\r
- }\r
-\r
-\r
- /**\r
- * Fills a 3D rectangle. If raised, it has bright fill and light appears\r
- * to come from the top left.\r
- */\r
- public void fill3DRect(int x, int y, int width, int height, boolean raised) {\r
- Color originalColor = getColor();\r
-\r
- if (raised) {\r
- setColor(originalColor.brighter());\r
+ else if (type == PathIterator.WIND_EVEN_ODD)\r
+ {\r
+ // Ignore.\r
}\r
- else {\r
- setColor(originalColor.darker());\r
+ else if (type == PathIterator.WIND_NON_ZERO)\r
+ {\r
+ // Ignore.\r
}\r
- draw(new Rectangle(x, y, width, height), "fill");\r
- setColor(originalColor);\r
- draw3DRect(x, y, width, height, raised);\r
- }\r
-\r
-\r
- /**\r
- * Draws a Shape on the EPS document.\r
- */\r
- public void draw(Shape s) {\r
- draw(s, "stroke");\r
- }\r
-\r
-\r
- /**\r
- * Draws an Image on the EPS document.\r
- */\r
- public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) {\r
- AffineTransform at = getTransform();\r
- transform(xform);\r
- boolean st = drawImage(img, 0, 0, obs);\r
- setTransform(at);\r
- return st;\r
- }\r
-\r
-\r
- /**\r
- * Draws a BufferedImage on the EPS document.\r
- */\r
- public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) {\r
- BufferedImage img1 = op.filter(img, null);\r
- drawImage(img1, new AffineTransform(1f, 0f, 0f, 1f, x, y), null);\r
- }\r
-\r
-\r
- /**\r
- * Draws a RenderedImage on the EPS document.\r
- */\r
- public void drawRenderedImage(RenderedImage img, AffineTransform xform) {\r
- Hashtable properties = new Hashtable();\r
- String[] names = img.getPropertyNames();\r
- for (int i = 0; i < names.length; i++) {\r
- properties.put(names[i], img.getProperty(names[i]));\r
+ it.next();\r
+ }\r
+ append(action);\r
+ append("newpath");\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Returns a hex string that always contains two characters.\r
+ */\r
+ private String toHexString(int n)\r
+ {\r
+ String result = Integer.toString(n, 16);\r
+ while (result.length() < 2)\r
+ {\r
+ result = "0" + result;\r
+ }\r
+ return result;\r
+ }\r
+\r
+ /////////////// Graphics2D methods ///////////////////////\r
+\r
+\r
+ /**\r
+ * Draws a 3D rectangle outline. If it is raised, light appears to come\r
+ * from the top left.\r
+ */\r
+ public void draw3DRect(int x, int y, int width, int height, boolean raised)\r
+ {\r
+ Color originalColor = getColor();\r
+ Stroke originalStroke = getStroke();\r
+\r
+ setStroke(new BasicStroke(1.0f));\r
+\r
+ if (raised)\r
+ {\r
+ setColor(originalColor.brighter());\r
+ }\r
+ else\r
+ {\r
+ setColor(originalColor.darker());\r
+ }\r
+\r
+ drawLine(x, y, x + width, y);\r
+ drawLine(x, y, x, y + height);\r
+\r
+ if (raised)\r
+ {\r
+ setColor(originalColor.darker());\r
+ }\r
+ else\r
+ {\r
+ setColor(originalColor.brighter());\r
+ }\r
+\r
+ drawLine(x + width, y + height, x, y + height);\r
+ drawLine(x + width, y + height, x + width, y);\r
+\r
+ setColor(originalColor);\r
+ setStroke(originalStroke);\r
+ }\r
+\r
+ /**\r
+ * Fills a 3D rectangle. If raised, it has bright fill and light appears\r
+ * to come from the top left.\r
+ */\r
+ public void fill3DRect(int x, int y, int width, int height, boolean raised)\r
+ {\r
+ Color originalColor = getColor();\r
+\r
+ if (raised)\r
+ {\r
+ setColor(originalColor.brighter());\r
+ }\r
+ else\r
+ {\r
+ setColor(originalColor.darker());\r
+ }\r
+ draw(new Rectangle(x, y, width, height), "fill");\r
+ setColor(originalColor);\r
+ draw3DRect(x, y, width, height, raised);\r
+ }\r
+\r
+ /**\r
+ * Draws a Shape on the EPS document.\r
+ */\r
+ public void draw(Shape s)\r
+ {\r
+ draw(s, "stroke");\r
+ }\r
+\r
+ /**\r
+ * Draws an Image on the EPS document.\r
+ */\r
+ public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs)\r
+ {\r
+ AffineTransform at = getTransform();\r
+ transform(xform);\r
+ boolean st = drawImage(img, 0, 0, obs);\r
+ setTransform(at);\r
+ return st;\r
+ }\r
+\r
+ /**\r
+ * Draws a BufferedImage on the EPS document.\r
+ */\r
+ public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y)\r
+ {\r
+ BufferedImage img1 = op.filter(img, null);\r
+ drawImage(img1, new AffineTransform(1f, 0f, 0f, 1f, x, y), null);\r
+ }\r
+\r
+ /**\r
+ * Draws a RenderedImage on the EPS document.\r
+ */\r
+ public void drawRenderedImage(RenderedImage img, AffineTransform xform)\r
+ {\r
+ Hashtable properties = new Hashtable();\r
+ String[] names = img.getPropertyNames();\r
+ for (int i = 0; i < names.length; i++)\r
+ {\r
+ properties.put(names[i], img.getProperty(names[i]));\r
+ }\r
+\r
+ ColorModel cm = img.getColorModel();\r
+ WritableRaster wr = img.copyData(null);\r
+ BufferedImage img1 = new BufferedImage(cm, wr, cm.isAlphaPremultiplied(),\r
+ properties);\r
+ AffineTransform at = AffineTransform.getTranslateInstance(img.getMinX(),\r
+ img.getMinY());\r
+ at.preConcatenate(xform);\r
+ drawImage(img1, at, null);\r
+ }\r
+\r
+ /**\r
+ * Draws a RenderableImage by invoking its createDefaultRendering method.\r
+ */\r
+ public void drawRenderableImage(RenderableImage img, AffineTransform xform)\r
+ {\r
+ drawRenderedImage(img.createDefaultRendering(), xform);\r
+ }\r
+\r
+ /**\r
+ * Draws a string at (x,y)\r
+ */\r
+ public void drawString(String str, int x, int y)\r
+ {\r
+ drawString(str, (float) x, (float) y);\r
+ }\r
+\r
+ /**\r
+ * Draws a string at (x,y)\r
+ */\r
+ public void drawString(String s, float x, float y)\r
+ {\r
+ if (s != null && s.length() > 0)\r
+ {\r
+ AttributedString as = new AttributedString(s);\r
+ as.addAttribute(TextAttribute.FONT, getFont());\r
+ drawString(as.getIterator(), x, y);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Draws the characters of an AttributedCharacterIterator, starting from\r
+ * (x,y).\r
+ */\r
+ public void drawString(AttributedCharacterIterator iterator, int x, int y)\r
+ {\r
+ drawString(iterator, (float) x, (float) y);\r
+ }\r
+\r
+ /**\r
+ * Draws the characters of an AttributedCharacterIterator, starting from\r
+ * (x,y).\r
+ */\r
+ public void drawString(AttributedCharacterIterator iterator, float x, float y)\r
+ {\r
+ if (getAccurateTextMode())\r
+ {\r
+ TextLayout layout = new TextLayout(iterator, getFontRenderContext());\r
+ Shape shape = layout.getOutline(AffineTransform.getTranslateInstance(x, y));\r
+ draw(shape, "fill");\r
+ }\r
+ else\r
+ {\r
+ append("newpath");\r
+ Point2D location = transform(x, y);\r
+ append(location.getX() + " " + location.getY() + " moveto");\r
+ StringBuffer buffer = new StringBuffer();\r
+ for (char ch = iterator.first(); ch != CharacterIterator.DONE;\r
+ ch = iterator.next())\r
+ {\r
+ if (ch == '(' || ch == ')')\r
+ {\r
+ buffer.append('\\');\r
}\r
-\r
- ColorModel cm = img.getColorModel();\r
- WritableRaster wr = img.copyData(null);\r
- BufferedImage img1 = new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), properties);\r
- AffineTransform at = AffineTransform.getTranslateInstance(img.getMinX(), img.getMinY());\r
- at.preConcatenate(xform);\r
- drawImage(img1, at, null);\r
- }\r
-\r
-\r
- /**\r
- * Draws a RenderableImage by invoking its createDefaultRendering method.\r
- */\r
- public void drawRenderableImage(RenderableImage img, AffineTransform xform) {\r
- drawRenderedImage(img.createDefaultRendering(), xform);\r
- }\r
-\r
-\r
- /**\r
- * Draws a string at (x,y)\r
- */\r
- public void drawString(String str, int x, int y) {\r
- drawString(str, (float) x, (float) y);\r
- }\r
-\r
-\r
- /**\r
- * Draws a string at (x,y)\r
- */\r
- public void drawString(String s, float x, float y) {\r
- if (s != null && s.length() > 0) {\r
- AttributedString as = new AttributedString(s);\r
- as.addAttribute(TextAttribute.FONT, getFont());\r
- drawString(as.getIterator(), x, y);\r
+ buffer.append(ch);\r
+ }\r
+ append("(" + buffer.toString() + ") show");\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Draws a GlyphVector at (x,y)\r
+ */\r
+ public void drawGlyphVector(GlyphVector g, float x, float y)\r
+ {\r
+ Shape shape = g.getOutline(x, y);\r
+ draw(shape, "fill");\r
+ }\r
+\r
+ /**\r
+ * Fills a Shape on the EPS document.\r
+ */\r
+ public void fill(Shape s)\r
+ {\r
+ draw(s, "fill");\r
+ }\r
+\r
+ /**\r
+ * Checks whether or not the specified Shape intersects the specified\r
+ * Rectangle, which is in device space.\r
+ */\r
+ public boolean hit(Rectangle rect, Shape s, boolean onStroke)\r
+ {\r
+ return s.intersects(rect);\r
+ }\r
+\r
+ /**\r
+ * Returns the device configuration associated with this EpsGraphics2D\r
+ * object.\r
+ */\r
+ public GraphicsConfiguration getDeviceConfiguration()\r
+ {\r
+ GraphicsConfiguration gc = null;\r
+ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();\r
+ GraphicsDevice[] gds = ge.getScreenDevices();\r
+ for (int i = 0; i < gds.length; i++)\r
+ {\r
+ GraphicsDevice gd = gds[i];\r
+ GraphicsConfiguration[] gcs = gd.getConfigurations();\r
+ if (gcs.length > 0)\r
+ {\r
+ return gcs[0];\r
+ }\r
+ }\r
+ return gc;\r
+ }\r
+\r
+ /**\r
+ * Sets the Composite to be used by this EpsGraphics2D. EpsGraphics2D\r
+ * does not make use of these.\r
+ */\r
+ public void setComposite(Composite comp)\r
+ {\r
+ _composite = comp;\r
+ }\r
+\r
+ /**\r
+ * Sets the Paint attribute for the EpsGraphics2D object. Only Paint\r
+ * objects of type Color are respected by EpsGraphics2D.\r
+ */\r
+ public void setPaint(Paint paint)\r
+ {\r
+ _paint = paint;\r
+ if (paint instanceof Color)\r
+ {\r
+ setColor( (Color) paint);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Sets the stroke. Only accepts BasicStroke objects (or subclasses of\r
+ * BasicStroke).\r
+ */\r
+ public void setStroke(Stroke s)\r
+ {\r
+ if (s instanceof BasicStroke)\r
+ {\r
+ _stroke = (BasicStroke) s;\r
+\r
+ append(_stroke.getLineWidth() + " setlinewidth");\r
+ float miterLimit = _stroke.getMiterLimit();\r
+ if (miterLimit < 1.0f)\r
+ {\r
+ miterLimit = 1;\r
+ }\r
+ append(miterLimit + " setmiterlimit");\r
+ append(_stroke.getLineJoin() + " setlinejoin");\r
+ append(_stroke.getEndCap() + " setlinecap");\r
+\r
+ StringBuffer dashes = new StringBuffer();\r
+ dashes.append("[ ");\r
+ float[] dashArray = _stroke.getDashArray();\r
+ if (dashArray != null)\r
+ {\r
+ for (int i = 0; i < dashArray.length; i++)\r
+ {\r
+ dashes.append( (dashArray[i]) + " ");\r
}\r
- }\r
-\r
-\r
- /**\r
- * Draws the characters of an AttributedCharacterIterator, starting from\r
- * (x,y).\r
- */\r
- public void drawString(AttributedCharacterIterator iterator, int x, int y) {\r
- drawString(iterator, (float) x, (float) y);\r
- }\r
-\r
-\r
- /**\r
- * Draws the characters of an AttributedCharacterIterator, starting from\r
- * (x,y).\r
- */\r
- public void drawString(AttributedCharacterIterator iterator, float x, float y) {\r
- if (getAccurateTextMode()) {\r
- TextLayout layout = new TextLayout(iterator, getFontRenderContext());\r
- Shape shape = layout.getOutline(AffineTransform.getTranslateInstance(x, y));\r
- draw(shape, "fill");\r
- }\r
- else {\r
- append("newpath");\r
- Point2D location = transform(x, y);\r
- append(location.getX() + " " + location.getY() + " moveto");\r
- StringBuffer buffer = new StringBuffer();\r
- for (char ch = iterator.first(); ch != CharacterIterator.DONE; ch = iterator.next()) {\r
- if (ch == '(' || ch == ')') {\r
- buffer.append('\\');\r
- }\r
- buffer.append(ch);\r
- }\r
- append("(" + buffer.toString() + ") show");\r
- }\r
- }\r
-\r
-\r
- /**\r
- * Draws a GlyphVector at (x,y)\r
- */\r
- public void drawGlyphVector(GlyphVector g, float x, float y) {\r
- Shape shape = g.getOutline(x, y);\r
- draw(shape, "fill");\r
- }\r
-\r
-\r
- /**\r
- * Fills a Shape on the EPS document.\r
- */\r
- public void fill(Shape s) {\r
- draw(s, "fill");\r
- }\r
-\r
-\r
- /**\r
- * Checks whether or not the specified Shape intersects the specified\r
- * Rectangle, which is in device space.\r
- */\r
- public boolean hit(Rectangle rect, Shape s, boolean onStroke) {\r
- return s.intersects(rect);\r
- }\r
-\r
-\r
- /**\r
- * Returns the device configuration associated with this EpsGraphics2D\r
- * object.\r
- */\r
- public GraphicsConfiguration getDeviceConfiguration() {\r
- GraphicsConfiguration gc = null;\r
- GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();\r
- GraphicsDevice[] gds = ge.getScreenDevices();\r
- for (int i = 0; i < gds.length; i++) {\r
- GraphicsDevice gd = gds[i];\r
- GraphicsConfiguration[] gcs = gd.getConfigurations();\r
- if (gcs.length > 0) {\r
- return gcs[0];\r
- }\r
- }\r
- return gc;\r
- }\r
-\r
-\r
- /**\r
- * Sets the Composite to be used by this EpsGraphics2D. EpsGraphics2D\r
- * does not make use of these.\r
- */\r
- public void setComposite(Composite comp) {\r
- _composite = comp;\r
- }\r
-\r
-\r
- /**\r
- * Sets the Paint attribute for the EpsGraphics2D object. Only Paint\r
- * objects of type Color are respected by EpsGraphics2D.\r
- */\r
- public void setPaint(Paint paint) {\r
- _paint = paint;\r
- if (paint instanceof Color) {\r
- setColor((Color) paint);\r
- }\r
- }\r
-\r
-\r
- /**\r
- * Sets the stroke. Only accepts BasicStroke objects (or subclasses of\r
- * BasicStroke).\r
- */\r
- public void setStroke(Stroke s) {\r
- if (s instanceof BasicStroke) {\r
- _stroke = (BasicStroke) s;\r
-\r
- append(_stroke.getLineWidth() + " setlinewidth");\r
- float miterLimit = _stroke.getMiterLimit();\r
- if (miterLimit < 1.0f) {\r
- miterLimit = 1;\r
- }\r
- append(miterLimit + " setmiterlimit");\r
- append(_stroke.getLineJoin() + " setlinejoin");\r
- append(_stroke.getEndCap() + " setlinecap");\r
-\r
- StringBuffer dashes = new StringBuffer();\r
- dashes.append("[ ");\r
- float[] dashArray = _stroke.getDashArray();\r
- if (dashArray != null) {\r
- for (int i = 0; i < dashArray.length; i++) {\r
- dashes.append((dashArray[i]) + " ");\r
- }\r
- }\r
- dashes.append("]");\r
- append(dashes.toString() + " 0 setdash");\r
- }\r
- }\r
-\r
-\r
- /**\r
- * Sets a rendering hint. These are not used by EpsGraphics2D.\r
- */\r
- public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) {\r
- // Do nothing.\r
- }\r
-\r
-\r
- /**\r
- * Returns the value of a single preference for the rendering\r
- * algorithms. Rendering hints are not used by EpsGraphics2D.\r
- */\r
- public Object getRenderingHint(RenderingHints.Key hintKey) {\r
- return null;\r
- }\r
-\r
-\r
- /**\r
- * Sets the rendering hints. These are ignored by EpsGraphics2D.\r
- */\r
- public void setRenderingHints(Map hints) {\r
- // Do nothing.\r
- }\r
-\r
-\r
- /**\r
- * Adds rendering hints. These are ignored by EpsGraphics2D.\r
- */\r
- public void addRenderingHints(Map hints) {\r
- // Do nothing.\r
- }\r
-\r
-\r
- /**\r
- * Returns the preferences for the rendering algorithms.\r
- */\r
- public RenderingHints getRenderingHints() {\r
- return new RenderingHints(null);\r
- }\r
-\r
-\r
- /**\r
- * Translates the origin of the EpsGraphics2D context to the point (x,y)\r
- * in the current coordinate system.\r
- */\r
- public void translate(int x, int y) {\r
- translate((double) x, (double) y);\r
- }\r
-\r
-\r
- /**\r
- * Concatenates the current EpsGraphics2D Transformation with a\r
- * translation transform.\r
- */\r
- public void translate(double tx, double ty) {\r
- transform(AffineTransform.getTranslateInstance(tx, ty));\r
- }\r
-\r
-\r
- /**\r
- * Concatenates the current EpsGraphics2D Transform with a rotation\r
- * transform.\r
- */\r
- public void rotate(double theta) {\r
- rotate(theta, 0, 0);\r
- }\r
-\r
-\r
- /**\r
- * Concatenates the current EpsGraphics2D Transform with a translated\r
- * rotation transform.\r
- */\r
- public void rotate(double theta, double x, double y) {\r
- transform(AffineTransform.getRotateInstance(theta, x, y));\r
- }\r
-\r
-\r
- /**\r
- * Concatenates the current EpsGraphics2D Transform with a scaling\r
- * transformation.\r
- */\r
- public void scale(double sx, double sy) {\r
- transform(AffineTransform.getScaleInstance(sx, sy));\r
- }\r
-\r
-\r
- /**\r
- * Concatenates the current EpsGraphics2D Transform with a shearing\r
- * transform.\r
- */\r
- public void shear(double shx, double shy) {\r
- transform(AffineTransform.getShearInstance(shx, shy));\r
- }\r
-\r
-\r
- /**\r
- * Composes an AffineTransform object with the Transform in this\r
- * EpsGraphics2D according to the rule last-specified-first-applied.\r
- */\r
- public void transform(AffineTransform Tx) {\r
- _transform.concatenate(Tx);\r
- setTransform(getTransform());\r
- }\r
-\r
-\r
- /**\r
- * Sets the AffineTransform to be used by this EpsGraphics2D.\r
- */\r
- public void setTransform(AffineTransform Tx) {\r
- if (Tx == null) {\r
- _transform = new AffineTransform();\r
- }\r
- else {\r
- _transform = new AffineTransform(Tx);\r
- }\r
- // Need to update the stroke and font so they know the scale changed\r
- setStroke(getStroke());\r
- setFont(getFont());\r
- }\r
-\r
-\r
- /**\r
- * Gets the AffineTransform used by this EpsGraphics2D.\r
- */\r
- public AffineTransform getTransform() {\r
- return new AffineTransform(_transform);\r
- }\r
-\r
-\r
- /**\r
- * Returns the current Paint of the EpsGraphics2D object.\r
- */\r
- public Paint getPaint() {\r
- return _paint;\r
- }\r
-\r
-\r
- /**\r
- * returns the current Composite of the EpsGraphics2D object.\r
- */\r
- public Composite getComposite() {\r
- return _composite;\r
- }\r
-\r
-\r
- /**\r
- * Sets the background color to be used by the clearRect method.\r
- */\r
- public void setBackground(Color color) {\r
- if (color == null) {\r
- color = Color.black;\r
- }\r
- _backgroundColor = color;\r
- }\r
-\r
-\r
- /**\r
- * Gets the background color that is used by the clearRect method.\r
- */\r
- public Color getBackground() {\r
- return _backgroundColor;\r
- }\r
-\r
-\r
- /**\r
- * Returns the Stroke currently used. Guaranteed to be an instance of\r
- * BasicStroke.\r
- */\r
- public Stroke getStroke() {\r
- return _stroke;\r
- }\r
-\r
-\r
- /**\r
- * Intersects the current clip with the interior of the specified Shape\r
- * and sets the clip to the resulting intersection.\r
- */\r
- public void clip(Shape s) {\r
- if (_clip == null) {\r
- setClip(s);\r
- }\r
- else {\r
- Area area = new Area(_clip);\r
- area.intersect(new Area(s));\r
- setClip(area);\r
- }\r
- }\r
-\r
-\r
- /**\r
- * Returns the FontRenderContext.\r
- */\r
- public FontRenderContext getFontRenderContext() {\r
- return _fontRenderContext;\r
- }\r
-\r
-\r
- /////////////// Graphics methods ///////////////////////\r
-\r
-\r
- /**\r
- * Returns a new Graphics object that is identical to this EpsGraphics2D.\r
- */\r
- public Graphics create() {\r
- return new EpsGraphics2D(this);\r
- }\r
-\r
-\r
- /**\r
- * Returns an EpsGraphics2D object based on this\r
- * Graphics object, but with a new translation and clip\r
- * area.\r
- */\r
- public Graphics create(int x, int y, int width, int height) {\r
- Graphics g = create();\r
- g.translate(x, y);\r
- g.clipRect(0, 0, width, height);\r
- return g;\r
- }\r
-\r
-\r
- /**\r
- * Returns the current Color. This will be a default value (black)\r
- * until it is changed using the setColor method.\r
- */\r
- public Color getColor() {\r
- return _color;\r
- }\r
-\r
-\r
- /**\r
- * Sets the Color to be used when drawing all future shapes, text, etc.\r
- */\r
- public void setColor(Color c) {\r
- if (c == null) {\r
- c = Color.black;\r
- }\r
- _color = c;\r
- append((c.getRed() / 255f) + " " + (c.getGreen() / 255f) + " " + (c.getBlue() / 255f) + " setrgbcolor");\r
- }\r
-\r
-\r
- /**\r
- * Sets the paint mode of this EpsGraphics2D object to overwrite the\r
- * destination EpsDocument with the current color.\r
- */\r
- public void setPaintMode() {\r
- // Do nothing - paint mode is the only method supported anyway.\r
- }\r
-\r
-\r
- /**\r
- * <b><i><font color="red">Not implemented</font></i></b> - performs no action.\r
- */\r
- public void setXORMode(Color c1) {\r
- methodNotSupported();\r
- }\r
-\r
-\r
- /**\r
- * Returns the Font currently being used.\r
- */\r
- public Font getFont() {\r
- return _font;\r
- }\r
-\r
-\r
- /**\r
- * Sets the Font to be used in future text.\r
- */\r
- public void setFont(Font font) {\r
- if (font == null) {\r
- font = Font.decode(null);\r
- }\r
- _font = font;\r
- append("/" + _font.getPSName() + " findfont " + ((int) _font.getSize()) + " scalefont setfont");\r
- }\r
-\r
-\r
- /**\r
- * Gets the font metrics of the current font.\r
- */\r
- public FontMetrics getFontMetrics() {\r
- return getFontMetrics(getFont());\r
- }\r
-\r
-\r
- /**\r
- * Gets the font metrics for the specified font.\r
- */\r
- public FontMetrics getFontMetrics(Font f) {\r
- BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);\r
- Graphics g = image.getGraphics();\r
- return g.getFontMetrics(f);\r
- }\r
-\r
-\r
- /**\r
- * Returns the bounding rectangle of the current clipping area.\r
- */\r
- public Rectangle getClipBounds() {\r
- if (_clip == null) {\r
- return null;\r
- }\r
- Rectangle rect = getClip().getBounds();\r
- return rect;\r
- }\r
-\r
-\r
- /**\r
- * Intersects the current clip with the specified rectangle.\r
- */\r
- public void clipRect(int x, int y, int width, int height) {\r
- clip(new Rectangle(x, y, width, height));\r
- }\r
-\r
-\r
- /**\r
- * Sets the current clip to the rectangle specified by the given\r
- * coordinates.\r
- */\r
- public void setClip(int x, int y, int width, int height) {\r
- setClip(new Rectangle(x, y, width, height));\r
- }\r
-\r
-\r
- /**\r
- * Gets the current clipping area.\r
- */\r
- public Shape getClip() {\r
- if (_clip == null) {\r
- return null;\r
- }\r
- else {\r
- try {\r
- AffineTransform t = _transform.createInverse();\r
- t.concatenate(_clipTransform);\r
- return t.createTransformedShape(_clip);\r
- }\r
- catch (Exception e) {\r
- throw new EpsException("Unable to get inverse of matrix: " + _transform);\r
- }\r
- }\r
- }\r
-\r
-\r
- /**\r
- * Sets the current clipping area to an arbitrary clip shape.\r
- */\r
- public void setClip(Shape clip) {\r
- if (clip != null) {\r
- if (_document.isClipSet()) {\r
- append("grestore");\r
- append("gsave");\r
- }\r
- else {\r
- _document.setClipSet(true);\r
- append("gsave");\r
- }\r
- draw(clip, "clip");\r
- _clip = clip;\r
- _clipTransform = (AffineTransform) _transform.clone();\r
- }\r
- else {\r
- if (_document.isClipSet()) {\r
- append("grestore");\r
- _document.setClipSet(false);\r
- }\r
- _clip = null;\r
- }\r
- }\r
-\r
-\r
- /**\r
- * <b><i><font color="red">Not implemented</font></i></b> - performs no action.\r
- */\r
- public void copyArea(int x, int y, int width, int height, int dx, int dy) {\r
- methodNotSupported();\r
- }\r
-\r
-\r
- /**\r
- * Draws a straight line from (x1,y1) to (x2,y2).\r
- */\r
- public void drawLine(int x1, int y1, int x2, int y2) {\r
- Shape shape = new Line2D.Float(x1, y1, x2, y2);\r
- draw(shape);\r
- }\r
-\r
-\r
- /**\r
- * Fills a rectangle with top-left corner placed at (x,y).\r
- */\r
- public void fillRect(int x, int y, int width, int height) {\r
- Shape shape = new Rectangle(x, y, width, height);\r
- draw(shape, "fill");\r
- }\r
-\r
-\r
- /**\r
- * Draws a rectangle with top-left corner placed at (x,y).\r
- */\r
- public void drawRect(int x, int y, int width, int height) {\r
- Shape shape = new Rectangle(x, y, width, height);\r
- draw(shape);\r
- }\r
-\r
-\r
- /**\r
- * Clears a rectangle with top-left corner placed at (x,y) using the\r
- * current background color.\r
- */\r
- public void clearRect(int x, int y, int width, int height) {\r
- Color originalColor = getColor();\r
-\r
- setColor(getBackground());\r
- Shape shape = new Rectangle(x, y, width, height);\r
- draw(shape, "fill");\r
-\r
- setColor(originalColor);\r
- }\r
-\r
-\r
- /**\r
- * Draws a rounded rectangle.\r
- */\r
- public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {\r
- Shape shape = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight);\r
- draw(shape);\r
- }\r
-\r
-\r
- /**\r
- * Fills a rounded rectangle.\r
- */\r
- public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {\r
- Shape shape = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight);\r
- draw(shape, "fill");\r
- }\r
-\r
-\r
- /**\r
- * Draws an oval.\r
- */\r
- public void drawOval(int x, int y, int width, int height) {\r
- Shape shape = new Ellipse2D.Float(x, y, width, height);\r
- draw(shape);\r
- }\r
-\r
-\r
- /**\r
- * Fills an oval.\r
- */\r
- public void fillOval(int x, int y, int width, int height) {\r
- Shape shape = new Ellipse2D.Float(x, y, width, height);\r
- draw(shape, "fill");\r
- }\r
-\r
-\r
- /**\r
- * Draws an arc.\r
- */\r
- public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) {\r
- Shape shape = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN);\r
- draw(shape);\r
- }\r
-\r
-\r
- /**\r
- * Fills an arc.\r
- */\r
- public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) {\r
- Shape shape = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.PIE);\r
- draw(shape, "fill");\r
- }\r
-\r
-\r
- /**\r
- * Draws a polyline.\r
- */\r
- public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) {\r
- if (nPoints > 0) {\r
- GeneralPath path = new GeneralPath();\r
- path.moveTo(xPoints[0], yPoints[0]);\r
- for (int i = 1; i < nPoints; i++) {\r
- path.lineTo(xPoints[i], yPoints[i]);\r
- }\r
- draw(path);\r
- }\r
- }\r
-\r
-\r
- /**\r
- * Draws a polygon made with the specified points.\r
- */\r
- public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) {\r
- Shape shape = new Polygon(xPoints, yPoints, nPoints);\r
- draw(shape);\r
- }\r
-\r
-\r
- /**\r
- * Draws a polygon.\r
- */\r
- public void drawPolygon(Polygon p) {\r
- draw(p);\r
- }\r
-\r
-\r
- /**\r
- * Fills a polygon made with the specified points.\r
- */\r
- public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) {\r
- Shape shape = new Polygon(xPoints, yPoints, nPoints);\r
- draw(shape, "fill");\r
- }\r
-\r
-\r
- /**\r
- * Fills a polygon.\r
- */\r
- public void fillPolygon(Polygon p) {\r
- draw(p, "fill");\r
- }\r
-\r
-\r
- /**\r
- * Draws the specified characters, starting from (x,y)\r
- */\r
- public void drawChars(char[] data, int offset, int length, int x, int y) {\r
- String string = new String(data, offset, length);\r
- drawString(string, x, y);\r
- }\r
-\r
-\r
- /**\r
- * Draws the specified bytes, starting from (x,y)\r
- */\r
- public void drawBytes(byte[] data, int offset, int length, int x, int y) {\r
- String string = new String(data, offset, length);\r
- drawString(string, x, y);\r
- }\r
-\r
-\r
- /**\r
- * Draws an image.\r
- */\r
- public boolean drawImage(Image img, int x, int y, ImageObserver observer) {\r
- return drawImage(img, x, y, Color.white, observer);\r
- }\r
-\r
-\r
- /**\r
- * Draws an image.\r
- */\r
- public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) {\r
- return drawImage(img, x, y, width, height, Color.white, observer);\r
- }\r
-\r
-\r
- /**\r
- * Draws an image.\r
- */\r
- public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) {\r
- int width = img.getWidth(null);\r
- int height = img.getHeight(null);\r
- return drawImage(img, x, y, width, height, bgcolor, observer);\r
- }\r
-\r
-\r
- /**\r
- * Draws an image.\r
- */\r
- public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) {\r
- return drawImage(img, x, y, x + width, y + height, 0, 0, width, height, bgcolor, observer);\r
- }\r
-\r
-\r
- /**\r
- * Draws an image.\r
- */\r
- public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) {\r
- return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, Color.white, observer);\r
- }\r
-\r
-\r
- /**\r
- * Draws an image.\r
- */\r
- public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) {\r
- if (dx1 >= dx2) {\r
- throw new IllegalArgumentException("dx1 >= dx2");\r
- }\r
- if (sx1 >= sx2) {\r
- throw new IllegalArgumentException("sx1 >= sx2");\r
- }\r
- if (dy1 >= dy2) {\r
- throw new IllegalArgumentException("dy1 >= dy2");\r
- }\r
- if (sy1 >= sy2) {\r
- throw new IllegalArgumentException("sy1 >= sy2");\r
- }\r
-\r
+ }\r
+ dashes.append("]");\r
+ append(dashes.toString() + " 0 setdash");\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Sets a rendering hint. These are not used by EpsGraphics2D.\r
+ */\r
+ public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue)\r
+ {\r
+ // Do nothing.\r
+ }\r
+\r
+ /**\r
+ * Returns the value of a single preference for the rendering\r
+ * algorithms. Rendering hints are not used by EpsGraphics2D.\r
+ */\r
+ public Object getRenderingHint(RenderingHints.Key hintKey)\r
+ {\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * Sets the rendering hints. These are ignored by EpsGraphics2D.\r
+ */\r
+ public void setRenderingHints(Map hints)\r
+ {\r
+ // Do nothing.\r
+ }\r
+\r
+ /**\r
+ * Adds rendering hints. These are ignored by EpsGraphics2D.\r
+ */\r
+ public void addRenderingHints(Map hints)\r
+ {\r
+ // Do nothing.\r
+ }\r
+\r
+ /**\r
+ * Returns the preferences for the rendering algorithms.\r
+ */\r
+ public RenderingHints getRenderingHints()\r
+ {\r
+ return new RenderingHints(null);\r
+ }\r
+\r
+ /**\r
+ * Translates the origin of the EpsGraphics2D context to the point (x,y)\r
+ * in the current coordinate system.\r
+ */\r
+ public void translate(int x, int y)\r
+ {\r
+ translate( (double) x, (double) y);\r
+ }\r
+\r
+ /**\r
+ * Concatenates the current EpsGraphics2D Transformation with a\r
+ * translation transform.\r
+ */\r
+ public void translate(double tx, double ty)\r
+ {\r
+ transform(AffineTransform.getTranslateInstance(tx, ty));\r
+ }\r
+\r
+ /**\r
+ * Concatenates the current EpsGraphics2D Transform with a rotation\r
+ * transform.\r
+ */\r
+ public void rotate(double theta)\r
+ {\r
+ rotate(theta, 0, 0);\r
+ }\r
+\r
+ /**\r
+ * Concatenates the current EpsGraphics2D Transform with a translated\r
+ * rotation transform.\r
+ */\r
+ public void rotate(double theta, double x, double y)\r
+ {\r
+ transform(AffineTransform.getRotateInstance(theta, x, y));\r
+ }\r
+\r
+ /**\r
+ * Concatenates the current EpsGraphics2D Transform with a scaling\r
+ * transformation.\r
+ */\r
+ public void scale(double sx, double sy)\r
+ {\r
+ transform(AffineTransform.getScaleInstance(sx, sy));\r
+ }\r
+\r
+ /**\r
+ * Concatenates the current EpsGraphics2D Transform with a shearing\r
+ * transform.\r
+ */\r
+ public void shear(double shx, double shy)\r
+ {\r
+ transform(AffineTransform.getShearInstance(shx, shy));\r
+ }\r
+\r
+ /**\r
+ * Composes an AffineTransform object with the Transform in this\r
+ * EpsGraphics2D according to the rule last-specified-first-applied.\r
+ */\r
+ public void transform(AffineTransform Tx)\r
+ {\r
+ _transform.concatenate(Tx);\r
+ setTransform(getTransform());\r
+ }\r
+\r
+ /**\r
+ * Sets the AffineTransform to be used by this EpsGraphics2D.\r
+ */\r
+ public void setTransform(AffineTransform Tx)\r
+ {\r
+ if (Tx == null)\r
+ {\r
+ _transform = new AffineTransform();\r
+ }\r
+ else\r
+ {\r
+ _transform = new AffineTransform(Tx);\r
+ }\r
+ // Need to update the stroke and font so they know the scale changed\r
+ setStroke(getStroke());\r
+ setFont(getFont());\r
+ }\r
+\r
+ /**\r
+ * Gets the AffineTransform used by this EpsGraphics2D.\r
+ */\r
+ public AffineTransform getTransform()\r
+ {\r
+ return new AffineTransform(_transform);\r
+ }\r
+\r
+ /**\r
+ * Returns the current Paint of the EpsGraphics2D object.\r
+ */\r
+ public Paint getPaint()\r
+ {\r
+ return _paint;\r
+ }\r
+\r
+ /**\r
+ * returns the current Composite of the EpsGraphics2D object.\r
+ */\r
+ public Composite getComposite()\r
+ {\r
+ return _composite;\r
+ }\r
+\r
+ /**\r
+ * Sets the background color to be used by the clearRect method.\r
+ */\r
+ public void setBackground(Color color)\r
+ {\r
+ if (color == null)\r
+ {\r
+ color = Color.black;\r
+ }\r
+ _backgroundColor = color;\r
+ }\r
+\r
+ /**\r
+ * Gets the background color that is used by the clearRect method.\r
+ */\r
+ public Color getBackground()\r
+ {\r
+ return _backgroundColor;\r
+ }\r
+\r
+ /**\r
+ * Returns the Stroke currently used. Guaranteed to be an instance of\r
+ * BasicStroke.\r
+ */\r
+ public Stroke getStroke()\r
+ {\r
+ return _stroke;\r
+ }\r
+\r
+ /**\r
+ * Intersects the current clip with the interior of the specified Shape\r
+ * and sets the clip to the resulting intersection.\r
+ */\r
+ public void clip(Shape s)\r
+ {\r
+ if (_clip == null)\r
+ {\r
+ setClip(s);\r
+ }\r
+ else\r
+ {\r
+ Area area = new Area(_clip);\r
+ area.intersect(new Area(s));\r
+ setClip(area);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Returns the FontRenderContext.\r
+ */\r
+ public FontRenderContext getFontRenderContext()\r
+ {\r
+ return _fontRenderContext;\r
+ }\r
+\r
+ /////////////// Graphics methods ///////////////////////\r
+\r
+\r
+ /**\r
+ * Returns a new Graphics object that is identical to this EpsGraphics2D.\r
+ */\r
+ public Graphics create()\r
+ {\r
+ return new EpsGraphics2D(this);\r
+ }\r
+\r
+ /**\r
+ * Returns an EpsGraphics2D object based on this\r
+ * Graphics object, but with a new translation and clip\r
+ * area.\r
+ */\r
+ public Graphics create(int x, int y, int width, int height)\r
+ {\r
+ Graphics g = create();\r
+ g.translate(x, y);\r
+ g.clipRect(0, 0, width, height);\r
+ return g;\r
+ }\r
+\r
+ /**\r
+ * Returns the current Color. This will be a default value (black)\r
+ * until it is changed using the setColor method.\r
+ */\r
+ public Color getColor()\r
+ {\r
+ return _color;\r
+ }\r
+\r
+ /**\r
+ * Sets the Color to be used when drawing all future shapes, text, etc.\r
+ */\r
+ public void setColor(Color c)\r
+ {\r
+ if (c == null)\r
+ {\r
+ c = Color.black;\r
+ }\r
+ _color = c;\r
+ append( (c.getRed() / 255f) + " " + (c.getGreen() / 255f) + " " +\r
+ (c.getBlue() / 255f) + " setrgbcolor");\r
+ }\r
+\r
+ /**\r
+ * Sets the paint mode of this EpsGraphics2D object to overwrite the\r
+ * destination EpsDocument with the current color.\r
+ */\r
+ public void setPaintMode()\r
+ {\r
+ // Do nothing - paint mode is the only method supported anyway.\r
+ }\r
+\r
+ /**\r
+ * <b><i><font color="red">Not implemented</font></i></b> - performs no action.\r
+ */\r
+ public void setXORMode(Color c1)\r
+ {\r
+ methodNotSupported();\r
+ }\r
+\r
+ /**\r
+ * Returns the Font currently being used.\r
+ */\r
+ public Font getFont()\r
+ {\r
+ return _font;\r
+ }\r
+\r
+ /**\r
+ * Sets the Font to be used in future text.\r
+ */\r
+ public void setFont(Font font)\r
+ {\r
+ if (font == null)\r
+ {\r
+ font = Font.decode(null);\r
+ }\r
+ _font = font;\r
+ append("/" + _font.getPSName() + " findfont " + ( (int) _font.getSize()) +\r
+ " scalefont setfont");\r
+ }\r
+\r
+ /**\r
+ * Gets the font metrics of the current font.\r
+ */\r
+ public FontMetrics getFontMetrics()\r
+ {\r
+ return getFontMetrics(getFont());\r
+ }\r
+\r
+ /**\r
+ * Gets the font metrics for the specified font.\r
+ */\r
+ public FontMetrics getFontMetrics(Font f)\r
+ {\r
+ BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);\r
+ Graphics g = image.getGraphics();\r
+ return g.getFontMetrics(f);\r
+ }\r
+\r
+ /**\r
+ * Returns the bounding rectangle of the current clipping area.\r
+ */\r
+ public Rectangle getClipBounds()\r
+ {\r
+ if (_clip == null)\r
+ {\r
+ return null;\r
+ }\r
+ Rectangle rect = getClip().getBounds();\r
+ return rect;\r
+ }\r
+\r
+ /**\r
+ * Intersects the current clip with the specified rectangle.\r
+ */\r
+ public void clipRect(int x, int y, int width, int height)\r
+ {\r
+ clip(new Rectangle(x, y, width, height));\r
+ }\r
+\r
+ /**\r
+ * Sets the current clip to the rectangle specified by the given\r
+ * coordinates.\r
+ */\r
+ public void setClip(int x, int y, int width, int height)\r
+ {\r
+ setClip(new Rectangle(x, y, width, height));\r
+ }\r
+\r
+ /**\r
+ * Gets the current clipping area.\r
+ */\r
+ public Shape getClip()\r
+ {\r
+ if (_clip == null)\r
+ {\r
+ return null;\r
+ }\r
+ else\r
+ {\r
+ try\r
+ {\r
+ AffineTransform t = _transform.createInverse();\r
+ t.concatenate(_clipTransform);\r
+ return t.createTransformedShape(_clip);\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ throw new EpsException("Unable to get inverse of matrix: " + _transform);\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Sets the current clipping area to an arbitrary clip shape.\r
+ */\r
+ public void setClip(Shape clip)\r
+ {\r
+ if (clip != null)\r
+ {\r
+ if (_document.isClipSet())\r
+ {\r
+ append("grestore");\r
append("gsave");\r
-\r
- int width = sx2 - sx1;\r
- int height = sy2 - sy1;\r
- int destWidth = dx2 - dx1;\r
- int destHeight = dy2 - dy1;\r
-\r
- int[] pixels = new int[width * height];\r
- PixelGrabber pg = new PixelGrabber(img, sx1, sy1, sx2 - sx1, sy2 - sy1, pixels, 0, width);\r
- try {\r
- pg.grabPixels();\r
- }\r
- catch(InterruptedException e) {\r
- return false;\r
- }\r
-\r
- AffineTransform matrix = new AffineTransform(_transform);\r
- matrix.translate(dx1, dy1);\r
- matrix.scale(destWidth / (double) width, destHeight / (double) height);\r
- double[] m = new double[6];\r
- try {\r
- matrix = matrix.createInverse();\r
- }\r
- catch (Exception e) {\r
- throw new EpsException("Unable to get inverse of matrix: " + matrix);\r
- }\r
- matrix.scale(1, -1);\r
- matrix.getMatrix(m);\r
- append(width + " " + height + " 8 [" + m[0] + " " + m[1] + " " + m[2] + " " + m[3] + " " + m[4] + " " + m[5] + "]");\r
- // Fill the background to update the bounding box.\r
- Color oldColor = getColor();\r
- setColor(getBackground());\r
- fillRect(dx1, dy1, destWidth, destHeight);\r
- setColor(oldColor);\r
- append("{currentfile 3 " + width + " mul string readhexstring pop} bind");\r
- append("false 3 colorimage");\r
- StringBuffer line = new StringBuffer();\r
- for (int y = 0; y < height; y++) {\r
- for (int x = 0; x < width; x++) {\r
- Color color = new Color(pixels[x + width * y]);\r
- line.append(toHexString(color.getRed()) + toHexString(color.getGreen()) + toHexString(color.getBlue()));\r
- if (line.length() > 64) {\r
- append(line.toString());\r
- line = new StringBuffer();\r
- }\r
- }\r
- }\r
- if (line.length() > 0) {\r
- append(line.toString());\r
- }\r
-\r
+ }\r
+ else\r
+ {\r
+ _document.setClipSet(true);\r
+ append("gsave");\r
+ }\r
+ draw(clip, "clip");\r
+ _clip = clip;\r
+ _clipTransform = (AffineTransform) _transform.clone();\r
+ }\r
+ else\r
+ {\r
+ if (_document.isClipSet())\r
+ {\r
append("grestore");\r
-\r
- return true;\r
- }\r
-\r
-\r
- /**\r
- * Disposes of all resources used by this EpsGraphics2D object.\r
- * If this is the only remaining EpsGraphics2D instance pointing at\r
- * a EpsDocument object, then the EpsDocument object shall become\r
- * eligible for garbage collection.\r
- */\r
- public void dispose() {\r
- _document = null;\r
- }\r
-\r
-\r
- /**\r
- * Finalizes the object.\r
- */\r
- public void finalize() {\r
- super.finalize();\r
- }\r
-\r
-\r
- /**\r
- * Returns the entire contents of the EPS document, complete with\r
- * headers and bounding box. The returned String is suitable for\r
- * being written directly to disk as an EPS file.\r
- */\r
- public String toString() {\r
- StringWriter writer = new StringWriter();\r
- try {\r
- _document.write(writer);\r
- _document.flush();\r
- _document.close();\r
- }\r
- catch (IOException e) {\r
- throw new EpsException(e.toString());\r
- }\r
- return writer.toString();\r
- }\r
-\r
-\r
- /**\r
- * Returns true if the specified rectangular area might intersect the\r
- * current clipping area.\r
- */\r
- public boolean hitClip(int x, int y, int width, int height) {\r
- if (_clip == null) {\r
- return true;\r
- }\r
- Rectangle rect = new Rectangle(x, y, width, height);\r
- return hit(rect, _clip, true);\r
- }\r
-\r
-\r
- /**\r
- * Returns the bounding rectangle of the current clipping area.\r
- */\r
- public Rectangle getClipBounds(Rectangle r) {\r
- if (_clip == null) {\r
- return r;\r
+ _document.setClipSet(false);\r
+ }\r
+ _clip = null;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * <b><i><font color="red">Not implemented</font></i></b> - performs no action.\r
+ */\r
+ public void copyArea(int x, int y, int width, int height, int dx, int dy)\r
+ {\r
+ methodNotSupported();\r
+ }\r
+\r
+ /**\r
+ * Draws a straight line from (x1,y1) to (x2,y2).\r
+ */\r
+ public void drawLine(int x1, int y1, int x2, int y2)\r
+ {\r
+ Shape shape = new Line2D.Float(x1, y1, x2, y2);\r
+ draw(shape);\r
+ }\r
+\r
+ /**\r
+ * Fills a rectangle with top-left corner placed at (x,y).\r
+ */\r
+ public void fillRect(int x, int y, int width, int height)\r
+ {\r
+ Shape shape = new Rectangle(x, y, width, height);\r
+ draw(shape, "fill");\r
+ }\r
+\r
+ /**\r
+ * Draws a rectangle with top-left corner placed at (x,y).\r
+ */\r
+ public void drawRect(int x, int y, int width, int height)\r
+ {\r
+ Shape shape = new Rectangle(x, y, width, height);\r
+ draw(shape);\r
+ }\r
+\r
+ /**\r
+ * Clears a rectangle with top-left corner placed at (x,y) using the\r
+ * current background color.\r
+ */\r
+ public void clearRect(int x, int y, int width, int height)\r
+ {\r
+ Color originalColor = getColor();\r
+\r
+ setColor(getBackground());\r
+ Shape shape = new Rectangle(x, y, width, height);\r
+ draw(shape, "fill");\r
+\r
+ setColor(originalColor);\r
+ }\r
+\r
+ /**\r
+ * Draws a rounded rectangle.\r
+ */\r
+ public void drawRoundRect(int x, int y, int width, int height, int arcWidth,\r
+ int arcHeight)\r
+ {\r
+ Shape shape = new RoundRectangle2D.Float(x, y, width, height, arcWidth,\r
+ arcHeight);\r
+ draw(shape);\r
+ }\r
+\r
+ /**\r
+ * Fills a rounded rectangle.\r
+ */\r
+ public void fillRoundRect(int x, int y, int width, int height, int arcWidth,\r
+ int arcHeight)\r
+ {\r
+ Shape shape = new RoundRectangle2D.Float(x, y, width, height, arcWidth,\r
+ arcHeight);\r
+ draw(shape, "fill");\r
+ }\r
+\r
+ /**\r
+ * Draws an oval.\r
+ */\r
+ public void drawOval(int x, int y, int width, int height)\r
+ {\r
+ Shape shape = new Ellipse2D.Float(x, y, width, height);\r
+ draw(shape);\r
+ }\r
+\r
+ /**\r
+ * Fills an oval.\r
+ */\r
+ public void fillOval(int x, int y, int width, int height)\r
+ {\r
+ Shape shape = new Ellipse2D.Float(x, y, width, height);\r
+ draw(shape, "fill");\r
+ }\r
+\r
+ /**\r
+ * Draws an arc.\r
+ */\r
+ public void drawArc(int x, int y, int width, int height, int startAngle,\r
+ int arcAngle)\r
+ {\r
+ Shape shape = new Arc2D.Float(x, y, width, height, startAngle, arcAngle,\r
+ Arc2D.OPEN);\r
+ draw(shape);\r
+ }\r
+\r
+ /**\r
+ * Fills an arc.\r
+ */\r
+ public void fillArc(int x, int y, int width, int height, int startAngle,\r
+ int arcAngle)\r
+ {\r
+ Shape shape = new Arc2D.Float(x, y, width, height, startAngle, arcAngle,\r
+ Arc2D.PIE);\r
+ draw(shape, "fill");\r
+ }\r
+\r
+ /**\r
+ * Draws a polyline.\r
+ */\r
+ public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)\r
+ {\r
+ if (nPoints > 0)\r
+ {\r
+ GeneralPath path = new GeneralPath();\r
+ path.moveTo(xPoints[0], yPoints[0]);\r
+ for (int i = 1; i < nPoints; i++)\r
+ {\r
+ path.lineTo(xPoints[i], yPoints[i]);\r
+ }\r
+ draw(path);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Draws a polygon made with the specified points.\r
+ */\r
+ public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)\r
+ {\r
+ Shape shape = new Polygon(xPoints, yPoints, nPoints);\r
+ draw(shape);\r
+ }\r
+\r
+ /**\r
+ * Draws a polygon.\r
+ */\r
+ public void drawPolygon(Polygon p)\r
+ {\r
+ draw(p);\r
+ }\r
+\r
+ /**\r
+ * Fills a polygon made with the specified points.\r
+ */\r
+ public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)\r
+ {\r
+ Shape shape = new Polygon(xPoints, yPoints, nPoints);\r
+ draw(shape, "fill");\r
+ }\r
+\r
+ /**\r
+ * Fills a polygon.\r
+ */\r
+ public void fillPolygon(Polygon p)\r
+ {\r
+ draw(p, "fill");\r
+ }\r
+\r
+ /**\r
+ * Draws the specified characters, starting from (x,y)\r
+ */\r
+ public void drawChars(char[] data, int offset, int length, int x, int y)\r
+ {\r
+ String string = new String(data, offset, length);\r
+ drawString(string, x, y);\r
+ }\r
+\r
+ /**\r
+ * Draws the specified bytes, starting from (x,y)\r
+ */\r
+ public void drawBytes(byte[] data, int offset, int length, int x, int y)\r
+ {\r
+ String string = new String(data, offset, length);\r
+ drawString(string, x, y);\r
+ }\r
+\r
+ /**\r
+ * Draws an image.\r
+ */\r
+ public boolean drawImage(Image img, int x, int y, ImageObserver observer)\r
+ {\r
+ return drawImage(img, x, y, Color.white, observer);\r
+ }\r
+\r
+ /**\r
+ * Draws an image.\r
+ */\r
+ public boolean drawImage(Image img, int x, int y, int width, int height,\r
+ ImageObserver observer)\r
+ {\r
+ return drawImage(img, x, y, width, height, Color.white, observer);\r
+ }\r
+\r
+ /**\r
+ * Draws an image.\r
+ */\r
+ public boolean drawImage(Image img, int x, int y, Color bgcolor,\r
+ ImageObserver observer)\r
+ {\r
+ int width = img.getWidth(null);\r
+ int height = img.getHeight(null);\r
+ return drawImage(img, x, y, width, height, bgcolor, observer);\r
+ }\r
+\r
+ /**\r
+ * Draws an image.\r
+ */\r
+ public boolean drawImage(Image img, int x, int y, int width, int height,\r
+ Color bgcolor, ImageObserver observer)\r
+ {\r
+ return drawImage(img, x, y, x + width, y + height, 0, 0, width, height,\r
+ bgcolor, observer);\r
+ }\r
+\r
+ /**\r
+ * Draws an image.\r
+ */\r
+ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,\r
+ int sx1, int sy1, int sx2, int sy2,\r
+ ImageObserver observer)\r
+ {\r
+ return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, Color.white,\r
+ observer);\r
+ }\r
+\r
+ /**\r
+ * Draws an image.\r
+ */\r
+ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,\r
+ int sx1, int sy1, int sx2, int sy2, Color bgcolor,\r
+ ImageObserver observer)\r
+ {\r
+ if (dx1 >= dx2)\r
+ {\r
+ throw new IllegalArgumentException("dx1 >= dx2");\r
+ }\r
+ if (sx1 >= sx2)\r
+ {\r
+ throw new IllegalArgumentException("sx1 >= sx2");\r
+ }\r
+ if (dy1 >= dy2)\r
+ {\r
+ throw new IllegalArgumentException("dy1 >= dy2");\r
+ }\r
+ if (sy1 >= sy2)\r
+ {\r
+ throw new IllegalArgumentException("sy1 >= sy2");\r
+ }\r
+\r
+ append("gsave");\r
+\r
+ int width = sx2 - sx1;\r
+ int height = sy2 - sy1;\r
+ int destWidth = dx2 - dx1;\r
+ int destHeight = dy2 - dy1;\r
+\r
+ int[] pixels = new int[width * height];\r
+ PixelGrabber pg = new PixelGrabber(img, sx1, sy1, sx2 - sx1, sy2 - sy1,\r
+ pixels, 0, width);\r
+ try\r
+ {\r
+ pg.grabPixels();\r
+ }\r
+ catch (InterruptedException e)\r
+ {\r
+ return false;\r
+ }\r
+\r
+ AffineTransform matrix = new AffineTransform(_transform);\r
+ matrix.translate(dx1, dy1);\r
+ matrix.scale(destWidth / (double) width, destHeight / (double) height);\r
+ double[] m = new double[6];\r
+ try\r
+ {\r
+ matrix = matrix.createInverse();\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ throw new EpsException("Unable to get inverse of matrix: " + matrix);\r
+ }\r
+ matrix.scale(1, -1);\r
+ matrix.getMatrix(m);\r
+ append(width + " " + height + " 8 [" + m[0] + " " + m[1] + " " + m[2] + " " +\r
+ m[3] + " " + m[4] + " " + m[5] + "]");\r
+ // Fill the background to update the bounding box.\r
+ Color oldColor = getColor();\r
+ setColor(getBackground());\r
+ fillRect(dx1, dy1, destWidth, destHeight);\r
+ setColor(oldColor);\r
+ append("{currentfile 3 " + width + " mul string readhexstring pop} bind");\r
+ append("false 3 colorimage");\r
+ StringBuffer line = new StringBuffer();\r
+ for (int y = 0; y < height; y++)\r
+ {\r
+ for (int x = 0; x < width; x++)\r
+ {\r
+ Color color = new Color(pixels[x + width * y]);\r
+ line.append(toHexString(color.getRed()) + toHexString(color.getGreen()) +\r
+ toHexString(color.getBlue()));\r
+ if (line.length() > 64)\r
+ {\r
+ append(line.toString());\r
+ line = new StringBuffer();\r
}\r
- Rectangle rect = getClipBounds();\r
- r.setLocation((int) rect.getX(), (int) rect.getY());\r
- r.setSize((int) rect.getWidth(), (int) rect.getHeight());\r
- return r;\r
- }\r
-\r
-\r
- private Color _color;\r
- private Color _backgroundColor;\r
- private Paint _paint;\r
- private Composite _composite;\r
- private BasicStroke _stroke;\r
- private Font _font;\r
- private Shape _clip;\r
- private AffineTransform _clipTransform;\r
- private AffineTransform _transform;\r
- private boolean _accurateTextMode;\r
-\r
- private EpsDocument _document;\r
-\r
- private static FontRenderContext _fontRenderContext = new FontRenderContext(null, false, true);\r
+ }\r
+ }\r
+ if (line.length() > 0)\r
+ {\r
+ append(line.toString());\r
+ }\r
+\r
+ append("grestore");\r
+\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Disposes of all resources used by this EpsGraphics2D object.\r
+ * If this is the only remaining EpsGraphics2D instance pointing at\r
+ * a EpsDocument object, then the EpsDocument object shall become\r
+ * eligible for garbage collection.\r
+ */\r
+ public void dispose()\r
+ {\r
+ _document = null;\r
+ }\r
+\r
+ /**\r
+ * Finalizes the object.\r
+ */\r
+ public void finalize()\r
+ {\r
+ super.finalize();\r
+ }\r
+\r
+ /**\r
+ * Returns the entire contents of the EPS document, complete with\r
+ * headers and bounding box. The returned String is suitable for\r
+ * being written directly to disk as an EPS file.\r
+ */\r
+ public String toString()\r
+ {\r
+ StringWriter writer = new StringWriter();\r
+ try\r
+ {\r
+ _document.write(writer);\r
+ _document.flush();\r
+ _document.close();\r
+ }\r
+ catch (IOException e)\r
+ {\r
+ throw new EpsException(e.toString());\r
+ }\r
+ return writer.toString();\r
+ }\r
+\r
+ /**\r
+ * Returns true if the specified rectangular area might intersect the\r
+ * current clipping area.\r
+ */\r
+ public boolean hitClip(int x, int y, int width, int height)\r
+ {\r
+ if (_clip == null)\r
+ {\r
+ return true;\r
+ }\r
+ Rectangle rect = new Rectangle(x, y, width, height);\r
+ return hit(rect, _clip, true);\r
+ }\r
+\r
+ /**\r
+ * Returns the bounding rectangle of the current clipping area.\r
+ */\r
+ public Rectangle getClipBounds(Rectangle r)\r
+ {\r
+ if (_clip == null)\r
+ {\r
+ return r;\r
+ }\r
+ Rectangle rect = getClipBounds();\r
+ r.setLocation( (int) rect.getX(), (int) rect.getY());\r
+ r.setSize( (int) rect.getWidth(), (int) rect.getHeight());\r
+ return r;\r
+ }\r
+\r
+ private Color _color;\r
+ private Color _backgroundColor;\r
+ private Paint _paint;\r
+ private Composite _composite;\r
+ private BasicStroke _stroke;\r
+ private Font _font;\r
+ private Shape _clip;\r
+ private AffineTransform _clipTransform;\r
+ private AffineTransform _transform;\r
+ private boolean _accurateTextMode;\r
+\r
+ private EpsDocument _document;\r
+\r
+ private static FontRenderContext _fontRenderContext = new FontRenderContext(null, false, true);\r
}
\ No newline at end of file