OSDN Git Service

4eb4c6182b12c94b6a38471c6181636b5d5e30e3
[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 instanceof Rectangle)
136       {
137         Rectangle clipRect = (Rectangle) clip;
138         clipRect.x -= tx;
139         clipRect.y -= ty;
140         return clipRect;
141       }
142
143     String msg =
144       "translating clip shape " + clip + " into user " +
145       "coordinate space has not been implemented yet";
146     
147     throw new UnsupportedOperationException(msg);
148   }
149
150   public Rectangle getClipBounds()
151   {
152     Rectangle clipRect = clip.getBounds();
153     
154     clipRect.x -= tx;
155     clipRect.y -= ty;
156     return clipRect;
157   }
158
159   public void copyArea(int x, int y, 
160                        int width, int height,
161                        int dx, int dy)
162   {
163     directGfx.copyArea(x+tx, y+ty, width, height, dx, dy);
164   }
165
166   public void drawLine(int x1, int y1,
167                        int x2, int y2)
168   {
169     directGfx.drawLine(x1+tx, y1+ty, x2+tx, y2+ty);
170   }
171     
172   public void fillRect(int x, int y,
173                        int width, int height)
174   {
175     directGfx.fillRect(x+tx, y+ty, width, height);
176   }
177     
178   public void clearRect(int x, int y,
179                         int width, int height)
180   {
181     directGfx.setColor(frontend.getBackground());
182     directGfx.fillRect(x+tx, y+ty, width, height);
183     directGfx.setColor(frontend.getColor());
184   }
185
186   public void drawRoundRect(int x, int y,
187                             int width, int height,
188                             int arcWidth, int arcHeight)
189   {
190     throw new UnsupportedOperationException("not implemented yet");
191   }
192   
193   public void fillRoundRect(int x, int y,
194                             int width, int height,
195                             int arcWidth, int arcHeight)
196   {
197     throw new UnsupportedOperationException("not implemented yet");
198   }
199
200   public void drawOval(int x, int y,
201                        int width, int height)
202   {
203     drawArc (x, y, width, height, 0, 360);
204   }
205   
206   public void fillOval(int x, int y,
207                        int width, int height)
208   {
209     fillArc (x, y, width, height, 0, 360);
210   }
211
212   public void drawArc(int x, int y,
213                       int width, int height,
214                       int startAngle, int arcAngle)
215   {
216     directGfx.drawArc(x+tx, y+ty, width, height, startAngle, arcAngle);
217   }    
218
219   public void fillArc(int x, int y,
220                       int width, int height,
221                       int startAngle, int arcAngle)
222   {
223     directGfx.fillArc(x+tx, y+ty, width, height, startAngle, arcAngle);
224   }
225   
226   public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
227   {
228     if ((tx == 0) && (ty == 0))
229       {
230         directGfx.drawPolyline(xPoints, yPoints, nPoints);
231         return;
232       }
233             
234     throw new UnsupportedOperationException("translate not implemented");
235   }
236
237   public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
238   {
239     if ((tx == 0) && (ty == 0))
240       {
241         directGfx.drawPolygon(xPoints, yPoints, nPoints);
242         return;
243       }
244
245     throw new UnsupportedOperationException("translate not implemented");
246   }
247   
248   public void fillPolygon (int[] xPoints, int[] yPoints, int nPoints)
249   {
250     // FIXME: remove tx & ty args once translation via AffineTransform
251     // is implemented.
252     directGfx.fillPolygon (xPoints, yPoints, nPoints, tx, ty);
253   }
254
255   public boolean drawImage(Image image, int x, int y,
256                            ImageObserver observer)
257   {
258     x += tx;
259     y += ty;
260     
261     if (image instanceof ScreenCoupledImage)
262     {
263       GraphicsConfiguration config
264         = ((ScreenCoupledImage)image).getGraphicsConfiguration ();
265       if (config == frontend.config)
266         return directGfx.drawImage (image, x, y, observer);
267     }
268     if (image instanceof BufferedImage)
269     {
270       BufferedImage bImage = (BufferedImage) image;
271       // FIXME: eliminate? ScreenCoupledImage is probably more efficient
272       Object config = bImage.getProperty ("java.awt.GraphicsConfiguration");
273       if (config == frontend.config)
274         return directGfx.drawImage (image, x, y, observer);
275       
276       int width = image.getWidth (null);
277       int height = image.getHeight (null);
278       
279       Rectangle bounds = new Rectangle (x, y, width, height);
280       
281       MappedRaster mr = directGfx.mapRaster (bounds);
282       
283       // manipulate raster here...
284       ColorModel colorModel = mr.getColorModel ();
285       WritableRaster raster = mr.getRaster ();
286       
287       int xEnd = x + width;
288       int yEnd = y + height;
289       
290       // FIXME: Use the following code only as a fallback. It's SLOW!
291       
292       Object rgbElem = null;
293       for (int yy=0; yy<height; yy++)
294       {
295         for (int xx=0; xx<width; xx++)
296         {
297           int srgb = bImage.getRGB (xx, yy);
298           int sa = ((srgb >>> 24) & 0xff) + 1;
299           int sr = ((srgb >>> 16) & 0xff) + 1;
300           int sg = ((srgb >>> 8) & 0xff) + 1;
301           int sb = (srgb & 0xff) + 1;
302           
303           rgbElem = raster.getDataElements (xx+x, yy+y, rgbElem);
304           int drgb = colorModel.getRGB (rgbElem);
305           int dr = ((drgb >>> 16) & 0xff) + 1;
306           int dg = ((drgb >>> 8) & 0xff) + 1;
307           int db = (drgb & 0xff) + 1;
308           int da = 256 - sa;
309           
310           dr = ((sr*sa + dr*da) >>> 8) - 1;
311           dg = ((sg*sa + dg*da) >>> 8) - 1;
312           db = ((sb*sa + db*da) >>> 8) - 1;
313           
314           drgb = (dr<<16) | (dg<<8) | db;
315           
316           rgbElem = colorModel.getDataElements (drgb, rgbElem);
317           
318           raster.setDataElements (xx+x, yy+y, rgbElem);
319         }
320       }
321       directGfx.unmapRaster (mr);
322       return true;
323       
324     }
325     throw new UnsupportedOperationException ("drawing image " + image +
326     "not implemented");
327   }
328   
329
330   // -------- Graphics2D methods:
331   
332   public void draw(Shape shape)
333   {
334     if (shape instanceof Rectangle)
335       {
336         Rectangle rect = (Rectangle) shape;
337         directGfx.drawRect(rect.x+tx, rect.y+ty, rect.width, rect.height);
338         return;
339       } 
340     
341     throw new UnsupportedOperationException("shape not implemented");
342   }
343
344   public void fill(Shape shape)
345   {
346     if (shape instanceof Rectangle)
347       {
348         Rectangle rect = (Rectangle) shape;
349         directGfx.fillRect(rect.x+tx, rect.y+ty, rect.width, rect.height);
350         return;
351       }
352     
353     throw new UnsupportedOperationException("not implemented");
354   }
355     
356   public boolean hit(Rectangle rect, Shape text,
357                      boolean onStroke)
358   {
359     throw new UnsupportedOperationException("not implemented");
360   }
361
362   public void drawString(String text, int x, int y)
363   {
364     directGfx.drawString(text, x+tx, y+ty);
365   }
366
367   public void drawString(String text, float x, float y)
368   {
369     drawString(text, (int) x, (int) y);
370   }
371   
372   public void translate(int x, int y)
373   {
374     tx += x;
375     ty += y;
376   }
377     
378   public void translate(double tx, double ty)
379   {
380     if ((tx == 0) && (ty == 0))
381       return;
382     
383     needAffineTransform();
384   }
385
386   public void rotate(double theta)
387   {
388     if (theta == 0)
389       return;
390     
391     needAffineTransform();
392   }
393
394   public void rotate(double theta, double x, double y)
395   {
396     if (theta == 0)
397       return;
398     
399     needAffineTransform();
400   }
401
402   public void scale(double scaleX, double scaleY)
403   {
404     if ((scaleX == 1) && (scaleY == 1))
405       return;
406
407     needAffineTransform();
408   }
409   
410   public void shear(double shearX, double shearY)
411   {
412     if ((shearX == 0) && (shearY == 0))
413       return;
414     
415     needAffineTransform();
416   }   
417   
418   private void needAffineTransform()
419   {
420     throw new UnsupportedOperationException("state with affine " +
421                                             "transform not implemented");
422   }
423 }