001    /* Graphics.java -- Abstract Java drawing class
002       Copyright (C) 1999, 2000, 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    
039    package java.awt;
040    
041    import java.awt.image.ImageObserver;
042    import java.text.AttributedCharacterIterator;
043    
044    /**
045     * This is the abstract superclass of classes for drawing to graphics
046     * devices such as the screen or printers.
047     *
048     * @author Aaron M. Renn (arenn@urbanophile.com)
049     * @author Warren Levy (warrenl@cygnus.com)
050     */
051    public abstract class Graphics
052    {
053    
054      /**
055       * Default constructor for subclasses.
056       */
057      protected
058      Graphics()
059      {
060      }
061    
062      /**
063       * Returns a copy of this <code>Graphics</code> object.
064       *
065       * @return A copy of this object.
066       */
067      public abstract Graphics create();
068    
069      /**
070       * Returns a copy of this <code>Graphics</code> object.  The origin point
071       * will be translated to the point (x, y) and the cliping rectangle set
072       * to the intersection of the clipping rectangle in this object and the
073       * rectangle specified by the parameters to this method.
074       *
075       * @param x The new X coordinate of the clipping region rect.
076       * @param y The new Y coordinate of the clipping region rect.
077       * @param width The width of the clipping region intersect rectangle. 
078       * @param height The height of the clipping region intersect rectangle. 
079       *
080       * @return A copy of this object, modified as specified.
081       */
082      public Graphics create(int x, int y, int width, int height)
083      {
084        Graphics g = create();
085    
086        g.translate(x, y);
087        // FIXME: I'm not sure if this will work.  Are the old clip rect bounds
088        // translated above?
089        g.clipRect(0, 0, width, height);
090    
091        return(g);
092      }
093    
094      /**
095       * Translates this context so that its new origin point is the point
096       * (x, y).
097       *
098       * @param x The new X coordinate of the origin.
099       * @param y The new Y coordinate of the origin.
100       */
101      public abstract void translate(int x, int y);
102    
103      /**
104       * Returns the current color for this object.
105       *
106       * @return The color for this object.
107       */
108      public abstract Color getColor();
109    
110      /**
111       * Sets the current color for this object.
112       *
113       * @param color The new color.
114       */
115      public abstract void setColor(Color color);
116    
117      /**
118       * Sets this context into "paint" mode, where the target pixels are
119       * completely overwritten when drawn on.
120       */
121      public abstract void setPaintMode();
122    
123      /**
124       * Sets this context info "XOR" mode, where the targe pixles are
125       * XOR-ed when drawn on. 
126       *
127       * @param color The color to XOR against.
128       */
129      public abstract void setXORMode(Color color);
130      
131      /**
132       * Returns the current font for this graphics context.
133       *
134       * @return The current font.
135       */
136      public abstract Font getFont();
137    
138      /**
139       * Sets the font for this graphics context to the specified value.
140       *
141       * @param font The new font.
142       */
143      public abstract void setFont(Font font);
144    
145      /**
146       * Returns the font metrics for the current font.
147       *
148       * @return The font metrics for the current font.
149       */
150      public FontMetrics getFontMetrics()
151      {
152        return getFontMetrics(getFont());
153      }
154    
155      /**
156       * Returns the font metrics for the specified font.
157       *
158       * @param font The font to return metrics for.
159       *
160       * @return The requested font metrics.
161       */
162      public abstract FontMetrics getFontMetrics(Font font);
163    
164      /**
165       * Returns the bounding rectangle of the clipping region for this 
166       * graphics context.
167       *
168       * @return The bounding rectangle for the clipping region.
169       */
170      public abstract Rectangle getClipBounds();
171    
172      /**
173       * Returns the bounding rectangle of the clipping region for this 
174       * graphics context.
175       *
176       * @return The bounding rectangle for the clipping region.
177       *
178       * @deprecated This method is deprecated in favor of
179       * <code>getClipBounds()</code>.
180       */
181      public Rectangle getClipRect()
182      {
183        return getClipBounds();
184      }
185    
186      /**
187       * Sets the clipping region to the intersection of the current clipping
188       * region and the rectangle determined by the specified parameters.
189       *
190       * @param x The X coordinate of the upper left corner of the intersect rect.
191       * @param y The Y coordinate of the upper left corner of the intersect rect.
192       * @param width The width of the intersect rect.
193       * @param height The height of the intersect rect.
194       */
195      public abstract void clipRect(int x, int y, int width, int height);
196    
197      /**
198       * Sets the clipping region to the rectangle determined by the specified
199       * parameters.
200       *
201       * @param x The X coordinate of the upper left corner of the rect.
202       * @param y The Y coordinate of the upper left corner of the rect.
203       * @param width The width of the rect.
204       * @param height The height of the rect.
205       */
206      public abstract void setClip(int x, int y, int width, int height);
207    
208      /**
209       * Returns the current clipping region as a <code>Shape</code> object.
210       *
211       * @return The clipping region as a <code>Shape</code>.
212       */
213      public abstract Shape getClip();
214    
215      /**
216       * Sets the clipping region to the specified <code>Shape</code>.
217       *
218       * @param clip The new clipping region.
219       */
220      public abstract void setClip(Shape clip);
221    
222      /**
223       * Copies the specified rectangle to the specified offset location.
224       *
225       * @param x The X coordinate of the upper left corner of the copy rect.
226       * @param y The Y coordinate of the upper left corner of the copy rect.
227       * @param width The width of the copy rect.
228       * @param height The height of the copy rect.
229       * @param dx The offset from the X value to start drawing.
230       * @param dy The offset from the Y value to start drawing.
231       */
232      public abstract void copyArea(int x, int y, int width, int height, int dx,
233                                    int dy);
234    
235      /**
236       * Draws a line between the two specified points.
237       *
238       * @param x1 The X coordinate of the first point.
239       * @param y1 The Y coordinate of the first point.
240       * @param x2 The X coordinate of the second point.
241       * @param y2 The Y coordinate of the second point.
242       */
243      public abstract void drawLine(int x1, int y1, int x2, int y2);
244    
245      /**
246       * Fills the area bounded by the specified rectangle.
247       *
248       * @param x The X coordinate of the upper left corner of the fill rect.
249       * @param y The Y coordinate of the upper left corner of the fill rect.
250       * @param width The width of the fill rect.
251       * @param height The height of the fill rect.
252       */
253      public abstract void fillRect(int x, int y, int width, int height);
254    
255      /**
256       * Draws the outline of the specified rectangle.
257       *
258       * @param x The X coordinate of the upper left corner of the draw rect.
259       * @param y The Y coordinate of the upper left corner of the draw rect.
260       * @param width The width of the draw rect.
261       * @param height The height of the draw rect.
262       */
263      public void drawRect(int x, int y, int width, int height)
264      {
265        int x1 = x;
266        int y1 = y;
267        int x2 = x + width;
268        int y2 = y + height;
269        drawLine(x1, y1, x2, y1);
270        drawLine(x2, y1, x2, y2);
271        drawLine(x2, y2, x1, y2);
272        drawLine(x1, y2, x1, y1);
273      }
274    
275      /**
276       * Clears the specified rectangle.
277       *
278       * @param x The X coordinate of the upper left corner of the clear rect.
279       * @param y The Y coordinate of the upper left corner of the clear rect.
280       * @param width The width of the clear rect.
281       * @param height The height of the clear rect.
282       */
283      public abstract void clearRect(int x, int y, int width, int height);
284    
285      /**
286       * Draws the outline of the specified rectangle with rounded cornders.
287       *
288       * @param x The X coordinate of the upper left corner of the draw rect.
289       * @param y The Y coordinate of the upper left corner of the draw rect.
290       * @param width The width of the draw rect.
291       * @param height The height of the draw rect.
292       * @param arcWidth The width of the corner arcs.
293       * @param arcHeight The height of the corner arcs.
294       */
295      public abstract void drawRoundRect(int x, int y, int width, int height,
296                                         int arcWidth, int arcHeight);
297    
298      /**
299       * Fills the specified rectangle with rounded cornders.
300       *
301       * @param x The X coordinate of the upper left corner of the fill rect.
302       * @param y The Y coordinate of the upper left corner of the fill rect.
303       * @param width The width of the fill rect.
304       * @param height The height of the fill rect.
305       * @param arcWidth The width of the corner arcs.
306       * @param arcHeight The height of the corner arcs.
307       */
308      public abstract void fillRoundRect(int x, int y, int width, int height,
309                                         int arcWidth, int arcHeight);
310    
311      public void draw3DRect(int x, int y, int width, int height, boolean raised)
312      {
313        Color color = getColor();
314        Color tl = color.brighter();
315        Color br = color.darker();
316        
317        if (!raised)
318          {
319            Color tmp = tl;
320            tl = br;
321            br = tmp;
322          }
323        
324        int x1 = x;
325        int y1 = y;
326        int x2 = x + width;
327        int y2 = y + height;
328        
329        setColor(tl);
330        drawLine(x1, y1, x2, y1);
331        drawLine(x1, y2, x1, y1);
332        setColor(br);
333        drawLine(x2, y1, x2, y2);
334        drawLine(x2, y2, x1, y2);
335        setColor(color);
336      }
337    
338      /**
339       * Fills the specified rectangle with a 3D effect
340       *
341       * @param x The X coordinate of the upper left corner of the fill rect.
342       * @param y The Y coordinate of the upper left corner of the fill rect.
343       * @param width The width of the fill rect.
344       * @param height The height of the fill rect.
345       * @param raised <code>true</code> if the rectangle appears raised,
346       * <code>false</code> if it should appear etched.
347       */
348      public void fill3DRect(int x, int y, int width, int height, boolean raised)
349      {
350        fillRect(x, y, width, height);
351        draw3DRect(x, y, width-1, height-1, raised);
352      }
353    
354      /**
355       * Draws an oval that just fits within the specified rectangle.
356       *
357       * @param x The X coordinate of the upper left corner of the rect.
358       * @param y The Y coordinate of the upper left corner of the rect.
359       * @param width The width of the rect.
360       * @param height The height of the rect.
361       */
362      public abstract void drawOval(int x, int y, int width, int height);
363    
364      /**
365       * Fills an oval that just fits within the specified rectangle.
366       *
367       * @param x The X coordinate of the upper left corner of the rect.
368       * @param y The Y coordinate of the upper left corner of the rect.
369       * @param width The width of the rect.
370       * @param height The height of the rect.
371       */
372      public abstract void fillOval(int x, int y, int width, int height);
373    
374      /**
375       * Draws an arc using the specified bounding rectangle and the specified
376       * angle parameter.  The arc is centered at the center of the rectangle.
377       * The arc starts at the arcAngle position and extend for arcAngle
378       * degrees.  The degree origin is at the 3 o'clock position.
379       *
380       * @param x The X coordinate of the upper left corner of the rect.
381       * @param y The Y coordinate of the upper left corner of the rect.
382       * @param width The width of the rect.
383       * @param height The height of the rect.
384       * @param arcStart The beginning angle of the arc.
385       * @param arcAngle The extent of the arc.
386       */
387      public abstract void drawArc(int x, int y, int width, int height,
388                                   int arcStart, int arcAngle);
389    
390      /**
391       * Fills the arc define by the specified bounding rectangle and the specified
392       * angle parameter.  The arc is centered at the center of the rectangle.
393       * The arc starts at the arcAngle position and extend for arcAngle
394       * degrees.  The degree origin is at the 3 o'clock position.
395       *
396       * @param x The X coordinate of the upper left corner of the rect.
397       * @param y The Y coordinate of the upper left corner of the rect.
398       * @param width The width of the rect.
399       * @param height The height of the rect.
400       * @param arcStart The beginning angle of the arc.
401       * @param arcAngle The extent of the arc.
402       */
403      public abstract void fillArc(int x, int y, int width, int height,
404                                   int arcStart, int arcAngle);
405    
406      /**
407       * Draws a series of interconnected lines determined by the arrays
408       * of corresponding x and y coordinates.
409       *
410       * @param xPoints The X coordinate array.
411       * @param yPoints The Y coordinate array.
412       * @param npoints The number of points to draw.
413       */
414      public abstract void drawPolyline(int xPoints[], int yPoints[], int npoints);
415    
416      /**
417       * Draws a series of interconnected lines determined by the arrays
418       * of corresponding x and y coordinates.  The figure is closed if necessary
419       * by connecting the first and last points.
420       *
421       * @param xPoints The X coordinate array.
422       * @param yPoints The Y coordinate array.
423       * @param npoints The number of points to draw.
424       */
425      public abstract void drawPolygon(int xPoints[], int yPoints[], int npoints);
426    
427      /**
428       * Draws the specified polygon.
429       *
430       * @param polygon The polygon to draw.
431       */
432      public void drawPolygon(Polygon polygon)
433      {
434        drawPolygon(polygon.xpoints, polygon.ypoints, polygon.npoints);
435      }
436    
437      /**
438       * Fills the polygon determined by the arrays
439       * of corresponding x and y coordinates.
440       *
441       * @param xPoints The X coordinate array.
442       * @param yPoints The Y coordinate array.
443       * @param npoints The number of points to draw.
444       */
445      public abstract void fillPolygon(int xPoints[], int yPoints[], int npoints);
446    
447      /**
448       * Fills the specified polygon
449       *
450       * @param polygon The polygon to fill.
451       */
452      public void fillPolygon(Polygon polygon)
453      {
454        fillPolygon(polygon.xpoints, polygon.ypoints, polygon.npoints);
455      }
456    
457      /**
458       * Draws the specified string starting at the specified point.
459       *
460       * @param string The string to draw.
461       * @param x The X coordinate of the point to draw at.
462       * @param y The Y coordinate of the point to draw at.
463       */
464      public abstract void drawString(String string, int x, int y);
465    
466      public abstract void drawString (AttributedCharacterIterator ci, int x,
467                                       int y);
468    
469      /**
470       * Draws the specified characters starting at the specified point.
471       *
472       * @param data The array of characters to draw.
473       * @param offset The offset into the array to start drawing characters from.
474       * @param length The number of characters to draw.
475       * @param x The X coordinate of the point to draw at.
476       * @param y The Y coordinate of the point to draw at.
477       */
478      public void drawChars(char data[], int offset, int length, int x, int y)
479      {
480        drawString(new String(data, offset, length), x, y);
481      }
482    
483      public void drawBytes(byte[] data, int offset, int length, int x, int y)
484      {
485        String str = new String(data, offset, length);
486        drawString(str, x, y);
487      }
488    
489      /**
490       * Draws all of the image that is available and returns.  If the image
491       * is not completely loaded, <code>false</code> is returned and 
492       * the specified iamge observer is notified as more data becomes 
493       * available.
494       *
495       * @param image The image to draw.
496       * @param x The X coordinate of the point to draw at.
497       * @param y The Y coordinate of the point to draw at.
498       * @param observer The image observer to notify as data becomes available.
499       *
500       * @return <code>true</code> if all the image data is available,
501       * <code>false</code> otherwise.
502       */
503      public abstract boolean drawImage(Image image, int x, int y,
504                                        ImageObserver observer);
505     
506      /**
507       * Draws all of the image that is available and returns.  The image
508       * is scaled to fit in the specified rectangle.  If the image
509       * is not completely loaded, <code>false</code> is returned and 
510       * the specified iamge observer is notified as more data becomes 
511       * available.
512       *
513       * @param image The image to draw.
514       * @param x The X coordinate of the point to draw at.
515       * @param y The Y coordinate of the point to draw at.
516       * @param width The width of the rectangle to draw in.
517       * @param height The height of the rectangle to draw in.
518       * @param observer The image observer to notify as data becomes available.
519       *
520       * @return <code>true</code> if all the image data is available,
521       * <code>false</code> otherwise.
522       */
523      public abstract boolean drawImage(Image image, int x, int y, int width,
524                                        int height, ImageObserver observer);
525     
526      /**
527       * Draws all of the image that is available and returns.  If the image
528       * is not completely loaded, <code>false</code> is returned and 
529       * the specified iamge observer is notified as more data becomes 
530       * available.
531       *
532       * @param image The image to draw.
533       * @param x The X coordinate of the point to draw at.
534       * @param y The Y coordinate of the point to draw at.
535       * @param bgcolor The background color to use for the image.
536       * @param observer The image observer to notify as data becomes available.
537       *
538       * @return <code>true</code> if all the image data is available,
539       * <code>false</code> otherwise.
540       */
541      public abstract boolean drawImage(Image image, int x, int y, Color bgcolor,
542                                        ImageObserver observer);
543     
544      /**
545       * Draws all of the image that is available and returns.  The image
546       * is scaled to fit in the specified rectangle.  If the image
547       * is not completely loaded, <code>false</code> is returned and 
548       * the specified iamge observer is notified as more data becomes 
549       * available.
550       *
551       * @param image The image to draw.
552       * @param x The X coordinate of the point to draw at.
553       * @param y The Y coordinate of the point to draw at.
554       * @param width The width of the rectangle to draw in.
555       * @param height The height of the rectangle to draw in.
556       * @param bgcolor The background color to use for the image.
557       * @param observer The image observer to notify as data becomes available.
558       *
559       * @return <code>true</code> if all the image data is available,
560       * <code>false</code> otherwise.
561       */
562      public abstract boolean drawImage(Image image, int x, int y, int width,
563                                        int height, Color bgcolor,
564                                        ImageObserver observer);
565    
566      /**
567       * FIXME: Write Javadocs for this when you understand it.
568       */
569      public abstract boolean drawImage(Image image, int dx1, int dy1, int dx2,
570                                        int dy2, int sx1, int sy1, int sx2,
571                                        int sy2, ImageObserver observer);
572    
573      /**
574       * FIXME: Write Javadocs for this when you understand it.
575       */
576      public abstract boolean drawImage(Image image, int dx1, int dy1, int dx2,
577                                        int dy2, int sx1, int sy1, int sx2,
578                                        int sy2, Color bgcolor,
579                                        ImageObserver observer);
580    
581      /**
582       * Free any resources held by this graphics context immediately instead
583       * of waiting for the object to be garbage collected and finalized.
584       */
585      public abstract void dispose();
586    
587      /**
588       * Frees the resources held by this graphics context when it is
589       * garbage collected.
590       */
591      public void finalize()
592      {
593        dispose();
594      }
595    
596      /**
597       * Returns a string representation of this object.
598       *
599       * @return A string representation of this object. 
600       */
601      public String toString()
602      {
603        return getClass ().getName () + "[font=" + getFont () + ",color="
604               + getColor () + "]";
605      }
606    
607      /**
608       * Returns <code>true</code> if the specified rectangle intersects with the
609       * current clip, <code>false</code> otherwise.
610       *
611       * @param x the X coordinate of the upper left corner of the test rectangle
612       * @param y the Y coordinate of the upper left corner of the test rectangle
613       * @param width the width of the upper left corner of the test rectangle
614       * @param height the height of the upper left corner of the test rectangle
615       * @return <code>true</code> if the specified rectangle intersects with the
616       *         current clip, <code>false</code> otherwise
617       */
618      public boolean hitClip(int x, int y, int width, int height)
619      {
620        Shape clip = getClip();
621        if (clip == null)
622          return true;
623        return getClip().intersects(x, y, width, height);
624      }
625    
626      public Rectangle getClipBounds(Rectangle r)
627      {
628        Rectangle clipBounds = getClipBounds();
629      
630        if (r == null)
631          return clipBounds;
632    
633        r.x      = clipBounds.x;
634        r.y      = clipBounds.y;
635        r.width  = clipBounds.width;
636        r.height = clipBounds.height;
637        return r;
638      }
639    }