Source for gnu.java.awt.peer.qt.QtGraphics

   1: /* QtGraphics.java --
   2:    Copyright (C)  2005, 2006  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: package gnu.java.awt.peer.qt;
  39: 
  40: import java.awt.AlphaComposite;
  41: import java.awt.AWTPermission;
  42: import java.awt.BasicStroke;
  43: import java.awt.Color;
  44: import java.awt.Composite;
  45: import java.awt.GradientPaint;
  46: import java.awt.GraphicsConfiguration;
  47: import java.awt.Font;
  48: import java.awt.FontMetrics;
  49: import java.awt.Graphics;
  50: import java.awt.Graphics2D;
  51: import java.awt.Image;
  52: import java.awt.RenderingHints;
  53: import java.awt.Rectangle;
  54: import java.awt.Paint;
  55: import java.awt.Polygon;
  56: import java.awt.Shape;
  57: import java.awt.Stroke;
  58: import java.awt.font.FontRenderContext;
  59: import java.awt.font.GlyphVector;
  60: import java.awt.geom.AffineTransform;
  61: import java.awt.geom.Arc2D;
  62: import java.awt.geom.Ellipse2D;
  63: import java.awt.geom.Line2D;
  64: import java.awt.geom.Rectangle2D;
  65: import java.awt.geom.RoundRectangle2D;
  66: import java.awt.image.BufferedImage;
  67: import java.awt.image.BufferedImageOp;
  68: import java.awt.image.ImageObserver;
  69: import java.awt.image.RenderedImage;
  70: import java.awt.image.renderable.RenderableImage;
  71: 
  72: import java.text.AttributedCharacterIterator;
  73: import java.text.CharacterIterator;
  74: import java.util.Map;
  75: 
  76: /**
  77:  * QtGraphics is an abstract implementation of Graphics2D over a QPainter
  78:  * object. This is to be subclassed for different drawing contexts,
  79:  * which may have different requirements.
  80:  */
  81: public abstract class QtGraphics extends Graphics2D
  82: {
  83:   /**
  84:    * Native QPainter pointer.
  85:    */
  86:   protected long nativeObject;
  87: 
  88:   private static final AffineTransform identity = new AffineTransform();
  89: 
  90:   // Graphics state
  91:   protected Font font;              // Current font.
  92:   protected Color color, bgcolor;   // Current color and background color.
  93:   protected Shape clip;             // Current clipping area.
  94:   protected Shape initialClip;      // Initial clip bounds
  95:   protected AffineTransform xform;  // Current transform
  96:   protected Stroke currentStroke;   // the current stroke
  97:   protected boolean nativeStroking; // whether we're using Qt's stroking or not
  98:   protected Composite composite; // current composite operator
  99:   protected double currentAlpha; // current alpha
 100:   protected Paint currentPaint;  // current paint
 101:   protected RenderingHints renderingHints; // the rendering hints.
 102: 
 103:   /**
 104:    * Owner Graphics, used by subcontext created by create()
 105:    * to avoid GC of the original context.
 106:    */
 107:   Graphics parent;
 108: 
 109:   /**
 110:    * Do-nothing constructor.
 111:    */
 112:   QtGraphics()
 113:   {
 114:   }
 115: 
 116:   /**
 117:    * Copying constructor - used by copy() and subclasses.
 118:    */
 119:   QtGraphics(QtGraphics parent)
 120:   {
 121:     cloneNativeContext( parent );
 122:     setFont( parent.getFont() );
 123:     setAlpha( parent.currentAlpha );
 124:     setBackground( parent.getBackground() );
 125:     setColor( parent.getColor() );
 126:     setClip( (initialClip = parent.getClip()) );
 127:     setTransform( parent.getTransform() );
 128:     setStroke( parent.getStroke() );
 129:     setComposite( parent.getComposite() );
 130:     setPaint( parent.getPaint() );
 131:     setRenderingHints( parent.getRenderingHints() );
 132:   }
 133: 
 134:   /**
 135:    * Set up some generic defaults.
 136:    */
 137:   protected void setup()
 138:   {
 139:     font = new Font ("Dialog", Font.PLAIN, 12);
 140:     setTransform( identity );
 141:     setStroke( new BasicStroke() );
 142:     renderingHints = new RenderingHints( null );
 143:   }
 144: 
 145:   public synchronized native void delete();
 146: 
 147:   public void dispose()
 148:   {
 149:   }
 150: 
 151:   // ********************** etc *******************************
 152: 
 153:   private void resetClip()
 154:   {
 155:     AffineTransform current = getTransform();
 156:     setTransform( identity );
 157:     setClip( initialClip );
 158:     setTransform( current );
 159:   }
 160: 
 161:   protected native void initImage(QtImage image);
 162:   protected native void initVolatileImage(QtVolatileImage image);
 163: 
 164:   // Creates a new native QPainter object on the same context.
 165:   private native void cloneNativeContext( QtGraphics parent );
 166:   private native void setColor(int r, int g, int b, int a);
 167:   private native void drawNative( QPainterPath p );
 168:   private native void fillNative( QPainterPath p );
 169:   private native void setClipNative( QPainterPath p );
 170:   private native void setClipRectNative( int x, int y, int w, int h );
 171:   private native void intersectClipNative( QPainterPath p );
 172:   private native void intersectClipRectNative( int x, int y, int w, int h );
 173:   private native void setQtTransform(QMatrix m);
 174:   private native void setNativeStroke(QPen p);
 175:   private native void setNativeComposite(int alphaMode);
 176:   private native void drawStringNative(String string, double x, double y);
 177:   private native void setLinearGradient(int r1, int g1, int b1,
 178:                                         int r2, int g2, int b2,
 179:                                         double x1, double y1,
 180:                                         double x2, double y2, boolean cyclic);
 181:   private native void setAlphaNative(double alpha);
 182:   private native void setFontNative(QtFontPeer font);
 183:   private native QPainterPath getClipNative();
 184: 
 185:   void setAlpha(double alpha)
 186:   {
 187:     currentAlpha = alpha;
 188:     setAlphaNative(currentAlpha);
 189:   }
 190: 
 191:   // ************ Public methods *********************
 192: 
 193:   /**
 194:    * Context-sensitive methods are declared abstract.
 195:    */
 196:   public abstract Graphics create();
 197: 
 198:   public abstract void copyArea(int x, int y, int width, int height,
 199:                                 int dx, int dy);
 200: 
 201:   public abstract GraphicsConfiguration getDeviceConfiguration();
 202: 
 203: 
 204:   public Color getColor()
 205:   {
 206:     return new Color(color.getRed(), color.getGreen(), color.getBlue());
 207:   }
 208: 
 209:   public void setColor(Color c)
 210:   {
 211:     if( c == null )
 212:       c = Color.white;
 213:     this.color = c;
 214:     int alpha = (int)(c.getAlpha() * currentAlpha);
 215:     setColor(c.getRed(), c.getGreen(), c.getBlue(), alpha);
 216:   }
 217: 
 218:   public void setBackground(Color color)
 219:   {
 220:     bgcolor = new Color(color.getRed(), color.getGreen(), color.getBlue());
 221:   }
 222: 
 223:   public Color getBackground()
 224:   {
 225:     return new Color(bgcolor.getRed(), bgcolor.getGreen(), bgcolor.getBlue());
 226:   }
 227: 
 228:   public void setPaintMode()
 229:   {
 230:   }
 231: 
 232:   public void setXORMode(Color color)
 233:   {
 234:     // FIXME
 235:   }
 236: 
 237:   public boolean hit(Rectangle rect, Shape s, boolean onStroke)
 238:   {
 239:     if( onStroke )
 240:       {
 241:         Shape stroked = currentStroke.createStrokedShape( s );
 242:         return stroked.intersects( (double)rect.x, (double)rect.y,
 243:                                    (double)rect.width, (double)rect.height );
 244:       }
 245:     return s.intersects( (double)rect.x, (double)rect.y,
 246:                          (double)rect.width, (double)rect.height );
 247:   }
 248: 
 249:   // ******************* Font ***********************
 250:   public Font getFont()
 251:   {
 252:     return font;
 253:   }
 254: 
 255:   public void setFont(Font font)
 256:   {
 257:     if( font == null )
 258:       return;
 259:     this.font = font;
 260:     if(font.getPeer() != null && font.getPeer() instanceof QtFontPeer)
 261:       setFontNative( (QtFontPeer)font.getPeer() );
 262:   }
 263: 
 264:   public FontMetrics getFontMetrics(Font font)
 265:   {
 266:     return new QtFontMetrics(font, this);
 267:   }
 268: 
 269:   // ***************** Clipping *********************
 270: 
 271:   /**
 272:    * Intersects the current clip with the shape
 273:    */
 274:   public void clip(Shape s)
 275:   {
 276:     intersectClipNative( new QPainterPath( s ) );
 277:   }
 278: 
 279:   public void clipRect(int x, int y, int width, int height)
 280:   {
 281:     intersectClipRectNative( x, y, width, height );
 282:   }
 283: 
 284:   public void setClip(int x, int y, int width, int height)
 285:   {
 286:     setClipRectNative( x, y, width, height );
 287:   }
 288: 
 289:   public Shape getClip()
 290:   {
 291:     return getClipNative().getPath();
 292:   }
 293: 
 294:   public native Rectangle getClipBounds();
 295: 
 296:   /**
 297:    * Sets the clip
 298:    */
 299:   public void setClip(Shape clip)
 300:   {
 301:     if (clip == null)
 302:       resetClip();
 303:     else
 304:       setClipNative(new QPainterPath( clip ));
 305:   }
 306: 
 307:   // ***************** Drawing primitives *********************
 308: 
 309:   public void draw(Shape s)
 310:   {
 311:     if( nativeStroking )
 312:       drawNative( new QPainterPath(s) );
 313:     else
 314:       fillNative( new QPainterPath( currentStroke.createStrokedShape( s ) ) );
 315:   }
 316: 
 317:   public void fill(Shape s)
 318:   {
 319:     fillNative( new QPainterPath(s) );
 320:   }
 321: 
 322:   public void drawLine(int x1, int y1, int x2, int y2)
 323:   {
 324:     if( nativeStroking )
 325:       drawNative( new QPainterPath((double)x1, (double)y1, (double)x2, (double)y2, true) );
 326:     else
 327:       draw( new Line2D.Double((double)x1, (double)y1, (double)x2, (double)y2) );
 328:   }
 329: 
 330:   public void drawRect(int x, int y, int width, int height)
 331:   {
 332:     if( nativeStroking )
 333:       drawNative( new QPainterPath((double)x, (double)y,
 334:                                    (double)width, (double)height) );
 335:     else
 336:       fillNative( new QPainterPath
 337:                   ( currentStroke.createStrokedShape
 338:                     (new Rectangle2D.Double
 339:                      ((double)x, (double)y,
 340:                       (double)width, (double)height) ) ) );
 341:   }
 342: 
 343:   public void fillRect(int x, int y, int width, int height)
 344:   {
 345:     fillNative( new QPainterPath( x, y, width, height ) );
 346:   }
 347: 
 348:   public void clearRect(int x, int y, int width, int height)
 349:   {
 350:     Color c = color;
 351:     setColor( bgcolor ); // FIXME
 352:     fillRect( x, y, width, height );
 353:     setColor( c );
 354:   }
 355: 
 356:   public void drawRoundRect(int x, int y, int width, int height,
 357:                             int arcWidth, int arcHeight)
 358:   {
 359:     draw( new RoundRectangle2D.Double(x, y, width, height,
 360:                                       arcWidth, arcHeight) );
 361:   }
 362: 
 363:   public void fillRoundRect(int x, int y, int width, int height,
 364:                             int arcWidth, int arcHeight)
 365:   {
 366:     fill( new RoundRectangle2D.Double(x, y, width, height,
 367:                                       arcWidth, arcHeight) );
 368:   }
 369: 
 370:   public void drawOval(int x, int y, int width, int height)
 371:   {
 372:     draw( new Ellipse2D.Double((double)x, (double)y,
 373:                                (double)width, (double)height) );
 374:   }
 375: 
 376:   public void fillOval(int x, int y, int width, int height)
 377:   {
 378:     fill( new Ellipse2D.Double(x, y, width, height) );
 379:   }
 380: 
 381:   public void drawArc(int x, int y, int width, int height,
 382:                       int arcStart, int arcAngle)
 383:   {
 384:     draw( new Arc2D.Double(x, y, width, height, arcStart, arcAngle,
 385:                            Arc2D.OPEN) );
 386:   }
 387: 
 388:   public void fillArc(int x, int y, int width, int height,
 389:                       int arcStart, int arcAngle)
 390:   {
 391:     fill( new Arc2D.Double(x, y, width, height, arcStart, arcAngle,
 392:                            Arc2D.CHORD) );
 393:   }
 394: 
 395:   public void drawPolyline(int xPoints[], int yPoints[], int npoints)
 396:   {
 397:     for( int i = 0; i < npoints - 1; i++)
 398:       drawLine(xPoints[i], yPoints[i], xPoints[i + 1], yPoints[i + 1]);
 399:   }
 400: 
 401:   public void drawPolygon(int xPoints[], int yPoints[], int npoints)
 402:   {
 403:     draw( new Polygon(xPoints, yPoints, npoints) );
 404:   }
 405: 
 406:   public void fillPolygon(int xPoints[], int yPoints[], int npoints)
 407:   {
 408:     fill( new Polygon(xPoints, yPoints, npoints) );
 409:   }
 410: 
 411:   public native void fill3DRect(int x, int y, int width, int height, boolean raised);
 412: 
 413:   public native void draw3DRect(int x, int y, int width, int height, boolean raised);
 414: 
 415:   // *********************** Text rendering *************************
 416: 
 417:   public void drawString(String string, int x, int y)
 418:   {
 419:     drawStringNative(string, (double)x, (double)y);
 420:   }
 421: 
 422:   public void drawString(String string, float x, float y)
 423:   {
 424:     drawStringNative(string, (double)x, (double)y);
 425:   }
 426: 
 427:   public void drawString (AttributedCharacterIterator ci, int x, int y)
 428:   {
 429:     // FIXME - to something more correct ?
 430:     String s = "";
 431:     for(char c = ci.first(); c != CharacterIterator.DONE; c = ci.next())
 432:       s += c;
 433:     drawString(s, x, y);
 434:   }
 435: 
 436:   public void drawString(AttributedCharacterIterator ci,
 437:                          float x, float y)
 438:   {
 439:     // FIXME - to something more correct ?
 440:     String s = "";
 441:     for(char c = ci.first(); c != CharacterIterator.DONE; c = ci.next())
 442:       s += c;
 443:     drawString(s, x, y);
 444:   }
 445: 
 446:   public void drawGlyphVector(GlyphVector v, float x, float y)
 447:   {
 448:     throw new RuntimeException("Not implemented");
 449:   }
 450: 
 451:   // ******************* Image drawing ******************************
 452:   public boolean drawImage(Image image,
 453:                            AffineTransform Tx,
 454:                            ImageObserver obs)
 455:   {
 456:     if (image instanceof QtImage)
 457:       return ((QtImage)image).drawImage(this, new QMatrix( Tx ), obs);
 458: 
 459:     return (new QtImage(image.getSource())).drawImage(this,
 460:                                                       new QMatrix( Tx ),
 461:                                                       obs);
 462:   }
 463: 
 464:   public boolean drawImage(Image image, int x, int y, Color bgcolor,
 465:                            ImageObserver observer)
 466:   {
 467:     if (image instanceof QtImage)
 468:       return ((QtImage)image).drawImage (this, x, y, bgcolor, observer);
 469:     return (new QtImage(image.getSource())).drawImage (this, x, y,
 470:                                                        bgcolor, observer);
 471:   }
 472: 
 473:   public boolean drawImage(Image image,
 474:                            int dx1, int dy1, int dx2, int dy2,
 475:                            int sx1, int sy1, int sx2, int sy2,
 476:                            Color bgcolor, ImageObserver observer)
 477:   {
 478:     if (image instanceof QtImage)
 479:       return ((QtImage)image).drawImage(this, dx1, dy1, dx2, dy2,
 480:                                         sx1, sy1, sx2, sy2, bgcolor, observer);
 481: 
 482:     return (new QtImage(image.getSource())).drawImage(this, dx1, dy1,
 483:                                                       dx2, dy2,
 484:                                                       sx1, sy1, sx2, sy2,
 485:                                                       bgcolor, observer);
 486:   }
 487: 
 488:   public boolean drawImage(Image image, int x, int y,
 489:                            int width, int height, Color bgcolor,
 490:                            ImageObserver observer)
 491:   {
 492:     if (image instanceof QtImage)
 493:       return ((QtImage)image).drawImage (this, x, y, width, height,
 494:                                          bgcolor, observer);
 495:     return (new QtImage(image.getSource())).drawImage (this, x, y,
 496:                                                        width, height,
 497:                                                        bgcolor, observer);
 498:   }
 499: 
 500:   public boolean drawImage(Image image, int x, int y, int width, int height,
 501:                            ImageObserver observer)
 502:   {
 503:     return drawImage(image, x, y, width, height, null, observer);
 504:   }
 505: 
 506:   public boolean drawImage(Image image, int x, int y, ImageObserver observer)
 507:   {
 508:     return drawImage(image, x, y, null, observer);
 509:   }
 510: 
 511:   public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer)
 512:   {
 513:     return drawImage(image, dx1, dy1, dx2, dy2,
 514:                      sx1, sy1, sx2, sy2, null, observer);
 515:   }
 516: 
 517:   // *********************** Transform methods *************************
 518:   public AffineTransform getTransform()
 519:   {
 520:     return new AffineTransform( xform );
 521:   }
 522: 
 523:   public void setTransform(AffineTransform Tx)
 524:   {
 525:     xform = new AffineTransform( Tx );
 526:     setQtTransform( new QMatrix( xform ) );
 527:   }
 528: 
 529:   public void rotate(double theta)
 530:   {
 531:     xform.rotate( theta );
 532:     setQtTransform( new QMatrix( xform ) );
 533:   }
 534: 
 535:   public void rotate(double theta, double x, double y)
 536:   {
 537:     xform.rotate(theta, x, y);
 538:     setQtTransform( new QMatrix( xform ) );
 539:   }
 540: 
 541:   public void scale(double sx, double sy)
 542:   {
 543:     xform.scale(sx, sy);
 544:     setQtTransform( new QMatrix( xform ) );
 545:   }
 546: 
 547:   public void shear(double shx, double shy)
 548:   {
 549:     xform.shear(shx, shy);
 550:     setQtTransform( new QMatrix( xform ) );
 551:   }
 552: 
 553:   public void transform(AffineTransform Tx)
 554:   {
 555:     xform.concatenate( Tx );
 556:     setQtTransform( new QMatrix( xform ) );
 557:   }
 558: 
 559:   public void translate(double tx, double ty)
 560:   {
 561:     xform.translate( tx, ty );
 562:     setQtTransform( new QMatrix( xform ) );
 563:   }
 564: 
 565:   public void translate(int x, int y)
 566:   {
 567:     translate((double)x, (double)y);
 568:   }
 569: 
 570:   // *************** Stroking, Filling, Compositing *****************
 571:   public void setStroke(Stroke s)
 572:   {
 573:     try  // ..to convert the stroke into a native one.
 574:       {
 575:         QPen pen = new QPen( s );
 576:         nativeStroking = true;
 577:         setNativeStroke( pen );
 578:         setColor( color );
 579:       }
 580:     catch (IllegalArgumentException e)
 581:       {
 582:         nativeStroking = false;
 583:       }
 584:     currentStroke = s;
 585:   }
 586: 
 587:   public Stroke getStroke()
 588:   { // FIXME: return copy?
 589:     return currentStroke;
 590:   }
 591: 
 592:   public void setComposite(Composite comp)
 593:   {
 594:     if( comp == null)
 595:       {
 596:         setNativeComposite( AlphaComposite.SRC_OVER );
 597:         return;
 598:       }
 599: 
 600:     if( comp instanceof AlphaComposite )
 601:       {
 602:         if( ((AlphaComposite)comp).getRule() != AlphaComposite.XOR )
 603:           setAlpha( ((AlphaComposite)comp).getAlpha() );
 604:         setNativeComposite( ((AlphaComposite)comp).getRule() );
 605:         composite = comp;
 606:       }
 607:     else
 608:       {
 609:         // FIXME: this check is only required "if this Graphics2D
 610:         // context is drawing to a Component on the display screen".
 611:         SecurityManager sm = System.getSecurityManager();
 612:         if (sm != null)
 613:           sm.checkPermission(new AWTPermission("readDisplayPixels"));
 614: 
 615:         throw new UnsupportedOperationException("We don't support custom"+
 616:                                                 " composites yet.");
 617:       }
 618:   }
 619: 
 620:   public Composite getComposite()
 621:   {
 622:     return composite;
 623:   }
 624: 
 625:   public void setPaint(Paint p)
 626:   {
 627:     if( p == null )
 628:       return;
 629: 
 630:     // FIXME
 631:     currentPaint = p;
 632:     if( p instanceof GradientPaint )
 633:       {
 634:         GradientPaint lg = (GradientPaint)p;
 635:         setLinearGradient(lg.getColor1().getRed(), lg.getColor1().getGreen(),
 636:                           lg.getColor1().getBlue(), lg.getColor2().getRed(),
 637:                           lg.getColor2().getGreen(), lg.getColor2().getBlue(),
 638:                           lg.getPoint1().getX(), lg.getPoint1().getY(),
 639:                           lg.getPoint2().getX(), lg.getPoint2().getY(),
 640:                           lg.isCyclic() );
 641:         return;
 642:       }
 643:     if( p instanceof Color )
 644:       {
 645:         setColor((Color) p);
 646:         return;
 647:       }
 648:     throw new UnsupportedOperationException("We don't support custom"+
 649:                                             " paints yet.");
 650:   }
 651: 
 652:   public Paint getPaint()
 653:   {
 654:     // FIXME
 655:     return currentPaint;
 656:   }
 657: 
 658:   // ********************** Rendering Hints *************************
 659: 
 660:   public void addRenderingHints(Map hints)
 661:   {
 662:     renderingHints.putAll( hints );
 663:   }
 664: 
 665:   public Object getRenderingHint(RenderingHints.Key hintKey)
 666:   {
 667:     return renderingHints.get( hintKey );
 668:   }
 669: 
 670:   public RenderingHints getRenderingHints()
 671:   {
 672:     return (RenderingHints) renderingHints.clone();
 673:   }
 674: 
 675:   public void setRenderingHints(Map<?,?> hints)
 676:   {
 677:     renderingHints = new RenderingHints( null );
 678:     renderingHints.putAll(hints);
 679:     updateRenderingHints();
 680:   }
 681: 
 682:   public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue)
 683:   {
 684:     renderingHints.put( hintKey, hintValue );
 685:     updateRenderingHints();
 686:   }
 687: 
 688:   private void updateRenderingHints()
 689:   {
 690:     // FIXME - update native settings.
 691:   }
 692: 
 693:   ////////////////////////////// unimplemented /////////////////////
 694: 
 695:   public FontRenderContext getFontRenderContext()
 696:   {
 697:     throw new UnsupportedOperationException("Not implemented yet");
 698:   }
 699: 
 700:   public void drawRenderableImage(RenderableImage image, AffineTransform xform)
 701:   {
 702:     throw new UnsupportedOperationException("Not implemented yet");
 703:   }
 704: 
 705:   public void drawRenderedImage(RenderedImage image, AffineTransform xform)
 706:   {
 707:     throw new UnsupportedOperationException("Not implemented yet");
 708:   }
 709: 
 710:   public void drawImage(BufferedImage image, BufferedImageOp op, int x, int y)
 711:   {
 712:     throw new UnsupportedOperationException("Not implemented yet");
 713:   }
 714: }