001    /* DebugGraphics.java --
002       Copyright (C) 2002, 2004, 2005  Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    package javax.swing;
039    
040    import java.awt.Color;
041    import java.awt.Font;
042    import java.awt.FontMetrics;
043    import java.awt.Graphics;
044    import java.awt.Image;
045    import java.awt.Point;
046    import java.awt.Rectangle;
047    import java.awt.Shape;
048    import java.awt.image.ImageObserver;
049    import java.io.PrintStream;
050    import java.text.AttributedCharacterIterator;
051    
052    
053    /**
054     * An extension of {@link Graphics} that can be used for debugging
055     * custom Swing widgets. <code>DebugGraphics</code> has the ability to
056     * draw slowly and can log drawing actions.
057     *
058     * @author Andrew Selkirk
059     */
060    public class DebugGraphics extends Graphics
061    {
062      /**
063       * LOG_OPTION
064       */
065      public static final int LOG_OPTION = 1;
066    
067      /**
068       * FLASH_OPTION
069       */
070      public static final int FLASH_OPTION = 2;
071    
072      /**
073       * BUFFERED_OPTION
074       */
075      public static final int BUFFERED_OPTION = 4;
076    
077      /**
078       * NONE_OPTION
079       */
080      public static final int NONE_OPTION = -1;
081    
082      static Color debugFlashColor = Color.RED;
083      static int debugFlashCount = 10;
084      static int debugFlashTime = 1000;
085      static PrintStream debugLogStream = System.out;
086    
087      /**
088       * Counts the created DebugGraphics objects. This is used by the
089       * logging facility.
090       */
091      static int counter = 0;
092    
093      /**
094       * graphics
095       */
096      Graphics graphics;
097    
098      /**
099       * buffer
100       */
101      Image buffer;
102    
103      /**
104       * debugOptions
105       */
106      int debugOptions;
107    
108      /**
109       * graphicsID
110       */
111      int graphicsID;
112    
113      /**
114       * xOffset
115       */
116      int xOffset;
117    
118      /**
119       * yOffset
120       */
121      int yOffset;
122    
123      /**
124       * Creates a <code>DebugGraphics</code> object.
125       */
126      public DebugGraphics()
127      {
128        counter++;
129      }
130    
131      /**
132       * Creates a <code>DebugGraphics</code> object.
133       *
134       * @param graphics The <code>Graphics</code> object to wrap
135       * @param component TODO
136       */
137      public DebugGraphics(Graphics graphics, JComponent component)
138      {
139        this(graphics);
140        // FIXME: What shall we do with component ?
141      }
142    
143      /**
144       * Creates a <code>DebugGraphics</code> object.
145       *
146       * @param graphics The <code>Graphics</code> object to wrap
147       */
148      public DebugGraphics(Graphics graphics)
149      {
150        this();
151        this.graphics = graphics;
152      }
153    
154      /**
155       * Sets the color to draw stuff with.
156       *
157       * @param color The color
158       */
159      public void setColor(Color color)
160      {
161        if ((debugOptions & LOG_OPTION) != 0)
162          logStream().println(prefix() + " Setting color: " + color);
163    
164        graphics.setColor(color);
165      }
166    
167      /**
168       * Creates a overrides <code>Graphics.create</code> to create a
169       * <code>DebugGraphics</code> object.
170       *
171       * @return a new <code>DebugGraphics</code> object.
172       */
173      public Graphics create()
174      {
175        DebugGraphics copy = new DebugGraphics(graphics.create());
176        copy.debugOptions = debugOptions;
177        return copy;
178      }
179    
180      /**
181       * Creates a overrides <code>Graphics.create</code> to create a
182       * <code>DebugGraphics</code> object.
183       *
184       * @param x the x coordinate
185       * @param y the y coordinate
186       * @param width the width
187       * @param height the height
188       *
189       * @return a new <code>DebugGraphics</code> object.
190       */
191      public Graphics create(int x, int y, int width, int height)
192      {
193        DebugGraphics copy = new DebugGraphics(graphics.create(x, y, width,
194                                                               height));
195        copy.debugOptions = debugOptions;
196        return copy;
197      }
198    
199      /**
200       * flashColor
201       *
202       * @return Color
203       */
204      public static Color flashColor()
205      {
206        return debugFlashColor;
207      }
208    
209      /**
210       * setFlashColor
211       *
212       * @param color the color to use for flashing
213       */
214      public static void setFlashColor(Color color)
215      {
216        debugFlashColor = color;
217      }
218    
219      /**
220       * flashTime
221       *
222       * @return The time in milliseconds
223       */
224      public static int flashTime()
225      {
226        return debugFlashTime;
227      }
228    
229      /**
230       * setFlashTime
231       *
232       * @param time The time in milliseconds
233       */
234      public static void setFlashTime(int time)
235      {
236        debugFlashTime = time;
237      }
238    
239      /**
240       * flashCount
241       *
242       * @return The number of flashes
243       */
244      public static int flashCount()
245      {
246        return debugFlashCount;
247      }
248    
249      /**
250       * setFlashCount
251       *
252       * @param count The number of flashes
253       */
254      public static void setFlashCount(int count)
255      {
256        debugFlashCount = count;
257      }
258    
259      /**
260       * logStream
261       *
262       * @return The <code>PrintStream</code> to write logging messages to
263       */
264      public static PrintStream logStream()
265      {
266        return debugLogStream;
267      }
268    
269      /**
270       * setLogStream
271       *
272       * @param stream The currently set <code>PrintStream</code>.
273       */
274      public static void setLogStream(PrintStream stream)
275      {
276        debugLogStream = stream;
277      }
278    
279      /**
280       * getFont
281       *
282       * @return The font
283       */
284      public Font getFont()
285      {
286        return graphics.getFont();
287      }
288    
289      /**
290       * setFont
291       *
292       * @param font The font to use for drawing text
293       */
294      public void setFont(Font font)
295      {
296        if ((debugOptions & LOG_OPTION) != 0)
297          logStream().println(prefix() + " Setting font: " + font);
298    
299        graphics.setFont(font);
300      }
301    
302      /**
303       * Returns the color used for drawing.
304       *
305       * @return The color.
306       */
307      public Color getColor()
308      {
309        return graphics.getColor();
310      }
311    
312      /**
313       * Returns the font metrics of the current font.
314       *
315       * @return a <code>FontMetrics</code> object
316       */
317      public FontMetrics getFontMetrics()
318      {
319        return graphics.getFontMetrics();
320      }
321    
322      /**
323       * Returns the font metrics for a given font.
324       *
325       * @param font the font to get the metrics for
326       *
327       * @return a <code>FontMetrics</code> object
328       */
329      public FontMetrics getFontMetrics(Font font)
330      {
331        return graphics.getFontMetrics(font);
332      }
333    
334      /**
335       * translate
336       *
337       * @param x the x coordinate
338       * @param y the y coordinate
339       */
340      public void translate(int x, int y)
341      {
342        if ((debugOptions & LOG_OPTION) != 0)
343          logStream().println(prefix() + " Translating by: " + new Point(x, y));
344    
345        graphics.translate(x, y);
346      }
347    
348      /**
349       * setPaintMode
350       */
351      public void setPaintMode()
352      {
353        if ((debugOptions & LOG_OPTION) != 0)
354          logStream().println(prefix() + " Setting paint mode");
355    
356        graphics.setPaintMode();
357      }
358    
359      /**
360       * setXORMode
361       *
362       * @param color the color
363       */
364      public void setXORMode(Color color)
365      {
366        if ((debugOptions & LOG_OPTION) != 0)
367          logStream().println(prefix() + " Setting XOR mode: " + color);
368    
369        graphics.setXORMode(color);
370      }
371    
372      /**
373       * getClipBounds
374       *
375       * @return Rectangle
376       */
377      public Rectangle getClipBounds()
378      {
379        return graphics.getClipBounds();
380      }
381    
382      /**
383       * Intersects the current clip region with the given region.
384       *
385       * @param x The x-position of the region
386       * @param y The y-position of the region
387       * @param width The width of the region
388       * @param height The height of the region
389       */
390      public void clipRect(int x, int y, int width, int height)
391      {
392        if ((debugOptions & LOG_OPTION) != 0)
393          {
394            logStream().print(prefix() + " Setting clipRect: "
395                              + new Rectangle(x, y, width, height));
396          }
397    
398        graphics.clipRect(x, y, width, height);
399    
400        if ((debugOptions & LOG_OPTION) != 0)
401          logStream().println(" Netting clipRect: " + graphics.getClipBounds());
402      }
403    
404      /**
405       * Sets the clipping region.
406       *
407       * @param x The x-position of the region
408       * @param y The y-position of the region
409       * @param width The width of the region
410       * @param height The height of the region
411       */
412      public void setClip(int x, int y, int width, int height)
413      {
414        if ((debugOptions & LOG_OPTION) != 0)
415          {
416            logStream().println(prefix() + " Setting new clipRect: "
417                                + new Rectangle(x, y, width, height));
418          }
419    
420        graphics.setClip(x, y, width, height);
421      }
422    
423      /**
424       * Returns the current clipping region.
425       *
426       * @return Shape
427       */
428      public Shape getClip()
429      {
430        return graphics.getClip();
431      }
432    
433      /**
434       * Sets the current clipping region
435       *
436       * @param shape The clippin region
437       */
438      public void setClip(Shape shape)
439      {
440        if ((debugOptions & LOG_OPTION) != 0)
441          logStream().println(prefix() + " Setting new clipRect: " + shape);
442    
443        graphics.setClip(shape);
444      }
445    
446      private void sleep(int milliseconds)
447      {
448        try
449          {
450            Thread.sleep(milliseconds);
451          }
452        catch (InterruptedException e)
453          {
454            // Ignore this.
455          }
456      }
457    
458      /**
459       * Draws a rectangle.
460       *
461       * @param x The x-position of the rectangle
462       * @param y The y-position of the rectangle
463       * @param width The width of the rectangle
464       * @param height The height of the rectangle
465       */
466      public void drawRect(int x, int y, int width, int height)
467      {
468        if ((debugOptions & LOG_OPTION) != 0)
469          {
470            logStream().println(prefix() + " Drawing rect: "
471                                + new Rectangle(x, y, width, height));
472          }
473    
474        if ((debugOptions & FLASH_OPTION) != 0)
475          {
476            Color color = graphics.getColor();
477            for (int index = 0; index < (debugFlashCount - 1); ++index)
478              {
479                graphics.setColor(color);
480                graphics.drawRect(x, y, width, height);
481                sleep(debugFlashTime);
482                graphics.setColor(debugFlashColor);
483                graphics.drawRect(x, y, width, height);
484                sleep(debugFlashTime);
485              }
486            graphics.setColor(color);
487          }
488    
489        graphics.drawRect(x, y, width, height);
490      }
491    
492      /**
493       * Draws a filled rectangle.
494       *
495       * @param x The x-position of the rectangle
496       * @param y The y-position of the rectangle
497       * @param width The width of the rectangle
498       * @param height The height of the rectangle
499       */
500      public void fillRect(int x, int y, int width, int height)
501      {
502        if ((debugOptions & LOG_OPTION) != 0)
503          {
504            logStream().println(prefix() + " Filling rect: "
505                                + new Rectangle(x, y, width, height));
506          }
507    
508        if ((debugOptions & FLASH_OPTION) != 0)
509          {
510            Color color = graphics.getColor();
511            for (int index = 0; index < (debugFlashCount - 1); ++index)
512              {
513                graphics.setColor(color);
514                graphics.fillRect(x, y, width, height);
515                sleep(debugFlashTime);
516                graphics.setColor(debugFlashColor);
517                graphics.fillRect(x, y, width, height);
518                sleep(debugFlashTime);
519              }
520            graphics.setColor(color);
521          }
522    
523        graphics.fillRect(x, y, width, height);
524      }
525    
526      /**
527       * clearRect
528       *
529       * @param x The x-position of the rectangle
530       * @param y The y-position of the rectangle
531       * @param width The width of the rectangle
532       * @param height The height of the rectangle
533       */
534      public void clearRect(int x, int y, int width, int height)
535      {
536        if ((debugOptions & LOG_OPTION) != 0)
537          {
538            logStream().println(prefix() + " Clearing rect: "
539                                + new Rectangle(x, y, width, height));
540          }
541    
542        graphics.clearRect(x, y, width, height);
543      }
544    
545      /**
546       * drawRoundRect
547       *
548       * @param x The x-position of the rectangle
549       * @param y The y-position of the rectangle
550       * @param width The width of the rectangle
551       * @param height The height of the rectangle
552       * @param arcWidth TODO
553       * @param arcHeight TODO
554       */
555      public void drawRoundRect(int x, int y, int width, int height,
556                                int arcWidth, int arcHeight)
557      {
558        if ((debugOptions & LOG_OPTION) != 0)
559          {
560            logStream().println(prefix() + " Drawing round rect: "
561                                + new Rectangle(x, y, width, height)
562                                + " arcWidth: " + arcWidth
563                                + " arcHeight: " + arcHeight);
564          }
565    
566        graphics.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
567      }
568    
569      /**
570       * fillRoundRect
571       *
572       * @param x The x-position of the rectangle
573       * @param y The y-position of the rectangle
574       * @param width The width of the rectangle
575       * @param height The height of the rectangle
576       * @param arcWidth TODO
577       * @param arcHeight TODO
578       */
579      public void fillRoundRect(int x, int y, int width, int height,
580                                int arcWidth, int arcHeight)
581      {
582        if ((debugOptions & LOG_OPTION) != 0)
583          {
584            logStream().println(prefix() + " Filling round rect: "
585                                + new Rectangle(x, y, width, height)
586                                + " arcWidth: " + arcWidth
587                                + " arcHeight: " + arcHeight);
588          }
589    
590        graphics.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
591      }
592    
593      /**
594       * drawLine
595       *
596       * @param x1 The x-position of the start
597       * @param y1 The y-position of the start
598       * @param x2 The x-position of the end
599       * @param y2 The y-position of the end
600       */
601      public void drawLine(int x1, int y1, int x2, int y2)
602      {
603        if ((debugOptions & LOG_OPTION) != 0)
604          {
605            logStream().println(prefix() + " Drawing line: from (" + x1 + ", "
606                                + y1 + ") to (" + x2 + ", " + y2 + ")");
607          }
608    
609        graphics.drawLine(x1, y1, x2, y2);
610      }
611    
612      /**
613       * draw3DRect
614       *
615       * @param x The x-position of the rectangle
616       * @param y The y-position of the rectangle
617       * @param width The width of the rectangle
618       * @param height The height of the rectangle
619       * @param raised TODO
620       */
621      public void draw3DRect(int x, int y, int width, int height, boolean raised)
622      {
623        if ((debugOptions & LOG_OPTION) != 0)
624          {
625            logStream().println(prefix() + " Drawing 3D rect: "
626                                + new Rectangle(x, y, width, height)
627                                + "Raised bezel: " + raised);
628          }
629    
630        graphics.draw3DRect(x, y, width, height, raised);
631      }
632    
633      /**
634       * fill3DRect
635       *
636       * @param x The x-position of the rectangle
637       * @param y The y-position of the rectangle
638       * @param width The width of the rectangle
639       * @param height The height of the rectangle
640       * @param raised TODO
641       */
642      public void fill3DRect(int x, int y, int width, int height, boolean raised)
643      {
644        if ((debugOptions & LOG_OPTION) != 0)
645          {
646            logStream().println(prefix() + " Filling 3D rect: "
647                                + new Rectangle(x, y, width, height)
648                                + "Raised bezel: " + raised);
649          }
650    
651        graphics.fill3DRect(x, y, width, height, raised);
652      }
653    
654      /**
655       * drawOval
656       *
657       * @param x the x coordinate
658       * @param y the y coordiante
659       * @param width the width
660       * @param height the height
661       */
662      public void drawOval(int x, int y, int width, int height)
663      {
664        if ((debugOptions & LOG_OPTION) != 0)
665          {
666            logStream().println(prefix() + " Drawing oval: "
667                                + new Rectangle(x, y, width, height));
668          }
669    
670        graphics.drawOval(x, y, width, height);
671      }
672    
673      /**
674       * fillOval
675       *
676       * @param x the x coordinate
677       * @param y the y coordinate
678       * @param width the width
679       * @param height the height
680       */
681      public void fillOval(int x, int y, int width, int height)
682      {
683        if ((debugOptions & LOG_OPTION) != 0)
684          {
685            logStream().println(prefix() + " Filling oval: "
686                                + new Rectangle(x, y, width, height));
687          }
688    
689        graphics.fillOval(x, y, width, height);
690      }
691    
692      /**
693       * drawArc
694       *
695       * @param x the x coordinate
696       * @param y the y coordinate
697       * @param width the width
698       * @param height the height
699       * @param startAngle TODO
700       * @param arcAngle TODO
701       */
702      public void drawArc(int x, int y, int width, int height,
703                          int startAngle, int arcAngle)
704      {
705        if ((debugOptions & LOG_OPTION) != 0)
706          {
707            logStream().println(prefix() + " Drawing arc: "
708                                + new Rectangle(x, y, width, height)
709                                + " startAngle: " + startAngle
710                                + " arcAngle: " + arcAngle);
711          }
712    
713        graphics.drawArc(x, y, width, height, startAngle, arcAngle);
714      }
715    
716      /**
717       * fillArc
718       *
719       * @param x the coordinate
720       * @param y the y coordinate
721       * @param width the width
722       * @param height the height
723       * @param startAngle TODO
724       * @param arcAngle TODO
725       */
726      public void fillArc(int x, int y, int width, int height,
727                          int startAngle, int arcAngle)
728      {
729        if ((debugOptions & LOG_OPTION) != 0)
730          {
731            logStream().println(prefix() + " Filling arc: "
732                                + new Rectangle(x, y, width, height)
733                                + " startAngle: " + startAngle
734                                + " arcAngle: " + arcAngle);
735          }
736    
737        graphics.fillArc(x, y, width, height, startAngle, arcAngle);
738      }
739    
740      /**
741       * drawPolyline
742       *
743       * @param xpoints TODO
744       * @param ypoints TODO
745       * @param npoints TODO
746       */
747      public void drawPolyline(int[] xpoints, int[] ypoints, int npoints)
748      {
749        if ((debugOptions & LOG_OPTION) != 0)
750          {
751            logStream().println(prefix() + " Drawing polyline: nPoints: " + npoints
752                                + " X's: " + xpoints + " Y's: " + ypoints);
753          }
754    
755        graphics.drawPolyline(xpoints, ypoints, npoints);
756      }
757    
758      /**
759       * drawPolygon
760       *
761       * @param xpoints TODO
762       * @param ypoints TODO
763       * @param npoints TODO
764       */
765      public void drawPolygon(int[] xpoints, int[] ypoints, int npoints)
766      {
767        if ((debugOptions & LOG_OPTION) != 0)
768          {
769            logStream().println(prefix() + " Drawing polygon: nPoints: " + npoints
770                                + " X's: " + xpoints + " Y's: " + ypoints);
771          }
772    
773        graphics.drawPolygon(xpoints, ypoints, npoints);
774      }
775    
776      /**
777       * fillPolygon
778       *
779       * @param xpoints TODO
780       * @param ypoints TODO
781       * @param npoints TODO
782       */
783      public void fillPolygon(int[] xpoints, int[] ypoints, int npoints)
784      {
785        if ((debugOptions & LOG_OPTION) != 0)
786          {
787            logStream().println(prefix() + " Drawing polygon: nPoints: " + npoints
788                                + " X's: " + xpoints + " Y's: " + ypoints);
789          }
790    
791        graphics.fillPolygon(xpoints, ypoints, npoints);
792      }
793    
794      /**
795       * drawString
796       *
797       * @param string the string
798       * @param x the x coordinate
799       * @param y the y coordinate
800       */
801      public void drawString(String string, int x, int y)
802      {
803        if ((debugOptions & LOG_OPTION) != 0)
804          {
805            logStream().println(prefix() + " Drawing string: \"" + string
806                                + "\" at: " + new Point(x, y));
807          }
808    
809        graphics.drawString(string, x, y);
810      }
811    
812      /**
813       * drawString
814       *
815       * @param iterator TODO
816       * @param x the x coordinate
817       * @param y the y coordinate
818       */
819      public void drawString(AttributedCharacterIterator iterator,
820                             int x, int y)
821      {
822        if ((debugOptions & LOG_OPTION) != 0)
823          {
824            logStream().println(prefix() + " Drawing string: \"" + iterator
825                                + "\" at: " + new Point(x, y));
826          }
827    
828        graphics.drawString(iterator, x, y);
829      }
830    
831      /**
832       * drawBytes
833       *
834       * @param data TODO
835       * @param offset TODO
836       * @param length TODO
837       * @param x the x coordinate
838       * @param y the y coordinate
839       */
840      public void drawBytes(byte[] data, int offset, int length,
841                            int x, int y)
842      {
843        if ((debugOptions & LOG_OPTION) != 0)
844          logStream().println(prefix() + " Drawing bytes at: " + new Point(x, y));
845    
846        graphics.drawBytes(data, offset, length, x, y);
847      }
848    
849      /**
850       * drawChars
851       *
852       * @param data array of characters to draw
853       * @param offset offset in array
854       * @param length number of characters in array to draw
855       * @param x x-position
856       * @param y y-position
857       */
858      public void drawChars(char[] data, int offset, int length,
859                            int x, int y)
860      {
861        if ((debugOptions & LOG_OPTION) != 0)
862          logStream().println(prefix() + " Drawing chars at: " + new Point(x, y));
863    
864        if ((debugOptions & FLASH_OPTION) != 0)
865          {
866            Color color = graphics.getColor();
867            for (int index = 0; index < (debugFlashCount - 1); ++index)
868              {
869                graphics.setColor(color);
870                graphics.drawChars(data, offset, length, x, y);
871                sleep(debugFlashTime);
872                graphics.setColor(debugFlashColor);
873                graphics.drawChars(data, offset, length, x, y);
874                sleep(debugFlashTime);
875              }
876            graphics.setColor(color);
877          }
878    
879        graphics.drawChars(data, offset, length, x, y);
880      }
881    
882      /**
883       * drawImage
884       *
885       * @param image The image to draw
886       * @param x The x position
887       * @param y The y position
888       * @param observer The image observer
889       * @return boolean
890       */
891      public boolean drawImage(Image image, int x, int y,
892                               ImageObserver observer)
893      {
894        if ((debugOptions & LOG_OPTION) != 0)
895          {
896            logStream().println(prefix() + " Drawing image: " + image + " at: "
897                              + new Point(x, y));
898          }
899    
900        return graphics.drawImage(image, x, y, observer);
901      }
902    
903      /**
904       * drawImage
905       *
906       * @param image The image to draw
907       * @param x The x position
908       * @param y The y position
909       * @param width The width of the area to draw the image
910       * @param height The height of the area to draw the image
911       * @param observer The image observer
912       *
913       * @return boolean
914       */
915      public boolean drawImage(Image image, int x, int y, int width,
916                               int height, ImageObserver observer)
917      {
918        if ((debugOptions & LOG_OPTION) != 0)
919          {
920            logStream().println(prefix() + " Drawing image: " + image
921                                + " at: " + new Rectangle(x, y, width, height));
922          }
923    
924        return graphics.drawImage(image, x, y, width, height, observer);
925      }
926    
927      /**
928       * drawImage
929       *
930       * @param image The image to draw
931       * @param x The x position
932       * @param y The y position
933       * @param background The color for the background in the opaque regions
934       * of the image
935       * @param observer The image observer
936       *
937       * @return boolean
938       */
939      public boolean drawImage(Image image, int x, int y,
940                               Color background, ImageObserver observer)
941      {
942        if ((debugOptions & LOG_OPTION) != 0)
943          {
944            logStream().println(prefix() + " Drawing image: " + image
945                                + " at: " + new Point(x, y)
946                                + ", bgcolor: " + background);
947          }
948    
949        return graphics.drawImage(image, x, y, background, observer);
950      }
951    
952      /**
953       * drawImage
954       *
955       * @param image The image to draw
956       * @param x The x position
957       * @param y The y position
958       * @param width The width of the area to draw the image
959       * @param height The height of the area to draw the image
960       * @param background The color for the background in the opaque regions
961       * of the image
962       * @param observer The image observer
963       *
964       * @return boolean
965       */
966      public boolean drawImage(Image image, int x, int y, int width, int height,
967                               Color background, ImageObserver observer)
968      {
969        if ((debugOptions & LOG_OPTION) != 0)
970          {
971            logStream().println(prefix() + " Drawing image: " + image
972                                + " at: " + new Rectangle(x, y, width, height)
973                                + ", bgcolor: " + background);
974          }
975    
976        return graphics.drawImage(image, x, y, width, height, background, observer);
977      }
978    
979      /**
980       * drawImage
981       *
982       * @param image The image to draw
983       * @param dx1 TODO
984       * @param dy1 TODO
985       * @param dx2 TODO
986       * @param dy2 TODO
987       * @param sx1 TODO
988       * @param sy1 TODO
989       * @param sx2 TODO
990       * @param sy2 TODO
991       * @param observer The image observer
992       *
993       * @return boolean
994       */
995      public boolean drawImage(Image image, int dx1, int dy1,
996                               int dx2, int dy2, int sx1, int sy1, int sx2, int sy2,
997                               ImageObserver observer)
998      {
999        if ((debugOptions & LOG_OPTION) != 0)
1000          {
1001            logStream().println(prefix() + " Drawing image: " + image
1002                             + " destination: " + new Rectangle(dx1, dy1, dx2, dy2)
1003                             + " source: " + new Rectangle(sx1, sy1, sx2, sy2));
1004          }
1005    
1006        return graphics.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer);
1007      }
1008    
1009      /**
1010       * drawImage
1011       *
1012       * @param image The image to draw
1013       * @param dx1 TODO
1014       * @param dy1 TODO
1015       * @param dx2 TODO
1016       * @param dy2 TODO
1017       * @param sx1 TODO
1018       * @param sy1 TODO
1019       * @param sx2 TODO
1020       * @param sy2 TODO
1021       * @param background The color for the background in the opaque regions
1022       * of the image
1023       * @param observer The image observer
1024       *
1025       * @return boolean
1026       */
1027      public boolean drawImage(Image image, int dx1, int dy1,
1028                               int dx2, int dy2, int sx1, int sy1, int sx2, int sy2,
1029                               Color background, ImageObserver observer)
1030      {
1031        if ((debugOptions & LOG_OPTION) != 0)
1032          {
1033            logStream().println(prefix() + " Drawing image: " + image
1034                             + " destination: " + new Rectangle(dx1, dy1, dx2, dy2)
1035                             + " source: " + new Rectangle(sx1, sy1, sx2, sy2)
1036                             + ", bgcolor: " + background);
1037          }
1038    
1039        return graphics.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, background, observer);
1040      }
1041    
1042      /**
1043       * copyArea
1044       *
1045       * @param x The x position of the source area
1046       * @param y The y position of the source area
1047       * @param width The width of the area
1048       * @param height The height of the area
1049       * @param destx The x position of the destination area
1050       * @param desty The y posiiton of the destination area
1051       */
1052      public void copyArea(int x, int y, int width, int height,
1053                           int destx, int desty)
1054      {
1055        if ((debugOptions & LOG_OPTION) != 0)
1056          {
1057            logStream().println(prefix() + " Copying area from: "
1058                                +  new Rectangle(x, y, width, height)
1059                                + " to: " + new Point(destx, desty));
1060          }
1061    
1062        graphics.copyArea(x, y, width, height, destx, desty);
1063      }
1064    
1065      /**
1066       * Releases all system resources that this <code>Graphics</code> is using.
1067       */
1068      public void dispose()
1069      {
1070        graphics.dispose();
1071        graphics = null;
1072      }
1073    
1074      /**
1075       * isDrawingBuffer
1076       *
1077       * @return boolean
1078       */
1079      public boolean isDrawingBuffer()
1080      {
1081        return false; // TODO
1082      }
1083    
1084      /**
1085       * setDebugOptions
1086       *
1087       * @param options the debug options
1088       */
1089      public void setDebugOptions(int options)
1090      {
1091        debugOptions = options;
1092        if ((debugOptions & LOG_OPTION) != 0)
1093          if (options == NONE_OPTION)
1094            logStream().println(prefix() + "Disabling debug");
1095          else
1096            logStream().println(prefix() + "Enabling debug");
1097      }
1098    
1099      /**
1100       * getDebugOptions
1101       *
1102       * @return the debug options
1103       */
1104      public int getDebugOptions()
1105      {
1106        return debugOptions;
1107      }
1108    
1109      /**
1110       * Creates and returns the prefix that should be prepended to all logging
1111       * messages. The prefix is made up like this:
1112       *
1113       * <code>Graphics(<counter>-1)</code> where counter is an integer number
1114       * saying how many DebugGraphics objects have been created so far. The second
1115       * number always seem to be 1 on Sun's JDK, this has to be investigated a
1116       * little more.
1117       *
1118       * @return the prefix that should be prepended to all logging
1119       *         messages
1120       */
1121      private String prefix()
1122      {
1123        return "Graphics(" + counter + "-1)";
1124      }
1125    }