Source for gnu.awt.j2d.Graphics2DImpl

   1: /* Copyright (C) 2000, 2002, 2003  Free Software Foundation
   2: 
   3:    This file is part of libgcj.
   4: 
   5: This software is copyrighted work licensed under the terms of the
   6: Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
   7: details.  */
   8: 
   9: package gnu.awt.j2d;
  10: 
  11: import java.awt.Color;
  12: import java.awt.Composite;
  13: import java.awt.Image;
  14: import java.awt.Shape;
  15: import java.awt.Rectangle;
  16: import java.awt.Graphics;
  17: import java.awt.Graphics2D;
  18: import java.awt.GraphicsConfiguration;
  19: import java.awt.Font;
  20: import java.awt.FontMetrics;
  21: import java.awt.Paint;
  22: import java.awt.RenderingHints;
  23: import java.awt.Stroke;
  24: import java.awt.font.FontRenderContext;
  25: import java.awt.font.GlyphVector;
  26: import java.awt.geom.AffineTransform;
  27: import java.awt.image.ImageObserver;
  28: import java.awt.image.BufferedImage;
  29: import java.awt.image.BufferedImageOp;
  30: import java.awt.image.RenderedImage;
  31: import java.awt.image.renderable.RenderableImage;
  32: import java.text.AttributedCharacterIterator;
  33: import java.util.Map;
  34: 
  35: /**
  36:  * Delegates almost all work to a state object, that allows us to
  37:  * hot-swap rendering strategies based on state changes inflicted on
  38:  * this Graphics object. This class keeps track of properties that are
  39:  * not affected by the state, (such as clip shape,
  40:  * foreground/background color, font, etc.).
  41:  *
  42:  * <p>The far front-end of the rendering pipeline consists of the
  43:  * Graphics2D API. In the far back-end, lies the native graphics
  44:  * libraries. In most cases the native graphics libraries only have
  45:  * direct support for a subset of the properties of Graphics2D. To
  46:  * make up missing features in the native graphics libraries, the
  47:  * pipeline between the front-end and the back-end need to translate
  48:  * drawing request to primitive operations that are supported by the
  49:  * back-end. E.g. for X11, drawing a straight line will translate to
  50:  * an XDrawLine, drawing a bezier curve will trigger flattening of the
  51:  * curve and will result in a call to XDrawLines.
  52:  *
  53:  * <p>This is the basic strategy for the rendering pipeline: Whenever
  54:  * a graphics property change occurs, that causes the current pipeline
  55:  * to be insufficient, amend or replace parts of the pipeline so that
  56:  * the pipeline will once again be able to translate requests to the
  57:  * set of primitives supported by the native graphics library.
  58:  *
  59:  * <p>Most graphics libraries share common subsets of
  60:  * functionality. To be able to reuse pieces of the rendering pipeline
  61:  * for several backends, we define interfaces that describe subsets of
  62:  * characteristics supported by the backends. A wrapper for the native
  63:  * library can implement several interfaces to describe its range of
  64:  * functionality.
  65:  *
  66:  * <p>Typically, most painting is done with a graphics object with
  67:  * simple properties. Unless one is using a complex Look & Feel, the
  68:  * painting of Swing components will never require affine transforms,
  69:  * alpha blending, non-rectangular clipping, etc. When graphics
  70:  * objects are created, they start off in a state where all the
  71:  * properties are simple. Most graphics objects experience only
  72:  * trivial property changes, and never leave this simple state. It is
  73:  * therefore wise to ensure that the rendering pipeline for this
  74:  * initial state is lean and as much as possible plugs directly into
  75:  * the backend.
  76:  *
  77:  * <p>The initial state for graphics object of most raster displays
  78:  * would call for two levels of indirection:
  79:  *
  80:  * <pre>
  81:  * Graphics2D object ---> IntegerGraphicsState ---> DirectRasterGraphics
  82:  * </pre>
  83:  */
  84: public class Graphics2DImpl extends Graphics2D implements Cloneable
  85: {
  86:   GraphicsConfiguration config;
  87: 
  88:   AbstractGraphicsState state;
  89:     
  90:   Color fg;
  91:   Color bg;
  92: 
  93:   Font font;
  94:   
  95:   public Graphics2DImpl(GraphicsConfiguration config)
  96:   {
  97:     this.config = config;
  98:   }
  99:   
 100:   public void setState(AbstractGraphicsState state)
 101:   {
 102:     this.state = state;
 103:     this.state.setFrontend(this);
 104:   }
 105:     
 106:   public Object clone()
 107:   {
 108:     try
 109:       {
 110:     Graphics2DImpl gfxCopy = (Graphics2DImpl) super.clone();
 111:     AbstractGraphicsState stateCopy =
 112:       (AbstractGraphicsState) state.clone();
 113:     gfxCopy.setState(stateCopy);
 114:     
 115:     return gfxCopy;
 116:       }
 117:     catch (CloneNotSupportedException ex)
 118:       {
 119:     // This should never happen.
 120:     throw new InternalError ();
 121:       }
 122:   }
 123: 
 124: 
 125:   // -------- Graphics methods:
 126: 
 127:   public Graphics create()
 128:   {
 129:     Graphics2DImpl gfxCopy = (Graphics2DImpl) clone();
 130:     return gfxCopy;
 131:   }
 132: 
 133:   public Color getColor()
 134:   {
 135:     return fg;
 136:   }
 137:   
 138:   public void setColor(Color color)
 139:   {
 140:     fg = color;
 141:     state.setColor(color);
 142:   }
 143: 
 144:   public void setPaintMode()
 145:   {
 146:     state.setPaintMode();
 147:   }
 148: 
 149:   public void setXORMode(Color altColor)
 150:   {
 151:     state.setXORMode(altColor);
 152:   }
 153: 
 154:   public Font getFont()
 155:   {
 156:     return font;
 157:   }
 158: 
 159:   public void setFont(Font font)
 160:   {
 161:     this.font = font;
 162:     state.setFont(font);
 163:   }
 164:     
 165:   public FontMetrics getFontMetrics(Font font)
 166:   {
 167:     return state.getFontMetrics(font);
 168:   }
 169: 
 170:   public Rectangle getClipBounds()
 171:   {
 172:     return state.getClipBounds();
 173:   }
 174:     
 175:   public void clipRect(int x, int y, int width, int height)
 176:   {
 177:     Shape clip = state.getClip();
 178:     if (clip == null)
 179:     {
 180:       clip = new Rectangle (x,y,width,height);
 181:       setClip (clip);
 182:       return;
 183:     }
 184:     if (clip instanceof Rectangle)
 185:       {
 186:     Rectangle clipRect = (Rectangle) clip;
 187:     clip = clipRect.intersection(new Rectangle(x, y, width, height));
 188:     setClip(clip);
 189:     return;
 190:       }
 191:     
 192:     String msg =
 193:       "intersecting current clip shape " + clip + " with new rectangle " +
 194:       "has not been implemented yet";
 195:     throw new UnsupportedOperationException(msg);
 196:   }
 197: 
 198:   public void setClip(int x, int y, int width, int height)
 199:   {
 200:     Rectangle clip = new Rectangle(x, y, width, height);
 201:     setClip(clip);
 202:   }
 203: 
 204:   public Shape getClip()
 205:   {
 206:     return state.getClip();
 207:   }
 208: 
 209:   public void setClip(Shape clip)
 210:   {
 211:     state.setClip(clip);
 212:   }
 213: 
 214:   public void copyArea(int x, int y, int width, int height,
 215:                int dx, int dy)
 216:   {
 217:     state.copyArea(x, y, width, height, dx, dy);
 218:   }
 219: 
 220:   public void drawLine(int x1, int y1, int x2, int y2)
 221:   {
 222:     state.drawLine(x1, y1, x2, y2);
 223:   }
 224:     
 225:   public void fillRect(int x, int y, int width, int height)
 226:   {
 227:     state.fillRect(x, y, width, height);
 228:   }
 229:     
 230:   public void clearRect(int x, int y, int width, int height)
 231:   {
 232:     state.clearRect(x, y, width, height);
 233:   }
 234:   
 235:   public void drawRoundRect(int x, int y, int width, int height,
 236:                 int arcWidth, int arcHeight)
 237:   {
 238:     state.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
 239:   }
 240:     
 241:   public void fillRoundRect(int x, int y, int width, int height,
 242:                 int arcWidth, int arcHeight)
 243:   {
 244:     state.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
 245:   }
 246: 
 247:   public void drawOval(int x, int y, int width, int height)
 248:   {
 249:     state.drawOval(x, y, width, height);
 250:   }
 251: 
 252:   public void fillOval(int x, int y, int width, int height)
 253:   {
 254:     state.fillOval(x, y, width, height);
 255:   }
 256: 
 257:   public void drawArc(int x, int y, int width, int height,
 258:               int startAngle, int arcAngle)
 259:   {
 260:     state.drawArc(x, y, width, height, startAngle, arcAngle);
 261:   }
 262: 
 263:   public void fillArc(int x, int y, int width, int height,
 264:               int startAngle, int arcAngle)
 265:   {
 266:     state.fillArc(x, y, width, height, startAngle, arcAngle);
 267:   }
 268: 
 269:   public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
 270:   {
 271:     state.drawPolyline(xPoints, yPoints, nPoints);
 272:   }
 273:   
 274:   public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
 275:   {
 276:     state.drawPolygon(xPoints, yPoints, nPoints);
 277:   }
 278:     
 279:   public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
 280:   {
 281:     state.fillPolygon(xPoints, yPoints, nPoints);
 282:   }
 283:     
 284:   public boolean drawImage(Image image, int x, int y,
 285:                ImageObserver observer)
 286:   {
 287:     return state.drawImage(image, x, y, observer);
 288:   }
 289: 
 290:   public boolean drawImage(Image img, int x, int y,
 291:                int width, int height,
 292:                ImageObserver observer)
 293:   {
 294:     throw new UnsupportedOperationException("not implemented yet");
 295:   }
 296: 
 297:   public boolean drawImage(Image img, int x, int y, Color bgcolor,
 298:                ImageObserver observer)
 299:   {
 300:     throw new UnsupportedOperationException("not implemented yet");
 301:   }
 302:   
 303:   public boolean drawImage(Image img, int x, int y,
 304:                int width, int height, Color bgcolor,
 305:                ImageObserver observer)
 306:   {
 307:     throw new UnsupportedOperationException("not implemented yet");
 308:   }
 309: 
 310:   public boolean drawImage(Image img,
 311:                int dx1, int dy1, int dx2, int dy2,
 312:                int sx1, int sy1, int sx2, int sy2,
 313:                ImageObserver observer)
 314:   {
 315:     throw new UnsupportedOperationException("not implemented yet");
 316:   }
 317:   
 318:   public boolean drawImage(Image img,
 319:                int dx1, int dy1, int dx2, int dy2,
 320:                int sx1, int sy1, int sx2, int sy2,
 321:                Color bgcolor, ImageObserver observer)
 322:   {
 323:     throw new UnsupportedOperationException("not implemented yet");
 324:   }
 325:   
 326:   public void dispose()
 327:   {
 328:     AbstractGraphicsState lState = state;
 329:     
 330:     state = null;
 331:     config = null;
 332:     font = null;
 333:     fg = null;
 334:     bg = null;
 335:     
 336:     if (lState != null)
 337:       lState.dispose();
 338:   }
 339:     
 340: 
 341: 
 342:   // -------- Graphics2D methods:
 343:     
 344:   public void draw(Shape shape)
 345:   {
 346:     state.draw(shape);
 347:   }
 348:   
 349:   public boolean drawImage(Image image, AffineTransform xform,
 350:                ImageObserver obs)
 351:   {
 352:     throw new UnsupportedOperationException("not implemented yet");
 353:   }
 354: 
 355: 
 356:   public void drawString(String text, int x, int y)
 357:   {
 358:     state.drawString(text, x, y);
 359:   }
 360: 
 361:   public void drawString(String text, float x, float y)
 362:   {
 363:     state.drawString(text, x, y);
 364:   }
 365: 
 366:   public void fill(Shape shape)
 367:   {
 368:     state.fill(shape);
 369:   }
 370: 
 371:   public boolean hit(Rectangle rect, Shape text, boolean onStroke)
 372:   {
 373:     return state.hit(rect, text, onStroke);
 374:   }
 375:     
 376:   public GraphicsConfiguration getDeviceConfiguration()
 377:   {
 378:     return config;
 379:   }
 380: 
 381:   public void setPaint(Paint paint)
 382:   {
 383:     throw new UnsupportedOperationException("not implemented yet");
 384:   }
 385: 
 386:   public void setRenderingHint(RenderingHints.Key hintKey,
 387:                    Object hintValue)
 388:   {
 389:     throw new UnsupportedOperationException("not implemented yet");
 390:   }
 391:   
 392:   public Object getRenderingHint(RenderingHints.Key hintKey)
 393:   {
 394:     throw new UnsupportedOperationException("not implemented yet");
 395:   }
 396: 
 397:   public RenderingHints getRenderingHints()
 398:   {
 399:     throw new UnsupportedOperationException("not implemented yet");
 400:   }
 401:     
 402:   public void translate(int x, int y)
 403:   {
 404:     state.translate(x, y);
 405:   }
 406:   
 407:   public void translate(double tx, double ty)
 408:   {
 409:     state.translate(tx, ty);
 410:   }
 411:     
 412:   public void rotate(double theta)
 413:   {
 414:     state.rotate(theta);
 415:   }
 416: 
 417:   public void rotate(double theta, double x, double y)
 418:   {
 419:     state.rotate(theta, x, y);
 420:   }
 421:   
 422:   public void scale(double scaleX, double scaleY)
 423:   {
 424:     state.scale(scaleX, scaleY);
 425:   }
 426:   
 427:   public void shear(double shearX, double shearY)
 428:   {
 429:     state.shear(shearX, shearY);
 430:   }
 431: 
 432:   public void transform(AffineTransform Tx)
 433:   {
 434:     throw new UnsupportedOperationException("not implemented yet");
 435:   }
 436: 
 437:   public void setTransform(AffineTransform Tx)
 438:   {
 439:     throw new UnsupportedOperationException("not implemented yet");
 440:   }
 441:     
 442:   public AffineTransform getTransform()
 443:   {
 444:     throw new UnsupportedOperationException("not implemented yet");
 445:   }
 446: 
 447:   public Paint getPaint()
 448:   {
 449:     throw new UnsupportedOperationException("not implemented yet");
 450:   }
 451:     
 452:   public void setBackground(Color color)
 453:   {
 454:     bg = color;
 455:   }
 456: 
 457:   public Color getBackground()
 458:   {
 459:     return bg;
 460:   }
 461: 
 462:   public void clip(Shape shape)
 463:   {
 464:     Shape clip = state.getClip();
 465:     
 466:     if ((shape instanceof Rectangle) && (clip instanceof Rectangle))
 467:       {
 468:     clip = ((Rectangle) clip).intersection((Rectangle) shape);
 469:     state.setClip(clip);
 470:     return;
 471:       }
 472:     
 473:     String msg =
 474:       "intersecting current clip shape " + clip + " with new shape " + shape +
 475:       "has not been implemented yet";
 476:     throw new UnsupportedOperationException(msg);
 477:   }
 478:   
 479:   public void drawImage(BufferedImage image, BufferedImageOp op, int x, int y)
 480:   {
 481:     throw new UnsupportedOperationException("not implemented yet");  
 482:   }
 483: 
 484:   public void drawRenderedImage(RenderedImage image, AffineTransform xform)
 485:   {
 486:     throw new UnsupportedOperationException("not implemented yet");  
 487:   }
 488: 
 489:   public void drawRenderableImage(RenderableImage image, AffineTransform xform)
 490:   {
 491:     throw new UnsupportedOperationException("not implemented yet");
 492:   }
 493: 
 494:   public void drawString(AttributedCharacterIterator iterator,
 495:                           int x, int y)
 496:   {
 497:     throw new UnsupportedOperationException("not implemented yet");  
 498:   }
 499: 
 500:   public void drawString(AttributedCharacterIterator iterator, float x, 
 501:              float y)
 502:   {
 503:     throw new UnsupportedOperationException("not implemented yet");
 504:   }
 505: 
 506:   public void setComposite(Composite comp)
 507:   {
 508:     throw new UnsupportedOperationException("not implemented yet");
 509:   }
 510: 
 511:   public void setStroke(Stroke stroke)
 512:   {
 513:     throw new UnsupportedOperationException("not implemented yet");
 514:   }
 515: 
 516:   public void setRenderingHints(Map hints)
 517:   {
 518:     throw new UnsupportedOperationException("not implemented yet");
 519:   }
 520: 
 521:   public void addRenderingHints(Map hints)
 522:   {
 523:     throw new UnsupportedOperationException("not implemented yet");
 524:   }
 525: 
 526:   public Composite getComposite()
 527:   {
 528:     throw new UnsupportedOperationException("not implemented yet");
 529:   }
 530: 
 531:   public Stroke getStroke()
 532:   {
 533:     throw new UnsupportedOperationException("not implemented yet");
 534:   }
 535: 
 536:   public FontRenderContext getFontRenderContext ()
 537:   {
 538:     throw new UnsupportedOperationException("not implemented yet");
 539:   }
 540: 
 541:   public void drawGlyphVector (GlyphVector g, float x, float y)
 542:   {
 543:     throw new UnsupportedOperationException("not implemented yet");
 544:   }
 545: }