OSDN Git Service

2006-02-23 Scott Gilbertson <scottg@mantatest.com>
[pf3gnuchains/gcc-fork.git] / libjava / gnu / awt / j2d / IntegerGraphicsState.java
1 /* Copyright (C) 2000, 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.Image;
13 import java.awt.Shape;
14 import java.awt.Rectangle;
15 import java.awt.Graphics;
16 import java.awt.Graphics2D;
17 import java.awt.GraphicsConfiguration;
18 import java.awt.Font;
19 import java.awt.FontMetrics;
20 import java.awt.image.BufferedImage;
21 import java.awt.image.ImageObserver;
22 import java.awt.image.Raster;
23 import java.awt.image.WritableRaster;
24 import java.awt.image.ColorModel;
25
26 /**
27  * IntegerGraphicsState is one of several graphics state
28  * implementations.  This graphics state is used when the graphics
29  * object has simple properties, (coordinate translation only, no
30  * transform) and the backend supports integer coordinates (pixel
31  * based). For primitive paint operations, this object translates the
32  * coordinates and forwards the request to the backend. For requests
33  * to draw arbitrary shapes and paths, this object translates the
34  * requests to primitive drawing operations supported by the
35  * backend. IntegerGraphicsState is meant to support the most common
36  * state of an graphics object. The degree of functionality is roughly
37  * equivalent with the old java.awt.Graphics API.
38  */
39 public class IntegerGraphicsState extends AbstractGraphicsState
40 {
41   int tx;
42   int ty;
43   
44   DirectRasterGraphics directGfx;
45   Shape clip;
46   
47   /** Interface for images which are coupled to a GraphicsConfiguration,
48    * as is typically the case for an off-screen buffer used in
49    * double-buffering.  Any image which implements this interface is
50    * rendered directly by DirectRasterGraphics (i.e. by directGfx.drawImage)
51    */
52   public interface ScreenCoupledImage
53   {
54     /** Get the GraphicsConfiguration to which this image is coupled
55      * @return the GraphicsConfiguration
56      */
57     GraphicsConfiguration getGraphicsConfiguration ();
58   }
59   
60   public IntegerGraphicsState(DirectRasterGraphics directGfx)
61   {
62     this.directGfx = directGfx;
63   }
64   
65   public Object clone()
66   {
67     IntegerGraphicsState clone = (IntegerGraphicsState) super.clone();
68     clone.directGfx = (DirectRasterGraphics) directGfx.clone();
69     
70     return clone;
71   }
72
73   public void dispose()
74   {
75     DirectRasterGraphics lDeviceGfx = directGfx;
76     
77     directGfx = null;
78     
79     if (lDeviceGfx != null)
80       lDeviceGfx.dispose();
81     
82     super.dispose();
83   }
84   
85   // -------- Graphics methods:
86   
87   public void setColor(Color color)
88   {
89     directGfx.setColor(color);
90   }
91   
92   public void setPaintMode()
93   {
94     directGfx.setPaintMode();
95   }
96
97   public void setXORMode(Color altColor)
98   {
99     directGfx.setXORMode(altColor);
100   }
101   
102   public void setFont(Font font)
103   {
104     directGfx.setFont(font);
105   }
106   
107   public FontMetrics getFontMetrics(Font font)
108   {
109     return directGfx.getFontMetrics(font);
110   }
111
112   public void setClip(Shape clip)
113   {
114     if (clip instanceof Rectangle)
115       {
116         Rectangle clipRect = (Rectangle) ((Rectangle) clip).clone();
117         clipRect.x += tx;
118         clipRect.y += ty;
119         
120         this.clip = clipRect;
121         
122         directGfx.setClip(clipRect);
123         return;
124       }
125     
126     String msg =
127       "translating clip shape " + clip + " into device " +
128       "coordinate space has not been implemented yet";
129     
130     throw new UnsupportedOperationException(msg);
131   }
132
133   public Shape getClip()
134   {
135     if (clip == null)
136       return null;
137     if (clip instanceof Rectangle)
138       {
139         Rectangle clipRect = (Rectangle) ((Rectangle) clip).clone();
140         clipRect.x -= tx;
141         clipRect.y -= ty;
142         return clipRect;
143       }
144
145     String msg =
146       "translating clip shape " + clip + " into user " +
147       "coordinate space has not been implemented yet";
148     
149     throw new UnsupportedOperationException(msg);
150   }
151
152   public Rectangle getClipBounds()
153   {
154     if (clip == null)
155       return null;
156     Rectangle clipRect = clip.getBounds();
157     
158     clipRect.x -= tx;
159     clipRect.y -= ty;
160     return clipRect;
161   }
162
163   public void copyArea(int x, int y, 
164                        int width, int height,
165                        int dx, int dy)
166   {
167     directGfx.copyArea(x+tx, y+ty, width, height, dx, dy);
168   }
169
170   public void drawLine(int x1, int y1,
171                        int x2, int y2)
172   {
173     directGfx.drawLine(x1+tx, y1+ty, x2+tx, y2+ty);
174   }
175     
176   public void fillRect(int x, int y,
177                        int width, int height)
178   {
179     directGfx.fillRect(x+tx, y+ty, width, height);
180   }
181     
182   public void clearRect(int x, int y,
183                         int width, int height)
184   {
185     directGfx.setColor(frontend.getBackground());
186     directGfx.fillRect(x+tx, y+ty, width, height);
187     directGfx.setColor(frontend.getColor());
188   }
189
190   public void drawRoundRect(int x, int y,
191                             int width, int height,
192                             int arcWidth, int arcHeight)
193   {
194     throw new UnsupportedOperationException("not implemented yet");
195   }
196   
197   public void fillRoundRect(int x, int y,
198                             int width, int height,
199                             int arcWidth, int arcHeight)
200   {
201     throw new UnsupportedOperationException("not implemented yet");
202   }
203
204   public void drawOval(int x, int y,
205                        int width, int height)
206   {
207     drawArc (x, y, width, height, 0, 360);
208   }
209   
210   public void fillOval(int x, int y,
211                        int width, int height)
212   {
213     fillArc (x, y, width, height, 0, 360);
214   }
215
216   public void drawArc(int x, int y,
217                       int width, int height,
218                       int startAngle, int arcAngle)
219   {
220     directGfx.drawArc(x+tx, y+ty, width, height, startAngle, arcAngle);
221   }    
222
223   public void fillArc(int x, int y,
224                       int width, int height,
225                       int startAngle, int arcAngle)
226   {
227     directGfx.fillArc(x+tx, y+ty, width, height, startAngle, arcAngle);
228   }
229   
230   public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
231   {
232     if ((tx == 0) && (ty == 0))
233       {
234         directGfx.drawPolyline(xPoints, yPoints, nPoints);
235         return;
236       }
237             
238     throw new UnsupportedOperationException("translate not implemented");
239   }
240
241   public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
242   {
243     if ((tx == 0) && (ty == 0))
244       {
245         directGfx.drawPolygon(xPoints, yPoints, nPoints);
246         return;
247       }
248
249     throw new UnsupportedOperationException("translate not implemented");
250   }
251   
252   public void fillPolygon (int[] xPoints, int[] yPoints, int nPoints)
253   {
254     // FIXME: remove tx & ty args once translation via AffineTransform
255     // is implemented.
256     directGfx.fillPolygon (xPoints, yPoints, nPoints, tx, ty);
257   }
258
259   public boolean drawImage(Image image, int x, int y,
260                            ImageObserver observer)
261   {
262     x += tx;
263     y += ty;
264     
265     if (image instanceof ScreenCoupledImage)
266     {
267       GraphicsConfiguration config
268         = ((ScreenCoupledImage)image).getGraphicsConfiguration ();
269       if (config == frontend.config)
270         return directGfx.drawImage (image, x, y, observer);
271     }
272     if (image instanceof BufferedImage)
273     {
274       BufferedImage bImage = (BufferedImage) image;
275       // FIXME: eliminate? ScreenCoupledImage is probably more efficient
276       Object config = bImage.getProperty ("java.awt.GraphicsConfiguration");
277       if (config == frontend.config)
278         return directGfx.drawImage (image, x, y, observer);
279       
280       int width = image.getWidth (null);
281       int height = image.getHeight (null);
282       
283       Rectangle bounds = new Rectangle (x, y, width, height);
284       
285       MappedRaster mr = directGfx.mapRaster (bounds);
286       
287       // manipulate raster here...
288       ColorModel colorModel = mr.getColorModel ();
289       WritableRaster raster = mr.getRaster ();
290       
291       int xEnd = x + width;
292       int yEnd = y + height;
293       
294       // FIXME: Use the following code only as a fallback. It's SLOW!
295       
296       Object rgbElem = null;
297       for (int yy=0; yy<height; yy++)
298       {
299         for (int xx=0; xx<width; xx++)
300         {
301           int srgb = bImage.getRGB (xx, yy);
302           int sa = ((srgb >>> 24) & 0xff) + 1;
303           int sr = ((srgb >>> 16) & 0xff) + 1;
304           int sg = ((srgb >>> 8) & 0xff) + 1;
305           int sb = (srgb & 0xff) + 1;
306           
307           rgbElem = raster.getDataElements (xx+x, yy+y, rgbElem);
308           int drgb = colorModel.getRGB (rgbElem);
309           int dr = ((drgb >>> 16) & 0xff) + 1;
310           int dg = ((drgb >>> 8) & 0xff) + 1;
311           int db = (drgb & 0xff) + 1;
312           int da = 256 - sa;
313           
314           dr = ((sr*sa + dr*da) >>> 8) - 1;
315           dg = ((sg*sa + dg*da) >>> 8) - 1;
316           db = ((sb*sa + db*da) >>> 8) - 1;
317           
318           drgb = (dr<<16) | (dg<<8) | db;
319           
320           rgbElem = colorModel.getDataElements (drgb, rgbElem);
321           
322           raster.setDataElements (xx+x, yy+y, rgbElem);
323         }
324       }
325       directGfx.unmapRaster (mr);
326       return true;
327       
328     }
329     throw new UnsupportedOperationException ("drawing image " + image +
330     "not implemented");
331   }
332   
333
334   // -------- Graphics2D methods:
335   
336   public void draw(Shape shape)
337   {
338     if (shape instanceof Rectangle)
339       {
340         Rectangle rect = (Rectangle) shape;
341         directGfx.drawRect(rect.x+tx, rect.y+ty, rect.width, rect.height);
342         return;
343       } 
344     
345     throw new UnsupportedOperationException("shape not implemented");
346   }
347
348   public void fill(Shape shape)
349   {
350     if (shape instanceof Rectangle)
351       {
352         Rectangle rect = (Rectangle) shape;
353         directGfx.fillRect(rect.x+tx, rect.y+ty, rect.width, rect.height);
354         return;
355       }
356     
357     throw new UnsupportedOperationException("not implemented");
358   }
359     
360   public boolean hit(Rectangle rect, Shape text,
361                      boolean onStroke)
362   {
363     throw new UnsupportedOperationException("not implemented");
364   }
365
366   public void drawString(String text, int x, int y)
367   {
368     directGfx.drawString(text, x+tx, y+ty);
369   }
370
371   public void drawString(String text, float x, float y)
372   {
373     drawString(text, (int) x, (int) y);
374   }
375   
376   public void translate(int x, int y)
377   {
378     tx += x;
379     ty += y;
380   }
381     
382   public void translate(double tx, double ty)
383   {
384     if ((tx == 0) && (ty == 0))
385       return;
386     
387     needAffineTransform();
388   }
389
390   public void rotate(double theta)
391   {
392     if (theta == 0)
393       return;
394     
395     needAffineTransform();
396   }
397
398   public void rotate(double theta, double x, double y)
399   {
400     if (theta == 0)
401       return;
402     
403     needAffineTransform();
404   }
405
406   public void scale(double scaleX, double scaleY)
407   {
408     if ((scaleX == 1) && (scaleY == 1))
409       return;
410
411     needAffineTransform();
412   }
413   
414   public void shear(double shearX, double shearY)
415   {
416     if ((shearX == 0) && (shearY == 0))
417       return;
418     
419     needAffineTransform();
420   }   
421   
422   private void needAffineTransform()
423   {
424     throw new UnsupportedOperationException("state with affine " +
425                                             "transform not implemented");
426   }
427 }