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 */ getGraphicsConfiguration()57 GraphicsConfiguration getGraphicsConfiguration (); 58 } 59 IntegerGraphicsState(DirectRasterGraphics directGfx)60 public IntegerGraphicsState(DirectRasterGraphics directGfx) 61 { 62 this.directGfx = directGfx; 63 } 64 clone()65 public Object clone() 66 { 67 IntegerGraphicsState clone = (IntegerGraphicsState) super.clone(); 68 clone.directGfx = (DirectRasterGraphics) directGfx.clone(); 69 70 return clone; 71 } 72 dispose()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 setColor(Color color)87 public void setColor(Color color) 88 { 89 directGfx.setColor(color); 90 } 91 setPaintMode()92 public void setPaintMode() 93 { 94 directGfx.setPaintMode(); 95 } 96 setXORMode(Color altColor)97 public void setXORMode(Color altColor) 98 { 99 directGfx.setXORMode(altColor); 100 } 101 setFont(Font font)102 public void setFont(Font font) 103 { 104 directGfx.setFont(font); 105 } 106 getFontMetrics(Font font)107 public FontMetrics getFontMetrics(Font font) 108 { 109 return directGfx.getFontMetrics(font); 110 } 111 setClip(Shape clip)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 getClip()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 getClipBounds()150 public Rectangle getClipBounds() 151 { 152 Rectangle clipRect = clip.getBounds(); 153 154 clipRect.x -= tx; 155 clipRect.y -= ty; 156 return clipRect; 157 } 158 copyArea(int x, int y, int width, int height, int dx, int dy)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 drawLine(int x1, int y1, int x2, int y2)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 fillRect(int x, int y, int width, int height)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 clearRect(int x, int y, int width, int height)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 drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)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 fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)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 drawOval(int x, int y, int width, int height)200 public void drawOval(int x, int y, 201 int width, int height) 202 { 203 drawArc (x, y, width, height, 0, 360); 204 } 205 fillOval(int x, int y, int width, int height)206 public void fillOval(int x, int y, 207 int width, int height) 208 { 209 fillArc (x, y, width, height, 0, 360); 210 } 211 drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)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 fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)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 drawPolyline(int[] xPoints, int[] yPoints, int nPoints)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 drawPolygon(int[] xPoints, int[] yPoints, int nPoints)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 fillPolygon(int[] xPoints, int[] yPoints, int nPoints)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 drawImage(Image image, int x, int y, ImageObserver observer)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 draw(Shape shape)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 fill(Shape shape)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 hit(Rectangle rect, Shape text, boolean onStroke)356 public boolean hit(Rectangle rect, Shape text, 357 boolean onStroke) 358 { 359 throw new UnsupportedOperationException("not implemented"); 360 } 361 drawString(String text, int x, int y)362 public void drawString(String text, int x, int y) 363 { 364 directGfx.drawString(text, x+tx, y+ty); 365 } 366 drawString(String text, float x, float y)367 public void drawString(String text, float x, float y) 368 { 369 drawString(text, (int) x, (int) y); 370 } 371 translate(int x, int y)372 public void translate(int x, int y) 373 { 374 tx += x; 375 ty += y; 376 } 377 translate(double tx, double ty)378 public void translate(double tx, double ty) 379 { 380 if ((tx == 0) && (ty == 0)) 381 return; 382 383 needAffineTransform(); 384 } 385 rotate(double theta)386 public void rotate(double theta) 387 { 388 if (theta == 0) 389 return; 390 391 needAffineTransform(); 392 } 393 rotate(double theta, double x, double y)394 public void rotate(double theta, double x, double y) 395 { 396 if (theta == 0) 397 return; 398 399 needAffineTransform(); 400 } 401 scale(double scaleX, double scaleY)402 public void scale(double scaleX, double scaleY) 403 { 404 if ((scaleX == 1) && (scaleY == 1)) 405 return; 406 407 needAffineTransform(); 408 } 409 shear(double shearX, double shearY)410 public void shear(double shearX, double shearY) 411 { 412 if ((shearX == 0) && (shearY == 0)) 413 return; 414 415 needAffineTransform(); 416 } 417 needAffineTransform()418 private void needAffineTransform() 419 { 420 throw new UnsupportedOperationException("state with affine " + 421 "transform not implemented"); 422 } 423 } 424