0001: /*
0002: * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004: *
0005: * This code is free software; you can redistribute it and/or modify it
0006: * under the terms of the GNU General Public License version 2 only, as
0007: * published by the Free Software Foundation. Sun designates this
0008: * particular file as subject to the "Classpath" exception as provided
0009: * by Sun in the LICENSE file that accompanied this code.
0010: *
0011: * This code is distributed in the hope that it will be useful, but WITHOUT
0012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014: * version 2 for more details (a copy is included in the LICENSE file that
0015: * accompanied this code).
0016: *
0017: * You should have received a copy of the GNU General Public License version
0018: * 2 along with this work; if not, write to the Free Software Foundation,
0019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022: * CA 95054 USA or visit www.sun.com if you need additional information or
0023: * have any questions.
0024: */
0025:
0026: package sun.print;
0027:
0028: import java.util.Map;
0029:
0030: import java.awt.BasicStroke;
0031: import java.awt.Color;
0032: import java.awt.Composite;
0033: import java.awt.Graphics;
0034: import java.awt.Graphics2D;
0035: import java.awt.Font;
0036: import java.awt.FontMetrics;
0037: import java.awt.font.FontRenderContext;
0038: import java.awt.Graphics;
0039: import java.awt.GraphicsConfiguration;
0040: import java.awt.Image;
0041: import java.awt.Paint;
0042: import java.awt.Rectangle;
0043: import java.awt.Shape;
0044: import java.awt.Stroke;
0045: import java.awt.RenderingHints;
0046: import java.awt.RenderingHints.Key;
0047:
0048: import java.awt.font.GlyphVector;
0049: import java.awt.font.TextLayout;
0050:
0051: import java.awt.geom.AffineTransform;
0052: import java.awt.geom.Line2D;
0053: import java.awt.geom.Point2D;
0054: import java.awt.geom.Rectangle2D;
0055: import java.awt.geom.RoundRectangle2D;
0056: import java.awt.image.BufferedImage;
0057: import java.awt.image.BufferedImageOp;
0058: import java.awt.image.ImageObserver;
0059: import java.awt.image.RenderedImage;
0060: import java.awt.image.renderable.RenderableImage;
0061: import java.awt.print.PrinterGraphics;
0062: import java.awt.print.PrinterJob;
0063:
0064: import java.text.AttributedCharacterIterator;
0065:
0066: import sun.java2d.Spans;
0067:
0068: public class PeekGraphics extends Graphics2D implements
0069: PrinterGraphics, ImageObserver, Cloneable {
0070:
0071: /**
0072: * Drawing methods will be forwarded to this object.
0073: */
0074: Graphics2D mGraphics;
0075:
0076: /**
0077: * The PrinterJob controlling the current printing.
0078: */
0079: PrinterJob mPrinterJob;
0080:
0081: /**
0082: * Keeps track of where drawing occurs on the page.
0083: */
0084: private Spans mDrawingArea = new Spans();
0085:
0086: /**
0087: * Track information about the types of drawing
0088: * performed by the printing application.
0089: */
0090: private PeekMetrics mPrintMetrics = new PeekMetrics();
0091:
0092: /**
0093: * If true the application will only be drawing AWT style
0094: * graphics, no Java2D graphics.
0095: */
0096: private boolean mAWTDrawingOnly = false;
0097:
0098: /**
0099: * The new PeekGraphics2D will forward state changing
0100: * calls to 'graphics'. 'printerJob' is stored away
0101: * so that the printing application can get the PrinterJob
0102: * if needed.
0103: */
0104: public PeekGraphics(Graphics2D graphics, PrinterJob printerJob) {
0105:
0106: mGraphics = graphics;
0107: mPrinterJob = printerJob;
0108: }
0109:
0110: /**
0111: * Return the Graphics2D object that does the drawing
0112: * for this instance.
0113: */
0114: public Graphics2D getDelegate() {
0115: return mGraphics;
0116: }
0117:
0118: /**
0119: * Set the Graphics2D instance which will do the
0120: * drawing.
0121: */
0122: public void setDelegate(Graphics2D graphics) {
0123: mGraphics = graphics;
0124: }
0125:
0126: public PrinterJob getPrinterJob() {
0127: return mPrinterJob;
0128: }
0129:
0130: /**
0131: * The caller promises that only AWT graphics will be drawn.
0132: * The print system can use this information to make general
0133: * assumptions about the types of graphics to be drawn without
0134: * requiring the application to draw the contents multiple
0135: * times.
0136: */
0137: public void setAWTDrawingOnly() {
0138: mAWTDrawingOnly = true;
0139: }
0140:
0141: public boolean getAWTDrawingOnly() {
0142: return mAWTDrawingOnly;
0143: }
0144:
0145: /**
0146: * Return a Spans instance describing the parts of the page in
0147: * to which drawing occurred.
0148: */
0149: public Spans getDrawingArea() {
0150: return mDrawingArea;
0151: }
0152:
0153: /**
0154: * Returns the device configuration associated with this Graphics2D.
0155: */
0156: public GraphicsConfiguration getDeviceConfiguration() {
0157: return ((RasterPrinterJob) mPrinterJob)
0158: .getPrinterGraphicsConfig();
0159: }
0160:
0161: /* The Delegated Graphics Methods */
0162:
0163: /**
0164: * Creates a new <code>Graphics</code> object that is
0165: * a copy of this <code>Graphics</code> object.
0166: * @return a new graphics context that is a copy of
0167: * this graphics context.
0168: * @since JDK1.0
0169: */
0170: public Graphics create() {
0171: PeekGraphics newGraphics = null;
0172:
0173: try {
0174: newGraphics = (PeekGraphics) clone();
0175: newGraphics.mGraphics = (Graphics2D) mGraphics.create();
0176:
0177: /* This exception can not happen unless this
0178: * class no longer implements the Cloneable
0179: * interface.
0180: */
0181: } catch (CloneNotSupportedException e) {
0182: // can never happen.
0183: }
0184:
0185: return newGraphics;
0186: }
0187:
0188: /**
0189: * Translates the origin of the graphics context to the point
0190: * (<i>x</i>, <i>y</i>) in the current coordinate system.
0191: * Modifies this graphics context so that its new origin corresponds
0192: * to the point (<i>x</i>, <i>y</i>) in this graphics context's
0193: * original coordinate system. All coordinates used in subsequent
0194: * rendering operations on this graphics context will be relative
0195: * to this new origin.
0196: * @param x the <i>x</i> coordinate.
0197: * @param y the <i>y</i> coordinate.
0198: * @since JDK1.0
0199: */
0200: public void translate(int x, int y) {
0201: mGraphics.translate(x, y);
0202: }
0203:
0204: /**
0205: * Concatenates the current transform of this Graphics2D with a
0206: * translation transformation.
0207: * This is equivalent to calling transform(T), where T is an
0208: * AffineTransform represented by the following matrix:
0209: * <pre>
0210: * [ 1 0 tx ]
0211: * [ 0 1 ty ]
0212: * [ 0 0 1 ]
0213: * </pre>
0214: */
0215: public void translate(double tx, double ty) {
0216: mGraphics.translate(tx, ty);
0217: }
0218:
0219: /**
0220: * Concatenates the current transform of this Graphics2D with a
0221: * rotation transformation.
0222: * This is equivalent to calling transform(R), where R is an
0223: * AffineTransform represented by the following matrix:
0224: * <pre>
0225: * [ cos(theta) -sin(theta) 0 ]
0226: * [ sin(theta) cos(theta) 0 ]
0227: * [ 0 0 1 ]
0228: * </pre>
0229: * Rotating with a positive angle theta rotates points on the positive
0230: * x axis toward the positive y axis.
0231: * @param theta The angle of rotation in radians.
0232: */
0233: public void rotate(double theta) {
0234: mGraphics.rotate(theta);
0235: }
0236:
0237: /**
0238: * Concatenates the current transform of this Graphics2D with a
0239: * translated rotation transformation.
0240: * This is equivalent to the following sequence of calls:
0241: * <pre>
0242: * translate(x, y);
0243: * rotate(theta);
0244: * translate(-x, -y);
0245: * </pre>
0246: * Rotating with a positive angle theta rotates points on the positive
0247: * x axis toward the positive y axis.
0248: * @param theta The angle of rotation in radians.
0249: * @param x The x coordinate of the origin of the rotation
0250: * @param y The x coordinate of the origin of the rotation
0251: */
0252: public void rotate(double theta, double x, double y) {
0253: mGraphics.rotate(theta, x, y);
0254: }
0255:
0256: /**
0257: * Concatenates the current transform of this Graphics2D with a
0258: * scaling transformation.
0259: * This is equivalent to calling transform(S), where S is an
0260: * AffineTransform represented by the following matrix:
0261: * <pre>
0262: * [ sx 0 0 ]
0263: * [ 0 sy 0 ]
0264: * [ 0 0 1 ]
0265: * </pre>
0266: */
0267: public void scale(double sx, double sy) {
0268: mGraphics.scale(sx, sy);
0269: }
0270:
0271: /**
0272: * Concatenates the current transform of this Graphics2D with a
0273: * shearing transformation.
0274: * This is equivalent to calling transform(SH), where SH is an
0275: * AffineTransform represented by the following matrix:
0276: * <pre>
0277: * [ 1 shx 0 ]
0278: * [ shy 1 0 ]
0279: * [ 0 0 1 ]
0280: * </pre>
0281: * @param shx The factor by which coordinates are shifted towards the
0282: * positive X axis direction according to their Y coordinate
0283: * @param shy The factor by which coordinates are shifted towards the
0284: * positive Y axis direction according to their X coordinate
0285: */
0286: public void shear(double shx, double shy) {
0287: mGraphics.shear(shx, shy);
0288: }
0289:
0290: /**
0291: * Gets this graphics context's current color.
0292: * @return this graphics context's current color.
0293: * @see java.awt.Color
0294: * @see java.awt.Graphics#setColor
0295: * @since JDK1.0
0296: */
0297: public Color getColor() {
0298: return mGraphics.getColor();
0299: }
0300:
0301: /**
0302: * Sets this graphics context's current color to the specified
0303: * color. All subsequent graphics operations using this graphics
0304: * context use this specified color.
0305: * @param c the new rendering color.
0306: * @see java.awt.Color
0307: * @see java.awt.Graphics#getColor
0308: * @since JDK1.0
0309: */
0310: public void setColor(Color c) {
0311: mGraphics.setColor(c);
0312: }
0313:
0314: /**
0315: * Sets the paint mode of this graphics context to overwrite the
0316: * destination with this graphics context's current color.
0317: * This sets the logical pixel operation function to the paint or
0318: * overwrite mode. All subsequent rendering operations will
0319: * overwrite the destination with the current color.
0320: * @since JDK1.0
0321: */
0322: public void setPaintMode() {
0323: mGraphics.setPaintMode();
0324: }
0325:
0326: /**
0327: * Sets the paint mode of this graphics context to alternate between
0328: * this graphics context's current color and the new specified color.
0329: * This specifies that logical pixel operations are performed in the
0330: * XOR mode, which alternates pixels between the current color and
0331: * a specified XOR color.
0332: * <p>
0333: * When drawing operations are performed, pixels which are the
0334: * current color are changed to the specified color, and vice versa.
0335: * <p>
0336: * Pixels that are of colors other than those two colors are changed
0337: * in an unpredictable but reversible manner; if the same figure is
0338: * drawn twice, then all pixels are restored to their original values.
0339: * @param c1 the XOR alternation color
0340: * @since JDK1.0
0341: */
0342: public void setXORMode(Color c1) {
0343: mGraphics.setXORMode(c1);
0344: }
0345:
0346: /**
0347: * Gets the current font.
0348: * @return this graphics context's current font.
0349: * @see java.awt.Font
0350: * @see java.awt.Graphics#setFont
0351: * @since JDK1.0
0352: */
0353: public Font getFont() {
0354: return mGraphics.getFont();
0355: }
0356:
0357: /**
0358: * Sets this graphics context's font to the specified font.
0359: * All subsequent text operations using this graphics context
0360: * use this font.
0361: * @param font the font.
0362: * @see java.awt.Graphics#getFont
0363: * @see java.awt.Graphics#drawChars(java.lang.String, int, int)
0364: * @see java.awt.Graphics#drawString(byte[], int, int, int, int)
0365: * @see java.awt.Graphics#drawBytes(char[], int, int, int, int)
0366: * @since JDK1.0
0367: */
0368: public void setFont(Font font) {
0369: mGraphics.setFont(font);
0370: }
0371:
0372: /**
0373: * Gets the font metrics for the specified font.
0374: * @return the font metrics for the specified font.
0375: * @param f the specified font
0376: * @see java.awt.Graphics#getFont
0377: * @see java.awt.FontMetrics
0378: * @see java.awt.Graphics#getFontMetrics()
0379: * @since JDK1.0
0380: */
0381: public FontMetrics getFontMetrics(Font f) {
0382: return mGraphics.getFontMetrics(f);
0383: }
0384:
0385: /**
0386: * Get the rendering context of the font
0387: * within this Graphics2D context.
0388: */
0389: public FontRenderContext getFontRenderContext() {
0390: return mGraphics.getFontRenderContext();
0391: }
0392:
0393: /**
0394: * Returns the bounding rectangle of the current clipping area.
0395: * The coordinates in the rectangle are relative to the coordinate
0396: * system origin of this graphics context.
0397: * @return the bounding rectangle of the current clipping area.
0398: * @see java.awt.Graphics#getClip
0399: * @see java.awt.Graphics#clipRect
0400: * @see java.awt.Graphics#setClip(int, int, int, int)
0401: * @see java.awt.Graphics#setClip(Shape)
0402: * @since JDK1.1
0403: */
0404: public Rectangle getClipBounds() {
0405: return mGraphics.getClipBounds();
0406: }
0407:
0408: /**
0409: * Intersects the current clip with the specified rectangle.
0410: * The resulting clipping area is the intersection of the current
0411: * clipping area and the specified rectangle.
0412: * This method can only be used to make the current clip smaller.
0413: * To set the current clip larger, use any of the setClip methods.
0414: * Rendering operations have no effect outside of the clipping area.
0415: * @param x the x coordinate of the rectangle to intersect the clip with
0416: * @param y the y coordinate of the rectangle to intersect the clip with
0417: * @param width the width of the rectangle to intersect the clip with
0418: * @param height the height of the rectangle to intersect the clip with
0419: * @see #setClip(int, int, int, int)
0420: * @see #setClip(Shape)
0421: */
0422: public void clipRect(int x, int y, int width, int height) {
0423: mGraphics.clipRect(x, y, width, height);
0424: }
0425:
0426: /**
0427: * Sets the current clip to the rectangle specified by the given
0428: * coordinates.
0429: * Rendering operations have no effect outside of the clipping area.
0430: * @param x the <i>x</i> coordinate of the new clip rectangle.
0431: * @param y the <i>y</i> coordinate of the new clip rectangle.
0432: * @param width the width of the new clip rectangle.
0433: * @param height the height of the new clip rectangle.
0434: * @see java.awt.Graphics#clipRect
0435: * @see java.awt.Graphics#setClip(Shape)
0436: * @since JDK1.1
0437: */
0438: public void setClip(int x, int y, int width, int height) {
0439: mGraphics.setClip(x, y, width, height);
0440: }
0441:
0442: /**
0443: * Gets the current clipping area.
0444: * @return a <code>Shape</code> object representing the
0445: * current clipping area.
0446: * @see java.awt.Graphics#getClipBounds
0447: * @see java.awt.Graphics#clipRect
0448: * @see java.awt.Graphics#setClip(int, int, int, int)
0449: * @see java.awt.Graphics#setClip(Shape)
0450: * @since JDK1.1
0451: */
0452: public Shape getClip() {
0453: return mGraphics.getClip();
0454: }
0455:
0456: /**
0457: * Sets the current clipping area to an arbitrary clip shape.
0458: * Not all objects which implement the <code>Shape</code>
0459: * interface can be used to set the clip. The only
0460: * <code>Shape</code> objects which are guaranteed to be
0461: * supported are <code>Shape</code> objects which are
0462: * obtained via the <code>getClip</code> method and via
0463: * <code>Rectangle</code> objects.
0464: * @see java.awt.Graphics#getClip()
0465: * @see java.awt.Graphics#clipRect
0466: * @see java.awt.Graphics#setClip(int, int, int, int)
0467: * @since JDK1.1
0468: */
0469: public void setClip(Shape clip) {
0470: mGraphics.setClip(clip);
0471: }
0472:
0473: /**
0474: * Copies an area of the component by a distance specified by
0475: * <code>dx</code> and <code>dy</code>. From the point specified
0476: * by <code>x</code> and <code>y</code>, this method
0477: * copies downwards and to the right. To copy an area of the
0478: * component to the left or upwards, specify a negative value for
0479: * <code>dx</code> or <code>dy</code>.
0480: * If a portion of the source rectangle lies outside the bounds
0481: * of the component, or is obscured by another window or component,
0482: * <code>copyArea</code> will be unable to copy the associated
0483: * pixels. The area that is omitted can be refreshed by calling
0484: * the component's <code>paint</code> method.
0485: * @param x the <i>x</i> coordinate of the source rectangle.
0486: * @param y the <i>y</i> coordinate of the source rectangle.
0487: * @param width the width of the source rectangle.
0488: * @param height the height of the source rectangle.
0489: * @param dx the horizontal distance to copy the pixels.
0490: * @param dy the vertical distance to copy the pixels.
0491: * @since JDK1.0
0492: */
0493: public void copyArea(int x, int y, int width, int height, int dx,
0494: int dy) {
0495: // This method is not supported for printing so we do nothing here.
0496: }
0497:
0498: /**
0499: * Draws a line, using the current color, between the points
0500: * <code>(x1, y1)</code> and <code>(x2, y2)</code>
0501: * in this graphics context's coordinate system.
0502: * @param x1 the first point's <i>x</i> coordinate.
0503: * @param y1 the first point's <i>y</i> coordinate.
0504: * @param x2 the second point's <i>x</i> coordinate.
0505: * @param y2 the second point's <i>y</i> coordinate.
0506: * @since JDK1.0
0507: */
0508: public void drawLine(int x1, int y1, int x2, int y2) {
0509: addStrokeShape(new Line2D.Float(x1, y1, x2, y2));
0510: mPrintMetrics.draw(this );
0511: }
0512:
0513: /**
0514: * Fills the specified rectangle.
0515: * The left and right edges of the rectangle are at
0516: * <code>x</code> and <code>x + width - 1</code>.
0517: * The top and bottom edges are at
0518: * <code>y</code> and <code>y + height - 1</code>.
0519: * The resulting rectangle covers an area
0520: * <code>width</code> pixels wide by
0521: * <code>height</code> pixels tall.
0522: * The rectangle is filled using the graphics context's current color.
0523: * @param x the <i>x</i> coordinate
0524: * of the rectangle to be filled.
0525: * @param y the <i>y</i> coordinate
0526: * of the rectangle to be filled.
0527: * @param width the width of the rectangle to be filled.
0528: * @param height the height of the rectangle to be filled.
0529: * @see java.awt.Graphics#fillRect
0530: * @see java.awt.Graphics#clearRect
0531: * @since JDK1.0
0532: */
0533: public void fillRect(int x, int y, int width, int height) {
0534:
0535: addDrawingRect(new Rectangle2D.Float(x, y, width, height));
0536: mPrintMetrics.fill(this );
0537:
0538: }
0539:
0540: /**
0541: * Clears the specified rectangle by filling it with the background
0542: * color of the current drawing surface. This operation does not
0543: * use the current paint mode.
0544: * <p>
0545: * Beginning with Java 1.1, the background color
0546: * of offscreen images may be system dependent. Applications should
0547: * use <code>setColor</code> followed by <code>fillRect</code> to
0548: * ensure that an offscreen image is cleared to a specific color.
0549: * @param x the <i>x</i> coordinate of the rectangle to clear.
0550: * @param y the <i>y</i> coordinate of the rectangle to clear.
0551: * @param width the width of the rectangle to clear.
0552: * @param height the height of the rectangle to clear.
0553: * @see java.awt.Graphics#fillRect(int, int, int, int)
0554: * @see java.awt.Graphics#drawRect
0555: * @see java.awt.Graphics#setColor(java.awt.Color)
0556: * @see java.awt.Graphics#setPaintMode
0557: * @see java.awt.Graphics#setXORMode(java.awt.Color)
0558: * @since JDK1.0
0559: */
0560: public void clearRect(int x, int y, int width, int height) {
0561: Rectangle2D.Float rect = new Rectangle2D.Float(x, y, width,
0562: height);
0563: addDrawingRect(rect);
0564: mPrintMetrics.clear(this );
0565: }
0566:
0567: /**
0568: * Draws an outlined round-cornered rectangle using this graphics
0569: * context's current color. The left and right edges of the rectangle
0570: * are at <code>x</code> and <code>x + width</code>,
0571: * respectively. The top and bottom edges of the rectangle are at
0572: * <code>y</code> and <code>y + height</code>.
0573: * @param x the <i>x</i> coordinate of the rectangle to be drawn.
0574: * @param y the <i>y</i> coordinate of the rectangle to be drawn.
0575: * @param width the width of the rectangle to be drawn.
0576: * @param height the height of the rectangle to be drawn.
0577: * @param arcWidth the horizontal diameter of the arc
0578: * at the four corners.
0579: * @param arcHeight the vertical diameter of the arc
0580: * at the four corners.
0581: * @see java.awt.Graphics#fillRoundRect
0582: * @since JDK1.0
0583: */
0584: public void drawRoundRect(int x, int y, int width, int height,
0585: int arcWidth, int arcHeight) {
0586: addStrokeShape(new RoundRectangle2D.Float(x, y, width, height,
0587: arcWidth, arcHeight));
0588: mPrintMetrics.draw(this );
0589:
0590: }
0591:
0592: /**
0593: * Fills the specified rounded corner rectangle with the current color.
0594: * The left and right edges of the rectangle
0595: * are at <code>x</code> and <code>x + width - 1</code>,
0596: * respectively. The top and bottom edges of the rectangle are at
0597: * <code>y</code> and <code>y + height - 1</code>.
0598: * @param x the <i>x</i> coordinate of the rectangle to be filled.
0599: * @param y the <i>y</i> coordinate of the rectangle to be filled.
0600: * @param width the width of the rectangle to be filled.
0601: * @param height the height of the rectangle to be filled.
0602: * @param arcWidth the horizontal diameter
0603: * of the arc at the four corners.
0604: * @param arcHeight the vertical diameter
0605: * of the arc at the four corners.
0606: * @see java.awt.Graphics#drawRoundRect
0607: * @since JDK1.0
0608: */
0609: public void fillRoundRect(int x, int y, int width, int height,
0610: int arcWidth, int arcHeight) {
0611: Rectangle2D.Float rect = new Rectangle2D.Float(x, y, width,
0612: height);
0613: addDrawingRect(rect);
0614: mPrintMetrics.fill(this );
0615: }
0616:
0617: /**
0618: * Draws the outline of an oval.
0619: * The result is a circle or ellipse that fits within the
0620: * rectangle specified by the <code>x</code>, <code>y</code>,
0621: * <code>width</code>, and <code>height</code> arguments.
0622: * <p>
0623: * The oval covers an area that is
0624: * <code>width + 1</code> pixels wide
0625: * and <code>height + 1</code> pixels tall.
0626: * @param x the <i>x</i> coordinate of the upper left
0627: * corner of the oval to be drawn.
0628: * @param y the <i>y</i> coordinate of the upper left
0629: * corner of the oval to be drawn.
0630: * @param width the width of the oval to be drawn.
0631: * @param height the height of the oval to be drawn.
0632: * @see java.awt.Graphics#fillOval
0633: * @since JDK1.0
0634: */
0635: public void drawOval(int x, int y, int width, int height) {
0636: addStrokeShape(new Rectangle2D.Float(x, y, width, height));
0637: mPrintMetrics.draw(this );
0638: }
0639:
0640: /**
0641: * Fills an oval bounded by the specified rectangle with the
0642: * current color.
0643: * @param x the <i>x</i> coordinate of the upper left corner
0644: * of the oval to be filled.
0645: * @param y the <i>y</i> coordinate of the upper left corner
0646: * of the oval to be filled.
0647: * @param width the width of the oval to be filled.
0648: * @param height the height of the oval to be filled.
0649: * @see java.awt.Graphics#drawOval
0650: * @since JDK1.0
0651: */
0652: public void fillOval(int x, int y, int width, int height) {
0653: Rectangle2D.Float rect = new Rectangle2D.Float(x, y, width,
0654: height);
0655: addDrawingRect(rect);
0656: mPrintMetrics.fill(this );
0657:
0658: }
0659:
0660: /**
0661: * Draws the outline of a circular or elliptical arc
0662: * covering the specified rectangle.
0663: * <p>
0664: * The resulting arc begins at <code>startAngle</code> and extends
0665: * for <code>arcAngle</code> degrees, using the current color.
0666: * Angles are interpreted such that 0 degrees
0667: * is at the 3 o'clock position.
0668: * A positive value indicates a counter-clockwise rotation
0669: * while a negative value indicates a clockwise rotation.
0670: * <p>
0671: * The center of the arc is the center of the rectangle whose origin
0672: * is (<i>x</i>, <i>y</i>) and whose size is specified by the
0673: * <code>width</code> and <code>height</code> arguments.
0674: * <p>
0675: * The resulting arc covers an area
0676: * <code>width + 1</code> pixels wide
0677: * by <code>height + 1</code> pixels tall.
0678: * @param x the <i>x</i> coordinate of the
0679: * upper-left corner of the arc to be drawn.
0680: * @param y the <i>y</i> coordinate of the
0681: * upper-left corner of the arc to be drawn.
0682: * @param width the width of the arc to be drawn.
0683: * @param height the height of the arc to be drawn.
0684: * @param startAngle the beginning angle.
0685: * @param arcAngle the angular extent of the arc,
0686: * relative to the start angle.
0687: * @see java.awt.Graphics#fillArc
0688: * @since JDK1.0
0689: */
0690: public void drawArc(int x, int y, int width, int height,
0691: int startAngle, int arcAngle) {
0692: addStrokeShape(new Rectangle2D.Float(x, y, width, height));
0693: mPrintMetrics.draw(this );
0694:
0695: }
0696:
0697: /**
0698: * Fills a circular or elliptical arc covering the specified rectangle.
0699: * <p>
0700: * The resulting arc begins at <code>startAngle</code> and extends
0701: * for <code>arcAngle</code> degrees.
0702: * Angles are interpreted such that 0 degrees
0703: * is at the 3 o'clock position.
0704: * A positive value indicates a counter-clockwise rotation
0705: * while a negative value indicates a clockwise rotation.
0706: * <p>
0707: * The center of the arc is the center of the rectangle whose origin
0708: * is (<i>x</i>, <i>y</i>) and whose size is specified by the
0709: * <code>width</code> and <code>height</code> arguments.
0710: * <p>
0711: * The resulting arc covers an area
0712: * <code>width + 1</code> pixels wide
0713: * by <code>height + 1</code> pixels tall.
0714: * @param x the <i>x</i> coordinate of the
0715: * upper-left corner of the arc to be filled.
0716: * @param y the <i>y</i> coordinate of the
0717: * upper-left corner of the arc to be filled.
0718: * @param width the width of the arc to be filled.
0719: * @param height the height of the arc to be filled.
0720: * @param startAngle the beginning angle.
0721: * @param arcAngle the angular extent of the arc,
0722: * relative to the start angle.
0723: * @see java.awt.Graphics#drawArc
0724: * @since JDK1.0
0725: */
0726: public void fillArc(int x, int y, int width, int height,
0727: int startAngle, int arcAngle) {
0728: Rectangle2D.Float rect = new Rectangle2D.Float(x, y, width,
0729: height);
0730: addDrawingRect(rect);
0731: mPrintMetrics.fill(this );
0732:
0733: }
0734:
0735: /**
0736: * Draws a sequence of connected lines defined by
0737: * arrays of <i>x</i> and <i>y</i> coordinates.
0738: * Each pair of (<i>x</i>, <i>y</i>) coordinates defines a point.
0739: * The figure is not closed if the first point
0740: * differs from the last point.
0741: * @param xPoints an array of <i>x</i> points
0742: * @param yPoints an array of <i>y</i> points
0743: * @param nPoints the total number of points
0744: * @see java.awt.Graphics#drawPolygon(int[], int[], int)
0745: * @since JDK1.1
0746: */
0747: public void drawPolyline(int xPoints[], int yPoints[], int nPoints) {
0748: if (nPoints > 0) {
0749: int x = xPoints[0];
0750: int y = yPoints[0];
0751:
0752: for (int i = 1; i < nPoints; i++) {
0753: drawLine(x, y, xPoints[i], yPoints[i]);
0754: x = xPoints[i];
0755: y = yPoints[i];
0756: }
0757: }
0758:
0759: }
0760:
0761: /**
0762: * Draws a closed polygon defined by
0763: * arrays of <i>x</i> and <i>y</i> coordinates.
0764: * Each pair of (<i>x</i>, <i>y</i>) coordinates defines a point.
0765: * <p>
0766: * This method draws the polygon defined by <code>nPoint</code> line
0767: * segments, where the first <code>nPoint - 1</code>
0768: * line segments are line segments from
0769: * <code>(xPoints[i - 1], yPoints[i - 1])</code>
0770: * to <code>(xPoints[i], yPoints[i])</code>, for
0771: * 1 ≤ <i>i</i> ≤ <code>nPoints</code>.
0772: * The figure is automatically closed by drawing a line connecting
0773: * the final point to the first point, if those points are different.
0774: * @param xPoints a an array of <code>x</code> coordinates.
0775: * @param yPoints a an array of <code>y</code> coordinates.
0776: * @param nPoints a the total number of points.
0777: * @see java.awt.Graphics#fillPolygon
0778: * @see java.awt.Graphics#drawPolyline
0779: * @since JDK1.0
0780: */
0781: public void drawPolygon(int xPoints[], int yPoints[], int nPoints) {
0782: if (nPoints > 0) {
0783: drawPolyline(xPoints, yPoints, nPoints);
0784: drawLine(xPoints[nPoints - 1], yPoints[nPoints - 1],
0785: xPoints[0], yPoints[0]);
0786: }
0787:
0788: }
0789:
0790: /**
0791: * Fills a closed polygon defined by
0792: * arrays of <i>x</i> and <i>y</i> coordinates.
0793: * <p>
0794: * This method draws the polygon defined by <code>nPoint</code> line
0795: * segments, where the first <code>nPoint - 1</code>
0796: * line segments are line segments from
0797: * <code>(xPoints[i - 1], yPoints[i - 1])</code>
0798: * to <code>(xPoints[i], yPoints[i])</code>, for
0799: * 1 ≤ <i>i</i> ≤ <code>nPoints</code>.
0800: * The figure is automatically closed by drawing a line connecting
0801: * the final point to the first point, if those points are different.
0802: * <p>
0803: * The area inside the polygon is defined using an
0804: * even-odd fill rule, also known as the alternating rule.
0805: * @param xPoints a an array of <code>x</code> coordinates.
0806: * @param yPoints a an array of <code>y</code> coordinates.
0807: * @param nPoints a the total number of points.
0808: * @see java.awt.Graphics#drawPolygon(int[], int[], int)
0809: * @since JDK1.0
0810: */
0811: public void fillPolygon(int xPoints[], int yPoints[], int nPoints) {
0812: if (nPoints > 0) {
0813: int minX = xPoints[0];
0814: int minY = yPoints[0];
0815: int maxX = xPoints[0];
0816: int maxY = yPoints[0];
0817:
0818: for (int i = 1; i < nPoints; i++) {
0819:
0820: if (xPoints[i] < minX) {
0821: minX = xPoints[i];
0822: } else if (xPoints[i] > maxX) {
0823: maxX = xPoints[i];
0824: }
0825:
0826: if (yPoints[i] < minY) {
0827: minY = yPoints[i];
0828: } else if (yPoints[i] > maxY) {
0829: maxY = yPoints[i];
0830: }
0831: }
0832:
0833: addDrawingRect(minX, minY, maxX - minX, maxY - minY);
0834: }
0835:
0836: mPrintMetrics.fill(this );
0837:
0838: }
0839:
0840: /**
0841: * Draws the text given by the specified string, using this
0842: * graphics context's current font and color. The baseline of the
0843: * first character is at position (<i>x</i>, <i>y</i>) in this
0844: * graphics context's coordinate system.
0845: * @param str the string to be drawn.
0846: * @param x the <i>x</i> coordinate.
0847: * @param y the <i>y</i> coordinate.
0848: * @see java.awt.Graphics#drawBytes
0849: * @see java.awt.Graphics#drawChars
0850: * @since JDK1.0
0851: */
0852: public void drawString(String str, int x, int y) {
0853:
0854: drawString(str, (float) x, (float) y);
0855: }
0856:
0857: /**
0858: * Draws the text given by the specified iterator, using this
0859: * graphics context's current color. The iterator has to specify a font
0860: * for each character. The baseline of the
0861: * first character is at position (<i>x</i>, <i>y</i>) in this
0862: * graphics context's coordinate system.
0863: * The rendering attributes applied include the clip, transform,
0864: * paint or color, and composite attributes.
0865: * For characters in script systems such as Hebrew and Arabic,
0866: * the glyphs may be draw from right to left, in which case the
0867: * coordinate supplied is the the location of the leftmost character
0868: * on the baseline.
0869: * @param iterator the iterator whose text is to be drawn
0870: * @param x,y the coordinates where the iterator's text should be drawn.
0871: * @see #setPaint
0872: * @see java.awt.Graphics#setColor
0873: * @see #setTransform
0874: * @see #setComposite
0875: * @see #setClip
0876: */
0877: public void drawString(AttributedCharacterIterator iterator, int x,
0878: int y) {
0879:
0880: drawString(iterator, (float) x, (float) y);
0881: }
0882:
0883: /**
0884: * Draws the text given by the specified iterator, using this
0885: * graphics context's current color. The iterator has to specify a font
0886: * for each character. The baseline of the
0887: * first character is at position (<i>x</i>, <i>y</i>) in this
0888: * graphics context's coordinate system.
0889: * The rendering attributes applied include the clip, transform,
0890: * paint or color, and composite attributes.
0891: * For characters in script systems such as Hebrew and Arabic,
0892: * the glyphs may be draw from right to left, in which case the
0893: * coordinate supplied is the the location of the leftmost character
0894: * on the baseline.
0895: * @param iterator the iterator whose text is to be drawn
0896: * @param x,y the coordinates where the iterator's text should be drawn.
0897: * @see #setPaint
0898: * @see java.awt.Graphics#setColor
0899: * @see #setTransform
0900: * @see #setComposite
0901: * @see #setClip
0902: */
0903: public void drawString(AttributedCharacterIterator iterator,
0904: float x, float y) {
0905: if (iterator == null) {
0906: throw new NullPointerException(
0907: "AttributedCharacterIterator is null");
0908: }
0909:
0910: TextLayout layout = new TextLayout(iterator,
0911: getFontRenderContext());
0912: layout.draw(this , x, y);
0913: }
0914:
0915: /**
0916: * Draws as much of the specified image as is currently available.
0917: * The image is drawn with its top-left corner at
0918: * (<i>x</i>, <i>y</i>) in this graphics context's coordinate
0919: * space. Transparent pixels in the image do not affect whatever
0920: * pixels are already there.
0921: * <p>
0922: * This method returns immediately in all cases, even if the
0923: * complete image has not yet been loaded, and it has not been dithered
0924: * and converted for the current output device.
0925: * <p>
0926: * If the image has not yet been completely loaded, then
0927: * <code>drawImage</code> returns <code>false</code>. As more of
0928: * the image becomes available, the process that draws the image notifies
0929: * the specified image observer.
0930: * @param img the specified image to be drawn.
0931: * @param x the <i>x</i> coordinate.
0932: * @param y the <i>y</i> coordinate.
0933: * @param observer object to be notified as more of
0934: * the image is converted.
0935: * @see java.awt.Image
0936: * @see java.awt.image.ImageObserver
0937: * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
0938: * @since JDK1.0
0939: */
0940: public boolean drawImage(Image img, int x, int y,
0941: ImageObserver observer) {
0942:
0943: if (img == null) {
0944: return true;
0945: }
0946:
0947: /* The ImageWaiter creation does not return until the
0948: * image is loaded.
0949: */
0950: ImageWaiter dim = new ImageWaiter(img);
0951:
0952: addDrawingRect(x, y, dim.getWidth(), dim.getHeight());
0953: mPrintMetrics.drawImage(this , img);
0954:
0955: return mGraphics.drawImage(img, x, y, observer);
0956: }
0957:
0958: /**
0959: * Draws as much of the specified image as has already been scaled
0960: * to fit inside the specified rectangle.
0961: * <p>
0962: * The image is drawn inside the specified rectangle of this
0963: * graphics context's coordinate space, and is scaled if
0964: * necessary. Transparent pixels do not affect whatever pixels
0965: * are already there.
0966: * <p>
0967: * This method returns immediately in all cases, even if the
0968: * entire image has not yet been scaled, dithered, and converted
0969: * for the current output device.
0970: * If the current output representation is not yet complete, then
0971: * <code>drawImage</code> returns <code>false</code>. As more of
0972: * the image becomes available, the process that draws the image notifies
0973: * the image observer by calling its <code>imageUpdate</code> method.
0974: * <p>
0975: * A scaled version of an image will not necessarily be
0976: * available immediately just because an unscaled version of the
0977: * image has been constructed for this output device. Each size of
0978: * the image may be cached separately and generated from the original
0979: * data in a separate image production sequence.
0980: * @param img the specified image to be drawn.
0981: * @param x the <i>x</i> coordinate.
0982: * @param y the <i>y</i> coordinate.
0983: * @param width the width of the rectangle.
0984: * @param height the height of the rectangle.
0985: * @param observer object to be notified as more of
0986: * the image is converted.
0987: * @see java.awt.Image
0988: * @see java.awt.image.ImageObserver
0989: * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
0990: * @since JDK1.0
0991: */
0992: public boolean drawImage(Image img, int x, int y, int width,
0993: int height, ImageObserver observer) {
0994:
0995: if (img == null) {
0996: return true;
0997: }
0998: addDrawingRect(x, y, width, height);
0999: mPrintMetrics.drawImage(this , img);
1000:
1001: return mGraphics.drawImage(img, x, y, width, height, observer);
1002:
1003: }
1004:
1005: /**
1006: * Draws as much of the specified image as is currently available.
1007: * The image is drawn with its top-left corner at
1008: * (<i>x</i>, <i>y</i>) in this graphics context's coordinate
1009: * space. Transparent pixels are drawn in the specified
1010: * background color.
1011: * <p>
1012: * This operation is equivalent to filling a rectangle of the
1013: * width and height of the specified image with the given color and then
1014: * drawing the image on top of it, but possibly more efficient.
1015: * <p>
1016: * This method returns immediately in all cases, even if the
1017: * complete image has not yet been loaded, and it has not been dithered
1018: * and converted for the current output device.
1019: * <p>
1020: * If the image has not yet been completely loaded, then
1021: * <code>drawImage</code> returns <code>false</code>. As more of
1022: * the image becomes available, the process that draws the image notifies
1023: * the specified image observer.
1024: * @param img the specified image to be drawn.
1025: * @param x the <i>x</i> coordinate.
1026: * @param y the <i>y</i> coordinate.
1027: * @param bgcolor the background color to paint under the
1028: * non-opaque portions of the image.
1029: * @param observer object to be notified as more of
1030: * the image is converted.
1031: * @see java.awt.Image
1032: * @see java.awt.image.ImageObserver
1033: * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
1034: * @since JDK1.0
1035: */
1036: public boolean drawImage(Image img, int x, int y, Color bgcolor,
1037: ImageObserver observer) {
1038:
1039: if (img == null) {
1040: return true;
1041: }
1042:
1043: /* The ImageWaiter creation does not return until the
1044: * image is loaded.
1045: */
1046: ImageWaiter dim = new ImageWaiter(img);
1047:
1048: addDrawingRect(x, y, dim.getWidth(), dim.getHeight());
1049: mPrintMetrics.drawImage(this , img);
1050:
1051: return mGraphics.drawImage(img, x, y, bgcolor, observer);
1052: }
1053:
1054: /**
1055: * Draws as much of the specified image as has already been scaled
1056: * to fit inside the specified rectangle.
1057: * <p>
1058: * The image is drawn inside the specified rectangle of this
1059: * graphics context's coordinate space, and is scaled if
1060: * necessary. Transparent pixels are drawn in the specified
1061: * background color.
1062: * This operation is equivalent to filling a rectangle of the
1063: * width and height of the specified image with the given color and then
1064: * drawing the image on top of it, but possibly more efficient.
1065: * <p>
1066: * This method returns immediately in all cases, even if the
1067: * entire image has not yet been scaled, dithered, and converted
1068: * for the current output device.
1069: * If the current output representation is not yet complete then
1070: * <code>drawImage</code> returns <code>false</code>. As more of
1071: * the image becomes available, the process that draws the image notifies
1072: * the specified image observer.
1073: * <p>
1074: * A scaled version of an image will not necessarily be
1075: * available immediately just because an unscaled version of the
1076: * image has been constructed for this output device. Each size of
1077: * the image may be cached separately and generated from the original
1078: * data in a separate image production sequence.
1079: * @param img the specified image to be drawn.
1080: * @param x the <i>x</i> coordinate.
1081: * @param y the <i>y</i> coordinate.
1082: * @param width the width of the rectangle.
1083: * @param height the height of the rectangle.
1084: * @param bgcolor the background color to paint under the
1085: * non-opaque portions of the image.
1086: * @param observer object to be notified as more of
1087: * the image is converted.
1088: * @see java.awt.Image
1089: * @see java.awt.image.ImageObserver
1090: * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
1091: * @since JDK1.0
1092: */
1093: public boolean drawImage(Image img, int x, int y, int width,
1094: int height, Color bgcolor, ImageObserver observer) {
1095:
1096: if (img == null) {
1097: return true;
1098: }
1099:
1100: addDrawingRect(x, y, width, height);
1101: mPrintMetrics.drawImage(this , img);
1102:
1103: return mGraphics.drawImage(img, x, y, width, height, bgcolor,
1104: observer);
1105:
1106: }
1107:
1108: /**
1109: * Draws as much of the specified area of the specified image as is
1110: * currently available, scaling it on the fly to fit inside the
1111: * specified area of the destination drawable surface. Transparent pixels
1112: * do not affect whatever pixels are already there.
1113: * <p>
1114: * This method returns immediately in all cases, even if the
1115: * image area to be drawn has not yet been scaled, dithered, and converted
1116: * for the current output device.
1117: * If the current output representation is not yet complete then
1118: * <code>drawImage</code> returns <code>false</code>. As more of
1119: * the image becomes available, the process that draws the image notifies
1120: * the specified image observer.
1121: * <p>
1122: * This method always uses the unscaled version of the image
1123: * to render the scaled rectangle and performs the required
1124: * scaling on the fly. It does not use a cached, scaled version
1125: * of the image for this operation. Scaling of the image from source
1126: * to destination is performed such that the first coordinate
1127: * of the source rectangle is mapped to the first coordinate of
1128: * the destination rectangle, and the second source coordinate is
1129: * mapped to the second destination coordinate. The subimage is
1130: * scaled and flipped as needed to preserve those mappings.
1131: * @param img the specified image to be drawn
1132: * @param dx1 the <i>x</i> coordinate of the first corner of the
1133: * destination rectangle.
1134: * @param dy1 the <i>y</i> coordinate of the first corner of the
1135: * destination rectangle.
1136: * @param dx2 the <i>x</i> coordinate of the second corner of the
1137: * destination rectangle.
1138: * @param dy2 the <i>y</i> coordinate of the second corner of the
1139: * destination rectangle.
1140: * @param sx1 the <i>x</i> coordinate of the first corner of the
1141: * source rectangle.
1142: * @param sy1 the <i>y</i> coordinate of the first corner of the
1143: * source rectangle.
1144: * @param sx2 the <i>x</i> coordinate of the second corner of the
1145: * source rectangle.
1146: * @param sy2 the <i>y</i> coordinate of the second corner of the
1147: * source rectangle.
1148: * @param observer object to be notified as more of the image is
1149: * scaled and converted.
1150: * @see java.awt.Image
1151: * @see java.awt.image.ImageObserver
1152: * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
1153: * @since JDK1.1
1154: */
1155: public boolean drawImage(Image img, int dx1, int dy1, int dx2,
1156: int dy2, int sx1, int sy1, int sx2, int sy2,
1157: ImageObserver observer) {
1158:
1159: if (img == null) {
1160: return true;
1161: }
1162:
1163: int width = dx2 - dx1;
1164: int height = dy2 - dy1;
1165:
1166: addDrawingRect(dx1, dy1, width, height);
1167: mPrintMetrics.drawImage(this , img);
1168:
1169: return mGraphics.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1,
1170: sx2, sy2, observer);
1171:
1172: }
1173:
1174: /**
1175: * Draws as much of the specified area of the specified image as is
1176: * currently available, scaling it on the fly to fit inside the
1177: * specified area of the destination drawable surface.
1178: * <p>
1179: * Transparent pixels are drawn in the specified background color.
1180: * This operation is equivalent to filling a rectangle of the
1181: * width and height of the specified image with the given color and then
1182: * drawing the image on top of it, but possibly more efficient.
1183: * <p>
1184: * This method returns immediately in all cases, even if the
1185: * image area to be drawn has not yet been scaled, dithered, and converted
1186: * for the current output device.
1187: * If the current output representation is not yet complete then
1188: * <code>drawImage</code> returns <code>false</code>. As more of
1189: * the image becomes available, the process that draws the image notifies
1190: * the specified image observer.
1191: * <p>
1192: * This method always uses the unscaled version of the image
1193: * to render the scaled rectangle and performs the required
1194: * scaling on the fly. It does not use a cached, scaled version
1195: * of the image for this operation. Scaling of the image from source
1196: * to destination is performed such that the first coordinate
1197: * of the source rectangle is mapped to the first coordinate of
1198: * the destination rectangle, and the second source coordinate is
1199: * mapped to the second destination coordinate. The subimage is
1200: * scaled and flipped as needed to preserve those mappings.
1201: * @param img the specified image to be drawn
1202: * @param dx1 the <i>x</i> coordinate of the first corner of the
1203: * destination rectangle.
1204: * @param dy1 the <i>y</i> coordinate of the first corner of the
1205: * destination rectangle.
1206: * @param dx2 the <i>x</i> coordinate of the second corner of the
1207: * destination rectangle.
1208: * @param dy2 the <i>y</i> coordinate of the second corner of the
1209: * destination rectangle.
1210: * @param sx1 the <i>x</i> coordinate of the first corner of the
1211: * source rectangle.
1212: * @param sy1 the <i>y</i> coordinate of the first corner of the
1213: * source rectangle.
1214: * @param sx2 the <i>x</i> coordinate of the second corner of the
1215: * source rectangle.
1216: * @param sy2 the <i>y</i> coordinate of the second corner of the
1217: * source rectangle.
1218: * @param bgcolor the background color to paint under the
1219: * non-opaque portions of the image.
1220: * @param observer object to be notified as more of the image is
1221: * scaled and converted.
1222: * @see java.awt.Image
1223: * @see java.awt.image.ImageObserver
1224: * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
1225: * @since JDK1.1
1226: */
1227: public boolean drawImage(Image img, int dx1, int dy1, int dx2,
1228: int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor,
1229: ImageObserver observer) {
1230:
1231: if (img == null) {
1232: return true;
1233: }
1234:
1235: int width = dx2 - dx1;
1236: int height = dy2 - dy1;
1237:
1238: addDrawingRect(dx1, dy1, width, height);
1239: mPrintMetrics.drawImage(this , img);
1240:
1241: return mGraphics.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1,
1242: sx2, sy2, bgcolor, observer);
1243:
1244: }
1245:
1246: /**
1247: * Draws an image, applying a transform from image space into user space
1248: * before drawing.
1249: * The transformation from user space into device space is done with
1250: * the current transform in the Graphics2D.
1251: * The given transformation is applied to the image before the
1252: * transform attribute in the Graphics2D state is applied.
1253: * The rendering attributes applied include the clip, transform,
1254: * and composite attributes. Note that the result is
1255: * undefined, if the given transform is noninvertible.
1256: * @param img The image to be drawn.
1257: * @param xform The transformation from image space into user space.
1258: * @see #transform
1259: * @see #setTransform
1260: * @see #setComposite
1261: * @see #clip
1262: * @see #setClip
1263: */
1264: public void drawRenderedImage(RenderedImage img,
1265: AffineTransform xform) {
1266:
1267: if (img == null) {
1268: return;
1269: }
1270:
1271: mPrintMetrics.drawImage(this , img);
1272: mDrawingArea.addInfinite();
1273: }
1274:
1275: public void drawRenderableImage(RenderableImage img,
1276: AffineTransform xform) {
1277:
1278: if (img == null) {
1279: return;
1280: }
1281:
1282: mPrintMetrics.drawImage(this , img);
1283: mDrawingArea.addInfinite();
1284: }
1285:
1286: /**
1287: * Disposes of this graphics context and releases
1288: * any system resources that it is using.
1289: * A <code>Graphics</code> object cannot be used after
1290: * <code>dispose</code>has been called.
1291: * <p>
1292: * When a Java program runs, a large number of <code>Graphics</code>
1293: * objects can be created within a short time frame.
1294: * Although the finalization process of the garbage collector
1295: * also disposes of the same system resources, it is preferable
1296: * to manually free the associated resources by calling this
1297: * method rather than to rely on a finalization process which
1298: * may not run to completion for a long period of time.
1299: * <p>
1300: * Graphics objects which are provided as arguments to the
1301: * <code>paint</code> and <code>update</code> methods
1302: * of components are automatically released by the system when
1303: * those methods return. For efficiency, programmers should
1304: * call <code>dispose</code> when finished using
1305: * a <code>Graphics</code> object only if it was created
1306: * directly from a component or another <code>Graphics</code> object.
1307: * @see java.awt.Graphics#finalize
1308: * @see java.awt.Component#paint
1309: * @see java.awt.Component#update
1310: * @see java.awt.Component#getGraphics
1311: * @see java.awt.Graphics#create
1312: * @since JDK1.0
1313: */
1314: public void dispose() {
1315: mGraphics.dispose();
1316: }
1317:
1318: /**
1319: * Empty finalizer as no clean up needed here.
1320: */
1321: public void finalize() {
1322: }
1323:
1324: /* The Delegated Graphics2D Methods */
1325:
1326: /**
1327: * Strokes the outline of a Shape using the settings of the current
1328: * graphics state. The rendering attributes applied include the
1329: * clip, transform, paint or color, composite and stroke attributes.
1330: * @param s The shape to be drawn.
1331: * @see #setStroke
1332: * @see #setPaint
1333: * @see java.awt.Graphics#setColor
1334: * @see #transform
1335: * @see #setTransform
1336: * @see #clip
1337: * @see #setClip
1338: * @see #setComposite
1339: */
1340: public void draw(Shape s) {
1341: addStrokeShape(s);
1342: mPrintMetrics.draw(this );
1343: }
1344:
1345: /**
1346: * Draws an image, applying a transform from image space into user space
1347: * before drawing.
1348: * The transformation from user space into device space is done with
1349: * the current transform in the Graphics2D.
1350: * The given transformation is applied to the image before the
1351: * transform attribute in the Graphics2D state is applied.
1352: * The rendering attributes applied include the clip, transform,
1353: * and composite attributes. Note that the result is
1354: * undefined, if the given transform is noninvertible.
1355: * @param img The image to be drawn.
1356: * @param xform The transformation from image space into user space.
1357: * @param obs The image observer to be notified as more of the image
1358: * is converted.
1359: * @see #transform
1360: * @see #setTransform
1361: * @see #setComposite
1362: * @see #clip
1363: * @see #setClip
1364: */
1365: public boolean drawImage(Image img, AffineTransform xform,
1366: ImageObserver obs) {
1367:
1368: if (img == null) {
1369: return true;
1370: }
1371:
1372: mDrawingArea.addInfinite();
1373: mPrintMetrics.drawImage(this , img);
1374:
1375: return mGraphics.drawImage(img, xform, obs);
1376:
1377: // if (mDrawingArea[0] != null) {
1378: // Rectangle2D.Double bbox = new Rectangle2D.Double();
1379: // Point2D leftTop = new Point2D.Double(0, 0);
1380: // Point2D rightBottom = new Point2D.Double(getImageWidth(img),
1381: // getImageHeight(img));
1382:
1383: // xform.transform(leftTop, leftTop);
1384: // xform.transform(rightBottom, rightBottom);
1385:
1386: // bbox.setBoundsFromDiagonal(leftTop, rightBottom);
1387: // addDrawingRect(bbox);
1388:
1389: // }
1390: }
1391:
1392: /**
1393: * Draws a BufferedImage that is filtered with a BufferedImageOp.
1394: * The rendering attributes applied include the clip, transform
1395: * and composite attributes. This is equivalent to:
1396: * <pre>
1397: * img1 = op.filter(img, null);
1398: * drawImage(img1, new AffineTransform(1f,0f,0f,1f,x,y), null);
1399: * </pre>
1400: * @param op The filter to be applied to the image before drawing.
1401: * @param img The BufferedImage to be drawn.
1402: * @param x,y The location in user space where the image should be drawn.
1403: * @see #transform
1404: * @see #setTransform
1405: * @see #setComposite
1406: * @see #clip
1407: * @see #setClip
1408: */
1409: public void drawImage(BufferedImage img, BufferedImageOp op, int x,
1410: int y) {
1411:
1412: if (img == null) {
1413: return;
1414: }
1415:
1416: mPrintMetrics.drawImage(this , (RenderedImage) img);
1417: mDrawingArea.addInfinite();
1418: }
1419:
1420: /**
1421: * Draws a string of text.
1422: * The rendering attributes applied include the clip, transform,
1423: * paint or color, font and composite attributes.
1424: * @param s The string to be drawn.
1425: * @param x,y The coordinates where the string should be drawn.
1426: * @see #setPaint
1427: * @see java.awt.Graphics#setColor
1428: * @see java.awt.Graphics#setFont
1429: * @see #transform
1430: * @see #setTransform
1431: * @see #setComposite
1432: * @see #clip
1433: * @see #setClip
1434: */
1435: public void drawString(String str, float x, float y) {
1436:
1437: if (str.length() == 0) {
1438: return;
1439: }
1440: /* Logical bounds close enough and is used for GlyphVector */
1441: FontRenderContext frc = getFontRenderContext();
1442: Rectangle2D bbox = getFont().getStringBounds(str, frc);
1443: addDrawingRect(bbox, x, y);
1444: mPrintMetrics.drawText(this );
1445: }
1446:
1447: /**
1448: * Draws a GlyphVector.
1449: * The rendering attributes applied include the clip, transform,
1450: * paint or color, and composite attributes. The GlyphVector specifies
1451: * individual glyphs from a Font.
1452: * @param g The GlyphVector to be drawn.
1453: * @param x,y The coordinates where the glyphs should be drawn.
1454: * @see #setPaint
1455: * @see java.awt.Graphics#setColor
1456: * @see #transform
1457: * @see #setTransform
1458: * @see #setComposite
1459: * @see #clip
1460: * @see #setClip
1461: */
1462: public void drawGlyphVector(GlyphVector g, float x, float y) {
1463:
1464: Rectangle2D bbox = g.getLogicalBounds();
1465: addDrawingRect(bbox, x, y);
1466: mPrintMetrics.drawText(this );
1467:
1468: }
1469:
1470: /**
1471: * Fills the interior of a Shape using the settings of the current
1472: * graphics state. The rendering attributes applied include the
1473: * clip, transform, paint or color, and composite.
1474: * @see #setPaint
1475: * @see java.awt.Graphics#setColor
1476: * @see #transform
1477: * @see #setTransform
1478: * @see #setComposite
1479: * @see #clip
1480: * @see #setClip
1481: */
1482: public void fill(Shape s) {
1483: addDrawingRect(s.getBounds());
1484: mPrintMetrics.fill(this );
1485:
1486: }
1487:
1488: /**
1489: * Checks to see if the outline of a Shape intersects the specified
1490: * Rectangle in device space.
1491: * The rendering attributes taken into account include the
1492: * clip, transform, and stroke attributes.
1493: * @param rect The area in device space to check for a hit.
1494: * @param s The shape to check for a hit.
1495: * @param onStroke Flag to choose between testing the stroked or
1496: * the filled shape.
1497: * @return True if there is a hit, false otherwise.
1498: * @see #setStroke
1499: * @see #fill
1500: * @see #draw
1501: * @see #transform
1502: * @see #setTransform
1503: * @see #clip
1504: * @see #setClip
1505: */
1506: public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
1507:
1508: return mGraphics.hit(rect, s, onStroke);
1509: }
1510:
1511: /**
1512: * Sets the Composite in the current graphics state. Composite is used
1513: * in all drawing methods such as drawImage, drawString, draw,
1514: * and fill. It specifies how new pixels are to be combined with
1515: * the existing pixels on the graphics device in the rendering process.
1516: * @param comp The Composite object to be used for drawing.
1517: * @see java.awt.Graphics#setXORMode
1518: * @see java.awt.Graphics#setPaintMode
1519: * @see AlphaComposite
1520: */
1521: public void setComposite(Composite comp) {
1522: mGraphics.setComposite(comp);
1523: }
1524:
1525: /**
1526: * Sets the Paint in the current graphics state.
1527: * @param paint The Paint object to be used to generate color in
1528: * the rendering process.
1529: * @see java.awt.Graphics#setColor
1530: * @see GradientPaint
1531: * @see TexturePaint
1532: */
1533: public void setPaint(Paint paint) {
1534: mGraphics.setPaint(paint);
1535: }
1536:
1537: /**
1538: * Sets the Stroke in the current graphics state.
1539: * @param s The Stroke object to be used to stroke a Shape in
1540: * the rendering process.
1541: * @see BasicStroke
1542: */
1543: public void setStroke(Stroke s) {
1544: mGraphics.setStroke(s);
1545: }
1546:
1547: /**
1548: * Sets the preferences for the rendering algorithms.
1549: * Hint categories include controls for rendering quality and
1550: * overall time/quality trade-off in the rendering process.
1551: * @param hintCategory The category of hint to be set.
1552: * @param hintValue The value indicating preferences for the specified
1553: * hint category.
1554: * @see RenderingHints
1555: */
1556: public void setRenderingHint(Key hintCategory, Object hintValue) {
1557: mGraphics.setRenderingHint(hintCategory, hintValue);
1558: }
1559:
1560: /**
1561: * Returns the preferences for the rendering algorithms.
1562: * @param hintCategory The category of hint to be set.
1563: * @return The preferences for rendering algorithms.
1564: * @see RenderingHings
1565: */
1566: public Object getRenderingHint(Key hintCategory) {
1567: return mGraphics.getRenderingHint(hintCategory);
1568: }
1569:
1570: /**
1571: * Sets the preferences for the rendering algorithms.
1572: * Hint categories include controls for rendering quality and
1573: * overall time/quality trade-off in the rendering process.
1574: * @param hints The rendering hints to be set
1575: * @see RenderingHints
1576: */
1577: public void setRenderingHints(Map<?, ?> hints) {
1578: mGraphics.setRenderingHints(hints);
1579: }
1580:
1581: /**
1582: * Adds a number of preferences for the rendering algorithms.
1583: * Hint categories include controls for rendering quality and
1584: * overall time/quality trade-off in the rendering process.
1585: * @param hints The rendering hints to be set
1586: * @see RenderingHints
1587: */
1588: public void addRenderingHints(Map<?, ?> hints) {
1589: mGraphics.addRenderingHints(hints);
1590: }
1591:
1592: /**
1593: * Gets the preferences for the rendering algorithms.
1594: * Hint categories include controls for rendering quality and
1595: * overall time/quality trade-off in the rendering process.
1596: * @see RenderingHints
1597: */
1598: public RenderingHints getRenderingHints() {
1599: return mGraphics.getRenderingHints();
1600: }
1601:
1602: /**
1603: * Composes a Transform object with the transform in this
1604: * Graphics2D according to the rule last-specified-first-applied.
1605: * If the currrent transform is Cx, the result of composition
1606: * with Tx is a new transform Cx'. Cx' becomes the current
1607: * transform for this Graphics2D.
1608: * Transforming a point p by the updated transform Cx' is
1609: * equivalent to first transforming p by Tx and then transforming
1610: * the result by the original transform Cx. In other words,
1611: * Cx'(p) = Cx(Tx(p)).
1612: * A copy of the Tx is made, if necessary, so further
1613: * modifications to Tx do not affect rendering.
1614: * @param Tx The Transform object to be composed with the current
1615: * transform.
1616: * @see #setTransform
1617: * @see TransformChain
1618: * @see AffineTransform
1619: */
1620: public void transform(AffineTransform Tx) {
1621: mGraphics.transform(Tx);
1622: }
1623:
1624: /**
1625: * Sets the Transform in the current graphics state.
1626: * @param Tx The Transform object to be used in the rendering process.
1627: * @see #transform
1628: * @see TransformChain
1629: * @see AffineTransform
1630: */
1631: public void setTransform(AffineTransform Tx) {
1632: mGraphics.setTransform(Tx);
1633: }
1634:
1635: /**
1636: * Returns the current Transform in the Graphics2D state.
1637: * @see #transform
1638: * @see #setTransform
1639: */
1640: public AffineTransform getTransform() {
1641: return mGraphics.getTransform();
1642: }
1643:
1644: /**
1645: * Returns the current Paint in the Graphics2D state.
1646: * @see #setPaint
1647: * @see java.awt.Graphics#setColor
1648: */
1649: public Paint getPaint() {
1650: return mGraphics.getPaint();
1651: }
1652:
1653: /**
1654: * Returns the current Composite in the Graphics2D state.
1655: * @see #setComposite
1656: */
1657: public Composite getComposite() {
1658: return mGraphics.getComposite();
1659: }
1660:
1661: /**
1662: * Sets the background color in this context used for clearing a region.
1663: * When Graphics2D is constructed for a component, the backgroung color is
1664: * inherited from the component. Setting the background color in the
1665: * Graphics2D context only affects the subsequent clearRect() calls and
1666: * not the background color of the component. To change the background
1667: * of the component, use appropriate methods of the component.
1668: * @param color The background color that should be used in
1669: * subsequent calls to clearRect().
1670: * @see getBackground
1671: * @see Graphics.clearRect()
1672: */
1673: public void setBackground(Color color) {
1674: mGraphics.setBackground(color);
1675: }
1676:
1677: /**
1678: * Returns the background color used for clearing a region.
1679: * @see setBackground
1680: */
1681: public Color getBackground() {
1682: return mGraphics.getBackground();
1683: }
1684:
1685: /**
1686: * Returns the current Stroke in the Graphics2D state.
1687: * @see setStroke
1688: */
1689: public Stroke getStroke() {
1690: return mGraphics.getStroke();
1691: }
1692:
1693: /**
1694: * Intersects the current clip with the interior of the specified Shape
1695: * and sets the current clip to the resulting intersection.
1696: * The indicated shape is transformed with the current transform in the
1697: * Graphics2D state before being intersected with the current clip.
1698: * This method is used to make the current clip smaller.
1699: * To make the clip larger, use any setClip method.
1700: * @param s The Shape to be intersected with the current clip.
1701: */
1702: public void clip(Shape s) {
1703: mGraphics.clip(s);
1704: }
1705:
1706: /**
1707: * Return true if the Rectangle <code>rect</code>
1708: * intersects the area into which the application
1709: * has drawn.
1710: */
1711: public boolean hitsDrawingArea(Rectangle rect) {
1712:
1713: return mDrawingArea.intersects((float) rect.getMinY(),
1714: (float) rect.getMaxY());
1715: }
1716:
1717: /**
1718: * Return the object holding the summary of the
1719: * drawing done by the printing application.
1720: */
1721: public PeekMetrics getMetrics() {
1722: return mPrintMetrics;
1723: }
1724:
1725: /* Support Routines for Calculating the Drawing Area */
1726:
1727: /**
1728: * Shift the rectangle 'rect' to the position ('x', 'y')
1729: * and add the resulting rectangle to the area representing
1730: * the part of the page which is drawn into.
1731: */
1732: private void addDrawingRect(Rectangle2D rect, float x, float y) {
1733:
1734: addDrawingRect((float) (rect.getX() + x),
1735: (float) (rect.getY() + y), (float) rect.getWidth(),
1736: (float) rect.getHeight());
1737:
1738: }
1739:
1740: private void addDrawingRect(float x, float y, float width,
1741: float height) {
1742:
1743: Rectangle2D.Float bbox = new Rectangle2D.Float(x, y, width,
1744: height);
1745: addDrawingRect(bbox);
1746: }
1747:
1748: /**
1749: * Add the rectangle 'rect' to the area representing
1750: * the part of the page which is drawn into.
1751: */
1752: private void addDrawingRect(Rectangle2D rect) {
1753:
1754: /* For testing purposes the following line can be uncommented.
1755: When uncommented it causes the entire page to be rasterized
1756: thus eliminating errors caused by a faulty bounding box
1757: calculation.
1758: */
1759: //mDrawingArea.addInfinite();
1760:
1761: AffineTransform matrix = getTransform();
1762:
1763: Shape transShape = matrix.createTransformedShape(rect);
1764:
1765: Rectangle2D transRect = transShape.getBounds2D();
1766:
1767: mDrawingArea.add((float) transRect.getMinY(), (float) transRect
1768: .getMaxY());
1769:
1770: }
1771:
1772: /**
1773: * Add the stroked shape to the area representing
1774: * the part of the page which is drawn into.
1775: */
1776: private void addStrokeShape(Shape s) {
1777: Shape transShape = getStroke().createStrokedShape(s);
1778: addDrawingRect(transShape.getBounds2D());
1779: }
1780:
1781: /* Image Observer */
1782:
1783: /**
1784: * Notify this object when the height or width become available
1785: * for an image.
1786: */
1787: public synchronized boolean imageUpdate(Image img, int infoFlags,
1788: int x, int y, int width, int height) {
1789:
1790: boolean gotInfo = false;
1791:
1792: if ((infoFlags & (WIDTH | HEIGHT)) != 0) {
1793: gotInfo = true;
1794: notify();
1795: }
1796:
1797: return gotInfo;
1798: }
1799:
1800: private synchronized int getImageWidth(Image img) {
1801:
1802: /* Wait for the width the image to
1803: * become available.
1804: */
1805: while (img.getWidth(this ) == -1) {
1806: try {
1807: wait();
1808: } catch (InterruptedException e) {
1809: }
1810: }
1811:
1812: return img.getWidth(this );
1813: }
1814:
1815: private synchronized int getImageHeight(Image img) {
1816:
1817: /* Wait for the height the image to
1818: * become available.
1819: */
1820: while (img.getHeight(this ) == -1) {
1821: try {
1822: wait();
1823: } catch (InterruptedException e) {
1824: }
1825: }
1826:
1827: return img.getHeight(this );
1828: }
1829:
1830: /**
1831: * This private class does not return from its constructor
1832: * until 'img's width and height are available.
1833: */
1834: protected class ImageWaiter implements ImageObserver {
1835:
1836: private int mWidth;
1837: private int mHeight;
1838: private boolean badImage = false;
1839:
1840: ImageWaiter(Image img) {
1841: waitForDimensions(img);
1842: }
1843:
1844: public int getWidth() {
1845: return mWidth;
1846: }
1847:
1848: public int getHeight() {
1849: return mHeight;
1850: }
1851:
1852: synchronized private void waitForDimensions(Image img) {
1853: mHeight = img.getHeight(this );
1854: mWidth = img.getWidth(this );
1855: while (!badImage && (mWidth < 0 || mHeight < 0)) {
1856: try {
1857: Thread.sleep(50);
1858: } catch (InterruptedException e) {
1859: // do nothing.
1860: }
1861: mHeight = img.getHeight(this );
1862: mWidth = img.getWidth(this );
1863: }
1864: if (badImage) {
1865: mHeight = 0;
1866: mWidth = 0;
1867: }
1868: }
1869:
1870: synchronized public boolean imageUpdate(Image image, int flags,
1871: int x, int y, int w, int h) {
1872:
1873: boolean dontCallMeAgain = (flags & (HEIGHT | ABORT | ERROR)) != 0;
1874: badImage = (flags & (ABORT | ERROR)) != 0;
1875:
1876: return dontCallMeAgain;
1877: }
1878:
1879: }
1880: }
|