0001: /*
0002: * $RCSfile: TiledImageGraphics.java,v $
0003: *
0004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * Use is subject to license terms.
0007: *
0008: * $Revision: 1.1 $
0009: * $Date: 2005/02/11 04:57:23 $
0010: * $State: Exp $
0011: */
0012: package javax.media.jai;
0013:
0014: import java.awt.Color;
0015: import java.awt.Composite;
0016: import java.awt.Font;
0017: import java.awt.FontMetrics;
0018: import java.awt.Graphics;
0019: import java.awt.Graphics2D;
0020: import java.awt.GraphicsConfiguration;
0021: import java.awt.Image;
0022: import java.awt.Paint;
0023: import java.awt.PaintContext;
0024: import java.awt.Point;
0025: import java.awt.Rectangle;
0026: import java.awt.RenderingHints;
0027: import java.awt.RenderingHints.Key;
0028: import java.awt.Shape;
0029: import java.awt.Stroke;
0030: import java.awt.font.FontRenderContext;
0031: import java.awt.font.GlyphVector;
0032: import java.awt.font.TextLayout;
0033: import java.awt.geom.AffineTransform;
0034: import java.awt.geom.Area;
0035: import java.awt.geom.Point2D;
0036: import java.awt.geom.Rectangle2D;
0037: import java.awt.image.BufferedImage;
0038: import java.awt.image.BufferedImageOp;
0039: import java.awt.image.ColorModel;
0040: import java.awt.image.DataBuffer;
0041: import java.awt.image.ImageObserver;
0042: import java.awt.image.Raster;
0043: import java.awt.image.RenderedImage;
0044: import java.awt.image.SampleModel;
0045: import java.awt.image.WritableRaster;
0046: import java.awt.image.renderable.RenderableImage;
0047: import java.lang.reflect.Method;
0048: import java.text.AttributedCharacterIterator;
0049: import java.util.Hashtable;
0050: import java.util.Map;
0051: import javax.media.jai.util.ImagingException;
0052: import javax.media.jai.util.ImagingListener;
0053: import com.sun.media.jai.util.JDKWorkarounds;
0054:
0055: /**
0056: * A concrete (i.e., non-abstract) class implementing all the methods
0057: * of <code>Graphics2D</code> (and thus of <code>Graphics</code>) with
0058: * a <code>TiledImage</code> as the implicit drawing canvas.
0059: * The actual implementation will use Java2D to do most of the work
0060: * by packaging up the image tiles in a form that Java2D can
0061: * understand.
0062: *
0063: * <p> Since the public methods of this class all derive from
0064: * <code>Graphics2D</code>, they are not commented individually.
0065: *
0066: * <p> The <code>ColorModel</code> for the canvas will be that of the
0067: * associated <code>TiledImage</code> unless that <code>ColorModel</code>
0068: * is null. If the <code>TiledImage</code> <code>ColorModel</code> is null,
0069: * an attempt will first be made to deduce the <code>ColorModel</code> from
0070: * the <code>SampleModel</code> of the <code>TiledImage</code> using the
0071: * <code>createColorModel()</code> method of <code>PlanarImage</code>.
0072: * If the <code>ColorModel</code> is still null, the default RGB
0073: * <code>ColorModel</code> returned by the <code>getRGBdefault()</code>
0074: * method of <code>ColorModel</code> will be used if the
0075: * <code>TiledImage</code> has a compatible <code>SampleModel</code>.
0076: * If no acceptable <code>ColorModel</code> can be derived an
0077: * <code>UnsupportedOperationException</code> will be thrown.
0078: *
0079: * @see java.awt.Graphics
0080: * @see java.awt.Graphics2D
0081: * @see java.awt.image.ColorModel
0082: * @see java.awt.image.SampleModel
0083: * @see TiledImage
0084: *
0085: */
0086: class TiledImageGraphics extends Graphics2D {
0087:
0088: // Constants
0089: private static final Class GRAPHICS2D_CLASS = Graphics2D.class;
0090: private static final int PAINT_MODE = 1;
0091: private static final int XOR_MODE = 2;
0092:
0093: // TiledImageGraphics state
0094: private TiledImage tiledImage;
0095: Hashtable properties;
0096: private RenderingHints renderingHints;
0097:
0098: // Cached variables available from the source TiledImage
0099: private int tileWidth;
0100: private int tileHeight;
0101: private int tileXMinimum;
0102: private int tileXMaximum;
0103: private int tileYMinimum;
0104: private int tileYMaximum;
0105: private ColorModel colorModel;
0106:
0107: // Graphics state information (from java.awt.Graphics)
0108: private Point origin;
0109: private Shape clip;
0110: private Color color;
0111: private Font font;
0112: private int paintMode = PAINT_MODE;
0113: private Color XORColor;
0114:
0115: // Graphics state information (from java.awt.Graphics2D)
0116: private Color background;
0117: private Composite composite;
0118: private Paint paint;
0119: private Stroke stroke;
0120: private AffineTransform transform;
0121:
0122: // ---------- Methods specific to TiledImageGraphics ----------
0123:
0124: /**
0125: * Determine the bounding box of the points represented by the supplied
0126: * arrays of X and Y coordinates.
0127: *
0128: * @param xPoints An array of <i>x</i> points.
0129: * @param yPoints An array of <i>y</i> points.
0130: * @param nPoints The total number of points.
0131: */
0132: private static final Rectangle getBoundingBox(int[] xPoints,
0133: int[] yPoints, int nPoints) {
0134: if (nPoints <= 0)
0135: return null;
0136:
0137: int minX;
0138: int maxX;
0139: int minY;
0140: int maxY;
0141:
0142: minX = maxX = xPoints[0];
0143: minY = maxY = yPoints[0];
0144:
0145: for (int i = 1; i < nPoints; i++) {
0146: minX = Math.min(minX, xPoints[i]);
0147: maxX = Math.max(maxX, xPoints[i]);
0148: minY = Math.min(minY, yPoints[i]);
0149: maxY = Math.max(maxY, yPoints[i]);
0150: }
0151:
0152: return new Rectangle(minX, minY, maxX - minX + 1, maxY - minY
0153: + 1);
0154: }
0155:
0156: /**
0157: * Construct a <code>TiledImageGraphics</code> object that draws onto a
0158: * particular <code>TiledImage</code>. The <code>TiledImage</code>
0159: * parameter must be of integral data type or an
0160: * <code>UnsupportedOperationException</code> will be thrown. Likewise,
0161: * if no appropriate <code>ColorModel</code> can be derived an
0162: * <code>UnsupportedOperationException</code> will be thrown.
0163: *
0164: * @param im The <code>TiledImage</code> which will serve as the graphics
0165: * canvas.
0166: * @throws <code>UnsupportedOperationException</code> if no appropriate
0167: * <code>ColorModel</code> can be derived.
0168: */
0169: public TiledImageGraphics(TiledImage im) {
0170: // Check for non-integral data type.
0171: int dataType = im.getSampleModel().getTransferType();
0172: if (dataType != DataBuffer.TYPE_BYTE
0173: && dataType != DataBuffer.TYPE_SHORT
0174: && dataType != DataBuffer.TYPE_USHORT
0175: && dataType != DataBuffer.TYPE_INT) {
0176: throw new UnsupportedOperationException(JaiI18N
0177: .getString("TiledImageGraphics0"));
0178: }
0179:
0180: // Cache the TiledImage.
0181: tiledImage = im;
0182:
0183: // Cache the tile dimensions and index extrema.
0184: tileWidth = im.getTileWidth();
0185: tileHeight = im.getTileHeight();
0186: tileXMinimum = im.getMinTileX();
0187: tileXMaximum = im.getMaxTileX();
0188: tileYMinimum = im.getMinTileY();
0189: tileYMaximum = im.getMaxTileY();
0190:
0191: // Attempt to derive an appropriate ColorModel.
0192: colorModel = getColorModel(tiledImage);
0193:
0194: // Obtain a Graphics2D object from which to derive state
0195: Graphics2D g = getBogusGraphics2D(false);
0196:
0197: // -- java.awt.Graphics state --
0198: origin = new Point(0, 0);
0199: setClip(tiledImage.getBounds());
0200: setColor(g.getColor());
0201: setFont(g.getFont());
0202: setPaintMode();
0203:
0204: // -- java.awt.Graphics2D state --
0205: setBackground(g.getBackground());
0206: setComposite(g.getComposite());
0207: setStroke(g.getStroke());
0208: setTransform(g.getTransform());
0209:
0210: // Dispose of the Graphics2D
0211: g.dispose();
0212:
0213: // -- TiledImageGraphics state --
0214: // Cache the Hashtable of properties.
0215: properties = tiledImage.getProperties();
0216:
0217: // Create RenderingHints from the properties.
0218: renderingHints = new RenderingHints(properties);
0219: }
0220:
0221: /**
0222: * Copy the graphics state of the current object to a
0223: * <code>Graphics2D</code> object.
0224: *
0225: * @param g2d The target <code>Graphics2D</code> object.
0226: */
0227: private void copyState(Graphics2D g2d) {
0228: // java.awt.Graphics state
0229: g2d.translate(origin.x, origin.y);
0230: setClip(getClip());
0231: g2d.setColor(getColor());
0232: if (paintMode == PAINT_MODE) {
0233: g2d.setPaintMode();
0234: } else if (XORColor != null) {
0235: g2d.setXORMode(XORColor);
0236: }
0237: g2d.setFont(getFont());
0238:
0239: // java.awt.Graphics2D state
0240: g2d.setBackground(getBackground());
0241: g2d.setComposite(getComposite());
0242: if (paint != null)
0243: g2d.setPaint(getPaint());
0244: g2d.setRenderingHints(renderingHints);
0245: g2d.setStroke(getStroke());
0246: g2d.setTransform(getTransform());
0247: }
0248:
0249: /**
0250: * Creates a bogus <code>Graphics2D</code> object to be used to retrieve
0251: * information dependent on system aspects which are image-independent.
0252: *
0253: * <p>The <code>dispose()</code> method of the <code>Graphics2D</code>
0254: * object returned should be called to free the associated resources as\
0255: * soon as possible.
0256: *
0257: * @param shouldCopyState Whether the state of the returned
0258: * <code>Graphics2D</code> should be initialized to that of the
0259: * current <code>TiledImageGraphics</code> object.
0260: *
0261: * @return A <code>Graphics2D</code> object.
0262: */
0263: private Graphics2D getBogusGraphics2D(boolean shouldCopyState) {
0264: Raster r = tiledImage.getTile(tileXMinimum, tileYMinimum);
0265: WritableRaster wr = r.createCompatibleWritableRaster(1, 1);
0266: BufferedImage bi = new BufferedImage(colorModel, wr, colorModel
0267: .isAlphaPremultiplied(), properties);
0268:
0269: Graphics2D bogusG2D = bi.createGraphics();
0270: if (shouldCopyState) {
0271: copyState(bogusG2D);
0272: }
0273: return bogusG2D;
0274: }
0275:
0276: /**
0277: * Derive an approriate <code>ColorModel</code> for use with the
0278: * underlying <code>BufferedImage</code> canvas. If an appropriate
0279: * <code>ColorModel</code> cannot be derived an
0280: * <code>UnsupportedOperationException</code> will be thrown.
0281: *
0282: * @return An appropriate <code>ColorModel</code>.
0283: * @throws <code>UnsupportedOperationException</code> if no appropriate
0284: * <code>ColorModel</code> can be derived.
0285: */
0286: private static ColorModel getColorModel(TiledImage ti) {
0287: // Derive an appropriate ColorModel for the BufferedImage:
0288: // first try to use that of the TiledImage.
0289: ColorModel colorModel = ti.getColorModel();
0290:
0291: if (colorModel == null) {
0292: // Try to guess an appropriate ColorModel.
0293: if (colorModel == null) {
0294: // First try to deduce one from the TiledImage SampleModel.
0295: SampleModel sm = ti.getSampleModel();
0296: colorModel = PlanarImage.createColorModel(sm);
0297: if (colorModel == null) {
0298: // ColorModel still null: try RGB default model.
0299: ColorModel cm = ColorModel.getRGBdefault();
0300: if (JDKWorkarounds.areCompatibleDataModels(sm, cm)) {
0301: colorModel = cm;
0302: }
0303: }
0304:
0305: // ColorModel is still null: throw an exception.
0306: if (colorModel == null) {
0307: throw new UnsupportedOperationException(JaiI18N
0308: .getString("TiledImageGraphics1"));
0309: }
0310: }
0311: }
0312:
0313: return colorModel;
0314: }
0315:
0316: /**
0317: * Effect a graphics operation on the <code>TiledImage</code> by
0318: * creating a <code>BufferedImage</code> for each tile in the affected
0319: * region and using the corresponding <code>Graphics2D</code> to
0320: * perform the equivalent operation on the tile.
0321: *
0322: * @param x The <i>x</i> coordinate of the upper left corner.
0323: * @param y The <i>y</i> coordinate of the upper left corner.
0324: * @param width The width of the region.
0325: * @param height The height of the region.
0326: * @param argTypes An array of the <code>Classes</code> of the arguments
0327: * of the specified operation.
0328: * @param args The arguments of the operation as an array of
0329: * <code>Object</code>s.
0330: */
0331: private boolean doGraphicsOp(int x, int y, int width, int height,
0332: String name, Class[] argTypes, Object[] args) {
0333: boolean returnValue = false;
0334:
0335: // Determine the Method object associated with the Graphics2D method
0336: // having the indicated name. The search begins with the Graphics2D
0337: // class and continues to its superclasses until the Method is found.
0338: Method method = null;
0339: try {
0340: method = GRAPHICS2D_CLASS.getMethod(name, argTypes);
0341: } catch (Exception e) {
0342: String message = JaiI18N.getString("TiledImageGraphics2")
0343: + name;
0344: sendExceptionToListener(message, new ImagingException(e));
0345: // throw new RuntimeException(e.getMessage());
0346: }
0347:
0348: // Transform requested area to obtain actual bounds.
0349: Rectangle bounds = new Rectangle(x, y, width, height);
0350: bounds = getTransform().createTransformedShape(bounds)
0351: .getBounds();
0352:
0353: // Determine the range of tile indexes
0354: int minTileX = tiledImage.XToTileX(bounds.x);
0355: if (minTileX < tileXMinimum)
0356: minTileX = tileXMinimum;
0357: int minTileY = tiledImage.YToTileY(bounds.y);
0358: if (minTileY < tileYMinimum)
0359: minTileY = tileYMinimum;
0360: int maxTileX = tiledImage.XToTileX(bounds.x + bounds.width - 1);
0361: if (maxTileX > tileXMaximum)
0362: maxTileX = tileXMaximum;
0363: int maxTileY = tiledImage
0364: .YToTileY(bounds.y + bounds.height - 1);
0365: if (maxTileY > tileYMaximum)
0366: maxTileY = tileYMaximum;
0367:
0368: // Loop over the tiles
0369: for (int tileY = minTileY; tileY <= maxTileY; tileY++) {
0370: int tileMinY = tiledImage.tileYToY(tileY);
0371: for (int tileX = minTileX; tileX <= maxTileX; tileX++) {
0372: int tileMinX = tiledImage.tileXToX(tileX);
0373:
0374: // Get the WritableRaster of the current tile
0375: WritableRaster wr = tiledImage.getWritableTile(tileX,
0376: tileY);
0377: wr = wr.createWritableTranslatedChild(0, 0);
0378:
0379: // Create an equivalent BufferedImage
0380: BufferedImage bi = new BufferedImage(colorModel, wr,
0381: colorModel.isAlphaPremultiplied(), properties);
0382:
0383: // Create the associated Graphics2D
0384: Graphics2D g2d = bi.createGraphics();
0385:
0386: // Initialize the Graphics2D state
0387: copyState(g2d);
0388:
0389: // Bias the tile origin so that the global coordinates
0390: // map correctly onto the tile.
0391: try {
0392: Point2D origin2D = g2d.getTransform().transform(
0393: new Point2D.Double(), null);
0394: Point pt = new Point((int) origin2D.getX()
0395: - tileMinX, (int) origin2D.getY()
0396: - tileMinY);
0397: Point2D pt2D = g2d.getTransform().inverseTransform(
0398: pt, null);
0399: g2d.translate(pt2D.getX(), pt2D.getY());
0400: } catch (Exception e) {
0401: String message = JaiI18N
0402: .getString("TiledImageGraphics3");
0403: sendExceptionToListener(message,
0404: new ImagingException(e));
0405: // throw new RuntimeException(e.getMessage());
0406: }
0407:
0408: // Perform the graphics operation
0409: try {
0410: Object retVal = method.invoke(g2d, args);
0411: if (retVal != null
0412: && retVal.getClass() == boolean.class) {
0413: returnValue = ((Boolean) retVal).booleanValue();
0414: }
0415: } catch (Exception e) {
0416: String message = JaiI18N
0417: .getString("TiledImageGraphics3")
0418: + " " + name;
0419: sendExceptionToListener(message,
0420: new ImagingException(e));
0421: // throw new RuntimeException(e.getMessage());
0422: }
0423:
0424: // Dispose of the Graphics2D
0425: g2d.dispose();
0426:
0427: // Notify the TiledImage that writing to the tile is complete
0428: tiledImage.releaseWritableTile(tileX, tileY);
0429: }
0430: }
0431:
0432: return returnValue;
0433: }
0434:
0435: /**
0436: * Effect a graphics operation on the <code>TiledImage</code> by
0437: * creating a <code>BufferedImage</code> for each tile in the affected
0438: * region and using the corresponding <code>Graphics2D</code> to
0439: * perform the equivalent operation on the tile.
0440: *
0441: * @param s The encompassing <code>Shape</code>.
0442: * @param argTypes An array of the <code>Classes</code> of the arguments
0443: * of the specified operation.
0444: * @param args The arguments of the operation as an array of
0445: * <code>Object</code>s.
0446: */
0447: private boolean doGraphicsOp(Shape s, String name,
0448: Class[] argTypes, Object[] args) {
0449: Rectangle r = s.getBounds();
0450: return doGraphicsOp(r.x, r.y, r.width, r.height, name,
0451: argTypes, args);
0452: }
0453:
0454: // ---------- Methods from java.awt.Graphics ----------
0455:
0456: public Graphics create() {
0457: // Construct the TiledImageGraphics object from the current TiledImage.
0458: TiledImageGraphics tig = new TiledImageGraphics(tiledImage);
0459:
0460: // Copy the state of the current TiledImageGraphics object.
0461: copyState(tig);
0462:
0463: return tig;
0464: }
0465:
0466: // public Graphics create(int x, int y, int width, int height)
0467: // -- implemented in Graphics superclass
0468:
0469: public Color getColor() {
0470: return color;
0471: }
0472:
0473: public void setColor(Color c) {
0474: color = c;
0475: }
0476:
0477: public void setPaintMode() {
0478: paintMode = PAINT_MODE;
0479: }
0480:
0481: public void setXORMode(Color c1) {
0482: paintMode = XOR_MODE;
0483: XORColor = c1;
0484: }
0485:
0486: public Font getFont() {
0487: return font;
0488: }
0489:
0490: public void setFont(Font font) {
0491: this .font = font;
0492: }
0493:
0494: public FontMetrics getFontMetrics(Font f) {
0495: Graphics2D g2d = getBogusGraphics2D(true);
0496:
0497: FontMetrics fontMetrics = g2d.getFontMetrics(f);
0498:
0499: g2d.dispose();
0500:
0501: return fontMetrics;
0502: }
0503:
0504: public Rectangle getClipBounds() {
0505: return clip.getBounds();
0506: }
0507:
0508: public void clipRect(int x, int y, int width, int height) {
0509: clip(new Rectangle(x, y, width, height));
0510: }
0511:
0512: public void setClip(int x, int y, int width, int height) {
0513: setClip(new Rectangle(x, y, width, height));
0514: }
0515:
0516: public Shape getClip() {
0517: return clip;
0518: }
0519:
0520: public void setClip(Shape clip) {
0521: this .clip = clip;
0522: }
0523:
0524: public void copyArea(int x, int y, int width, int height, int dx,
0525: int dy) {
0526: Rectangle rect = getBoundingBox(new int[] { x, x + dx,
0527: x + width - 1, x + width - 1 + dx }, new int[] { y,
0528: y + dy, y + height - 1, y + height - 1 + dy }, 4);
0529:
0530: doGraphicsOp(rect, "copyArea",
0531: new Class[] { int.class, int.class, int.class,
0532: int.class, int.class, int.class },
0533: new Object[] { new Integer(x), new Integer(y),
0534: new Integer(width), new Integer(height),
0535: new Integer(dx), new Integer(dy) });
0536: }
0537:
0538: public void drawLine(int x1, int y1, int x2, int y2) {
0539: Rectangle rect = getBoundingBox(new int[] { x1, x2 },
0540: new int[] { y1, y2 }, 2);
0541:
0542: doGraphicsOp(rect, "drawLine", new Class[] { int.class,
0543: int.class, int.class, int.class }, new Object[] {
0544: new Integer(x1), new Integer(y1), new Integer(x2),
0545: new Integer(y2) });
0546: }
0547:
0548: public void fillRect(int x, int y, int width, int height) {
0549: doGraphicsOp(x, y, width, height, "fillRect", new Class[] {
0550: int.class, int.class, int.class, int.class },
0551: new Object[] { new Integer(x), new Integer(y),
0552: new Integer(width), new Integer(height) });
0553: }
0554:
0555: // public void drawRect(int x, int y, int width, int height)
0556: // -- implemented in Graphics superclass
0557:
0558: public void clearRect(int x, int y, int width, int height) {
0559: doGraphicsOp(x, y, width, height, "clearRect", new Class[] {
0560: int.class, int.class, int.class, int.class },
0561: new Object[] { new Integer(x), new Integer(y),
0562: new Integer(width), new Integer(height) });
0563: }
0564:
0565: public void drawRoundRect(int x, int y, int width, int height,
0566: int arcWidth, int arcHeight) {
0567: doGraphicsOp(x - arcWidth, y - arcHeight, width + 2 * arcWidth,
0568: height + 2 * arcHeight, "drawRoundRect", new Class[] {
0569: int.class, int.class, int.class, int.class,
0570: int.class, int.class }, new Object[] {
0571: new Integer(x), new Integer(y),
0572: new Integer(width), new Integer(height),
0573: new Integer(arcWidth), new Integer(arcHeight) });
0574: }
0575:
0576: public void fillRoundRect(int x, int y, int width, int height,
0577: int arcWidth, int arcHeight) {
0578: doGraphicsOp(x - arcWidth, y - arcHeight, width + 2 * arcWidth,
0579: height + 2 * arcHeight, "fillRoundRect", new Class[] {
0580: int.class, int.class, int.class, int.class,
0581: int.class, int.class }, new Object[] {
0582: new Integer(x), new Integer(y),
0583: new Integer(width), new Integer(height),
0584: new Integer(arcWidth), new Integer(arcHeight) });
0585: }
0586:
0587: // draw3DRect() is implemented in the Graphics superclass but is
0588: // overridden in Graphics2D and so must be implemented here.
0589: public void draw3DRect(int x, int y, int width, int height,
0590: boolean raised) {
0591: doGraphicsOp(x, y, width, height, "draw3DRect", new Class[] {
0592: int.class, int.class, int.class, int.class,
0593: boolean.class }, new Object[] { new Integer(x),
0594: new Integer(y), new Integer(width),
0595: new Integer(height), new Boolean(raised) });
0596: }
0597:
0598: // fill3DRect() is implemented in the Graphics superclass but is
0599: // overridden in Graphics2D and so must be implemented here.
0600: public void fill3DRect(int x, int y, int width, int height,
0601: boolean raised) {
0602: doGraphicsOp(x, y, width, height, "fill3DRect", new Class[] {
0603: int.class, int.class, int.class, int.class,
0604: boolean.class }, new Object[] { new Integer(x),
0605: new Integer(y), new Integer(width),
0606: new Integer(height), new Boolean(raised) });
0607: }
0608:
0609: public void drawOval(int x, int y, int width, int height) {
0610: doGraphicsOp(x, y, width, height, "drawOval", new Class[] {
0611: int.class, int.class, int.class, int.class },
0612: new Object[] { new Integer(x), new Integer(y),
0613: new Integer(width), new Integer(height) });
0614: }
0615:
0616: public void fillOval(int x, int y, int width, int height) {
0617: doGraphicsOp(x, y, width, height, "fillOval", new Class[] {
0618: int.class, int.class, int.class, int.class },
0619: new Object[] { new Integer(x), new Integer(y),
0620: new Integer(width), new Integer(height) });
0621: }
0622:
0623: public void drawArc(int x, int y, int width, int height,
0624: int startAngle, int arcAngle) {
0625: doGraphicsOp(x, y, width, height, "drawArc", new Class[] {
0626: int.class, int.class, int.class, int.class, int.class,
0627: int.class }, new Object[] { new Integer(x),
0628: new Integer(y), new Integer(width),
0629: new Integer(height), new Integer(startAngle),
0630: new Integer(arcAngle) });
0631: }
0632:
0633: public void fillArc(int x, int y, int width, int height,
0634: int startAngle, int arcAngle) {
0635: doGraphicsOp(x, y, width, height, "fillArc", new Class[] {
0636: int.class, int.class, int.class, int.class, int.class,
0637: int.class }, new Object[] { new Integer(x),
0638: new Integer(y), new Integer(width),
0639: new Integer(height), new Integer(startAngle),
0640: new Integer(arcAngle) });
0641: }
0642:
0643: public void drawPolyline(int xPoints[], int yPoints[], int nPoints) {
0644: Class intArrayClass = xPoints.getClass();
0645: Rectangle box = getBoundingBox(xPoints, yPoints, nPoints);
0646:
0647: if (box == null)
0648: return;
0649:
0650: doGraphicsOp(box, "drawPolyline", new Class[] { intArrayClass,
0651: intArrayClass, int.class }, new Object[] { xPoints,
0652: yPoints, new Integer(nPoints) });
0653: }
0654:
0655: public void drawPolygon(int xPoints[], int yPoints[], int nPoints) {
0656: Class intArrayClass = xPoints.getClass();
0657: Rectangle box = getBoundingBox(xPoints, yPoints, nPoints);
0658:
0659: if (box == null)
0660: return;
0661:
0662: doGraphicsOp(box, "drawPolygon", new Class[] { intArrayClass,
0663: intArrayClass, int.class }, new Object[] { xPoints,
0664: yPoints, new Integer(nPoints) });
0665: }
0666:
0667: // public void drawPolygon(Polygon) -- implemented in Graphics superclass
0668:
0669: public void fillPolygon(int xPoints[], int yPoints[], int nPoints) {
0670: Class intArrayClass = xPoints.getClass();
0671: Rectangle box = getBoundingBox(xPoints, yPoints, nPoints);
0672:
0673: if (box == null)
0674: return;
0675:
0676: doGraphicsOp(box, "fillPolygon", new Class[] { intArrayClass,
0677: intArrayClass, int.class }, new Object[] { xPoints,
0678: yPoints, new Integer(nPoints) });
0679: }
0680:
0681: // public void fillPolygon(Polygon) -- implemented in Graphics superclass
0682:
0683: public void drawString(String str, int x, int y) {
0684: Rectangle2D r2d = getFontMetrics(getFont()).getStringBounds(
0685: str, this );
0686:
0687: r2d.setRect(x, y - r2d.getHeight() + 1, r2d.getWidth(), r2d
0688: .getHeight());
0689:
0690: doGraphicsOp(r2d, "drawString", new Class[] {
0691: java.lang.String.class, int.class, int.class },
0692: new Object[] { str, new Integer(x), new Integer(y) });
0693: }
0694:
0695: // public void drawChars -- implemented in Graphics superclass
0696: // public void drawBytes -- implemented in Graphics superclass
0697:
0698: public boolean drawImage(Image img, int x, int y,
0699: ImageObserver observer) {
0700: return doGraphicsOp(x, y, img.getWidth(observer), img
0701: .getHeight(observer), "drawImage", new Class[] {
0702: java.awt.Image.class, int.class, int.class,
0703: java.awt.image.ImageObserver.class }, new Object[] {
0704: img, new Integer(x), new Integer(y), observer });
0705: }
0706:
0707: public void drawRenderedImage(RenderedImage im,
0708: AffineTransform transform) {
0709: Rectangle2D.Double srcRect = new Rectangle2D.Double(im
0710: .getMinX(), im.getMinY(), im.getWidth(), im.getHeight());
0711:
0712: Rectangle2D dstRect = transform.createTransformedShape(srcRect)
0713: .getBounds2D();
0714:
0715: doGraphicsOp(dstRect, "drawRenderedImage", new Class[] {
0716: java.awt.image.RenderedImage.class,
0717: java.awt.geom.AffineTransform.class }, new Object[] {
0718: im, transform });
0719: }
0720:
0721: public void drawRenderableImage(RenderableImage img,
0722: AffineTransform xform) {
0723: Rectangle2D.Double srcRect = new Rectangle2D.Double(img
0724: .getMinX(), img.getMinY(), img.getWidth(), img
0725: .getHeight());
0726:
0727: Rectangle2D dstRect = xform.createTransformedShape(srcRect)
0728: .getBounds2D();
0729:
0730: doGraphicsOp(dstRect, "drawRenderableImage", new Class[] {
0731: java.awt.image.renderable.RenderableImage.class,
0732: java.awt.geom.AffineTransform.class }, new Object[] {
0733: img, xform });
0734: }
0735:
0736: public boolean drawImage(Image img, int x, int y, int width,
0737: int height, ImageObserver observer) {
0738: return doGraphicsOp(x, y, width, height, "drawImage",
0739: new Class[] { java.awt.Image.class, int.class,
0740: int.class, int.class, int.class,
0741: java.awt.image.ImageObserver.class },
0742: new Object[] { img, new Integer(x), new Integer(y),
0743: new Integer(width), new Integer(height),
0744: observer });
0745: }
0746:
0747: public boolean drawImage(Image img, int x, int y, Color bgcolor,
0748: ImageObserver observer) {
0749: return doGraphicsOp(x, y, img.getWidth(observer), img
0750: .getHeight(observer), "drawImage", new Class[] {
0751: java.awt.Image.class, int.class, int.class,
0752: java.awt.Color.class,
0753: java.awt.image.ImageObserver.class },
0754: new Object[] { img, new Integer(x), new Integer(y),
0755: bgcolor, observer });
0756: }
0757:
0758: public boolean drawImage(Image img, int x, int y, int width,
0759: int height, Color bgcolor, ImageObserver observer) {
0760: return doGraphicsOp(x, y, width, height, "drawImage",
0761: new Class[] { java.awt.Image.class, int.class,
0762: int.class, int.class, int.class,
0763: java.awt.Color.class,
0764: java.awt.image.ImageObserver.class },
0765: new Object[] { img, new Integer(x), new Integer(y),
0766: new Integer(width), new Integer(height),
0767: bgcolor, observer });
0768: }
0769:
0770: public boolean drawImage(Image img, int dx1, int dy1, int dx2,
0771: int dy2, int sx1, int sy1, int sx2, int sy2,
0772: ImageObserver observer) {
0773: return doGraphicsOp(dx1, dy1, dx2 - dx1 + 1, dy2 - dy1 + 1,
0774: "drawImage", new Class[] { java.awt.Image.class,
0775: int.class, int.class, int.class, int.class,
0776: int.class, int.class, int.class, int.class,
0777: java.awt.image.ImageObserver.class },
0778: new Object[] { img, new Integer(dx1), new Integer(dy1),
0779: new Integer(dx2), new Integer(dy2),
0780: new Integer(sx1), new Integer(sy1),
0781: new Integer(sx2), new Integer(sy2), observer });
0782: }
0783:
0784: public boolean drawImage(Image img, int dx1, int dy1, int dx2,
0785: int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor,
0786: ImageObserver observer) {
0787: return doGraphicsOp(dx1, dy1, dx2 - dx1 + 1, dy2 - dy1 + 1,
0788: "drawImage", new Class[] { java.awt.Image.class,
0789: int.class, int.class, int.class, int.class,
0790: int.class, int.class, int.class, int.class,
0791: java.awt.Color.class,
0792: java.awt.image.ImageObserver.class },
0793: new Object[] { img, new Integer(dx1), new Integer(dy1),
0794: new Integer(dx2), new Integer(dy2),
0795: new Integer(sx1), new Integer(sy1),
0796: new Integer(sx2), new Integer(sy2), bgcolor,
0797: observer });
0798: }
0799:
0800: public void dispose() {
0801: // No resources need to be released.
0802: }
0803:
0804: // public void finalize -- implemented in Graphics superclass
0805: // public String toString -- implemented in Graphics superclass
0806:
0807: // ---------- Methods from java.awt.Graphics2D ----------
0808:
0809: public void addRenderingHints(Map hints) {
0810: renderingHints.putAll(hints);
0811: }
0812:
0813: public void draw(Shape s) {
0814: doGraphicsOp(s.getBounds(), "draw",
0815: new Class[] { java.awt.Shape.class },
0816: new Object[] { s });
0817: }
0818:
0819: public boolean drawImage(Image img, AffineTransform xform,
0820: ImageObserver obs) {
0821: Rectangle2D.Double srcRect = new Rectangle2D.Double(0, 0, img
0822: .getWidth(obs), img.getHeight(obs));
0823:
0824: Rectangle2D dstRect = transform.createTransformedShape(srcRect)
0825: .getBounds2D();
0826:
0827: return doGraphicsOp(dstRect, "drawImage", new Class[] {
0828: java.awt.Image.class,
0829: java.awt.geom.AffineTransform.class,
0830: java.awt.image.ImageObserver.class }, new Object[] {
0831: img, xform, obs });
0832: }
0833:
0834: public void drawImage(BufferedImage img, BufferedImageOp op, int x,
0835: int y) {
0836: doGraphicsOp(op.getBounds2D(img), "drawImage", new Class[] {
0837: java.awt.image.BufferedImage.class,
0838: java.awt.image.BufferedImageOp.class, int.class,
0839: int.class }, new Object[] { img, op, new Integer(x),
0840: new Integer(y) });
0841: }
0842:
0843: public void drawString(String s, float x, float y) {
0844: Rectangle2D r2d = getFontMetrics(getFont()).getStringBounds(s,
0845: this );
0846:
0847: r2d.setRect(x, y - r2d.getHeight() + 1, r2d.getWidth(), r2d
0848: .getHeight());
0849:
0850: doGraphicsOp(r2d, "drawString", new Class[] {
0851: java.lang.String.class, float.class, float.class },
0852: new Object[] { s, new Float(x), new Float(y) });
0853: }
0854:
0855: public void drawString(AttributedCharacterIterator iterator, int x,
0856: int y) {
0857: Rectangle2D r2d = getFontMetrics(getFont()).getStringBounds(
0858: iterator, iterator.getBeginIndex(),
0859: iterator.getEndIndex(), this );
0860:
0861: r2d.setRect(x, y - r2d.getHeight() + 1, r2d.getWidth(), r2d
0862: .getHeight());
0863:
0864: doGraphicsOp(r2d, "drawString", new Class[] {
0865: java.text.AttributedCharacterIterator.class, int.class,
0866: int.class }, new Object[] { iterator, new Integer(x),
0867: new Integer(y) });
0868: }
0869:
0870: public void drawString(AttributedCharacterIterator iterator,
0871: float x, float y) {
0872: Rectangle2D r2d = getFontMetrics(getFont()).getStringBounds(
0873: iterator, iterator.getBeginIndex(),
0874: iterator.getEndIndex(), this );
0875:
0876: r2d.setRect(x, y - r2d.getHeight() + 1, r2d.getWidth(), r2d
0877: .getHeight());
0878:
0879: doGraphicsOp(r2d, "drawString", new Class[] {
0880: java.text.AttributedCharacterIterator.class,
0881: float.class, float.class }, new Object[] { iterator,
0882: new Float(x), new Float(y) });
0883: }
0884:
0885: public void drawGlyphVector(GlyphVector g, float x, float y) {
0886: doGraphicsOp(g.getVisualBounds(), "drawGlyphVector",
0887: new Class[] { java.awt.font.GlyphVector.class,
0888: float.class, float.class }, new Object[] { g,
0889: new Float(x), new Float(y) });
0890: }
0891:
0892: public void fill(Shape s) {
0893: doGraphicsOp(s.getBounds(), "fill",
0894: new Class[] { java.awt.Shape.class },
0895: new Object[] { s });
0896: }
0897:
0898: public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
0899: Graphics2D g2d = getBogusGraphics2D(true);
0900:
0901: boolean hitTarget = g2d.hit(rect, s, onStroke);
0902:
0903: g2d.dispose();
0904:
0905: return hitTarget;
0906: }
0907:
0908: public GraphicsConfiguration getDeviceConfiguration() {
0909: Graphics2D g2d = getBogusGraphics2D(true);
0910:
0911: GraphicsConfiguration gConf = g2d.getDeviceConfiguration();
0912:
0913: g2d.dispose();
0914:
0915: return gConf;
0916: }
0917:
0918: public void setComposite(Composite comp) {
0919: composite = comp;
0920: }
0921:
0922: public void setPaint(Paint paint) {
0923: this .paint = paint;
0924: }
0925:
0926: public void setStroke(Stroke s) {
0927: stroke = s;
0928: }
0929:
0930: public void setRenderingHint(RenderingHints.Key hintKey,
0931: Object hintValue) {
0932: renderingHints.put(hintKey, hintValue);
0933: }
0934:
0935: public Object getRenderingHint(RenderingHints.Key hintKey) {
0936: return renderingHints.get(hintKey);
0937: }
0938:
0939: public void setRenderingHints(Map hints) {
0940: renderingHints.putAll(hints);
0941: }
0942:
0943: public RenderingHints getRenderingHints() {
0944: return renderingHints;
0945: }
0946:
0947: public void translate(int x, int y) {
0948: origin = new Point(x, y);
0949: transform.translate((double) x, (double) y);
0950: }
0951:
0952: public void translate(double x, double y) {
0953: transform.translate(x, y);
0954: }
0955:
0956: public void rotate(double theta) {
0957: transform.rotate(theta);
0958: }
0959:
0960: public void rotate(double theta, double x, double y) {
0961: transform.rotate(theta, x, y);
0962: }
0963:
0964: public void scale(double sx, double sy) {
0965: transform.scale(sx, sy);
0966: }
0967:
0968: public void shear(double shx, double shy) {
0969: transform.shear(shx, shy);
0970: }
0971:
0972: public void transform(AffineTransform Tx) {
0973: transform.concatenate(Tx);
0974: }
0975:
0976: public void setTransform(AffineTransform Tx) {
0977: transform = Tx;
0978: }
0979:
0980: public AffineTransform getTransform() {
0981: return transform;
0982: }
0983:
0984: public Paint getPaint() {
0985: return paint;
0986: }
0987:
0988: public Composite getComposite() {
0989: return composite;
0990: }
0991:
0992: public void setBackground(Color color) {
0993: background = color;
0994: }
0995:
0996: public Color getBackground() {
0997: return background;
0998: }
0999:
1000: public Stroke getStroke() {
1001: return stroke;
1002: }
1003:
1004: public void clip(Shape s) {
1005: if (clip == null) {
1006: clip = s;
1007: } else {
1008: Area clipArea = (clip instanceof Area ? (Area) clip
1009: : new Area(clip));
1010: clipArea.intersect(s instanceof Area ? (Area) s : new Area(
1011: s));
1012: clip = clipArea;
1013: }
1014: }
1015:
1016: public FontRenderContext getFontRenderContext() {
1017: Graphics2D g2d = getBogusGraphics2D(true);
1018:
1019: FontRenderContext fontRenderContext = g2d
1020: .getFontRenderContext();
1021:
1022: g2d.dispose();
1023:
1024: return fontRenderContext;
1025: }
1026:
1027: void sendExceptionToListener(String message, Exception e) {
1028: ImagingListener listener = null;
1029: if (renderingHints != null)
1030: listener = (ImagingListener) renderingHints
1031: .get(JAI.KEY_IMAGING_LISTENER);
1032:
1033: if (listener == null)
1034: listener = JAI.getDefaultInstance().getImagingListener();
1035: listener.errorOccurred(message, e, this , false);
1036: }
1037: }
|