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.xlib; 10 11 import java.awt.Image; 12 import java.awt.Graphics; 13 import java.awt.Graphics2D; 14 import java.awt.GraphicsConfiguration; 15 import java.awt.image.ColorModel; 16 import java.awt.image.ImageObserver; 17 import java.awt.image.ImageProducer; 18 import java.awt.image.ImageConsumer; 19 import java.util.Hashtable; 20 import gnu.awt.j2d.DirectRasterGraphics; 21 import gnu.awt.j2d.Graphics2DImpl; 22 import gnu.awt.j2d.IntegerGraphicsState; 23 import gnu.gcj.xlib.Drawable; 24 import gnu.gcj.xlib.Pixmap; 25 import gnu.gcj.xlib.Screen; 26 import gnu.gcj.xlib.Visual; 27 import gnu.gcj.xlib.GC; 28 29 /** Image class for xlib off-screen buffers. 30 * The image is stored in a server-side pixmap for best performance. 31 * This class supports getGraphics, so you can draw on the pixmap, and is 32 * specially handled when doing drawImage, so that the image copy is done 33 * entirely in the X server. 34 * This class does not support rasterization, for which you'd need an XImage. 35 * 36 * @author scott gilbertson <scottg@mantatest.com> <sgilbertson@cogeco.ca> 37 */ 38 public class XOffScreenImage extends Image 39 implements IntegerGraphicsState.ScreenCoupledImage, 40 ImageConsumer 41 { 42 private Pixmap pixmap; 43 private XGraphicsConfiguration config; 44 private int width; 45 private int height; 46 private Drawable drawable; 47 private ImageProducer prod; 48 private GC gc; 49 private ColorModel pixmapColorModel; 50 51 /** Create a new XOffScreenImage 52 * @param config Graphics configuration, to compare against on-screen 53 * components and to create the appropriate Graphics 54 * @param drawable The drawable with which the image is compatible 55 * @param width The width of the image 56 * @param height The height of the image 57 * @param cm The ColorModel associated with drawable 58 */ XOffScreenImage(XGraphicsConfiguration config, Drawable drawable, int width, int height, ColorModel cm)59 XOffScreenImage (XGraphicsConfiguration config, Drawable drawable, int width, int height, ColorModel cm) 60 { 61 this.config = config; 62 this.width = width; 63 this.height = height; 64 this.drawable = drawable; 65 pixmapColorModel = cm; 66 pixmap = new Pixmap (drawable, width, height, drawable.getDepth ()); 67 gc = GC.create (pixmap); 68 } 69 70 /** Create a new XOffScreenImage and obtain image data from an ImageProducer 71 * @param config Graphics configuration, to compare against on-screen 72 * components and to create the appropriate Graphics 73 * @param drawable The drawable with which the image is compatible 74 * @param prod The source of image data for this image 75 * @param cm The ColorModel associated with drawable 76 */ XOffScreenImage(XGraphicsConfiguration config, Drawable drawable, ImageProducer prod, ColorModel cm)77 XOffScreenImage (XGraphicsConfiguration config, Drawable drawable, ImageProducer prod, ColorModel cm) 78 { 79 this.config = config; 80 this.width = 0; // size will be overridden in a moment 81 this.height = 0; 82 this.drawable = drawable; 83 this.prod = prod; 84 pixmapColorModel = cm; 85 prod.startProduction (this); 86 } 87 88 /** Get the pixmap which contains this image 89 * @return The pixmap 90 */ getPixmap()91 public Pixmap getPixmap () 92 { 93 return pixmap; 94 } 95 96 /** Flushes (that is, destroys) any resources used for this image. This 97 * includes the actual image data. 98 */ flush()99 public void flush () 100 { 101 // FIXME: should dispose pixmap 102 pixmap = null; 103 } 104 105 /** Returns a graphics context object for drawing an off-screen object. 106 * This method is only valid for off-screen objects. 107 * 108 * @return a graphics context object for an off-screen object 109 * @see Graphics#createImage(int, int) 110 */ getGraphics()111 public Graphics getGraphics () 112 { 113 DirectRasterGraphics gfxDevice = new XGraphics (pixmap, config); 114 IntegerGraphicsState igState = new IntegerGraphicsState (gfxDevice); 115 Graphics2DImpl gfx2d = new Graphics2DImpl (config); 116 gfx2d.setState (igState); 117 return gfx2d; 118 } 119 120 /** Returns the height of the image, or -1 if it is unknown. If the 121 * image height is unknown, the observer object will be notified when 122 * the value is known. 123 * 124 * @param observer the image observer for this object 125 * @return the height in pixels 126 * @see #getWidth(ImageObserver) 127 */ getHeight(ImageObserver observer)128 public int getHeight (ImageObserver observer) 129 { 130 return height; 131 } 132 133 /** Returns the height of the image, or -1 if it is unknown. If the 134 * image height is unknown, the observer object will be notified when 135 * the value is known. 136 * 137 * @return the height in pixels 138 * @see #getWidth() 139 */ getHeight()140 public int getHeight () 141 { 142 return height; 143 } 144 145 /** Returns the image producer object for this object. The producer is the 146 * object which generates pixels for this image. 147 * 148 * @return the image producer for this object 149 */ getSource()150 public ImageProducer getSource () 151 { 152 if (prod == null) 153 throw new UnsupportedOperationException ("getSource not supported"); 154 else 155 return prod; 156 } 157 158 /** Returns the width of the image, or -1 if it is unknown. If the 159 * image width is unknown, the observer object will be notified when 160 * the value is known. 161 * 162 * @param observer the image observer for this object 163 * @return the width in pixels 164 * @see #getHeight(ImageObserver) 165 */ getWidth(ImageObserver observer)166 public int getWidth (ImageObserver observer) 167 { 168 return width; 169 } 170 171 /** Returns the width of the image, or -1 if it is unknown. If the 172 * image width is unknown, the observer object will be notified when 173 * the value is known. 174 * 175 * @return the width in pixels 176 * @see #getHeight() 177 */ getWidth()178 public int getWidth () 179 { 180 return width; 181 } 182 183 /** This method requests a named property for an object. The value of the 184 * property is returned. The value <code>UndefinedProperty</code> is 185 * returned if there is no property with the specified name. The value 186 * <code>null</code> is returned if the properties for the object are 187 * not yet known. In this case, the specified image observer is notified 188 * when the properties are known. 189 * 190 * @param name the requested property name 191 * @param observer the image observer for this object 192 * @return the named property, if available 193 * @see #UndefinedProperty 194 */ getProperty(String name, ImageObserver observer)195 public Object getProperty (String name, ImageObserver observer) 196 { 197 return null; 198 } 199 200 /** Get the GraphicsConfiguration to which this image is coupled 201 * @return the GraphicsConfiguration 202 */ getGraphicsConfiguration()203 public GraphicsConfiguration getGraphicsConfiguration () 204 { 205 return config; 206 } 207 imageComplete(int status)208 public void imageComplete (int status) 209 { 210 } 211 setColorModel(ColorModel model)212 public void setColorModel (ColorModel model) 213 { 214 } 215 setDimensions(int width, int height)216 public void setDimensions (int width, int height) 217 { 218 this.width = width; 219 this.height = height; 220 pixmap = new Pixmap (drawable, width, height, drawable.getDepth ()); 221 gc = GC.create (pixmap); 222 } 223 setHints(int flags)224 public void setHints (int flags) 225 { 226 } 227 setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int offset, int scansize)228 public void setPixels (int x, int y, int w, int h, ColorModel model, int[] pixels, int offset, int scansize) 229 { 230 int idx = 0; 231 float[] normalizedComponents = new float [4]; 232 int[] unnormalizedComponents = { 0, 0, 0, 0xff }; 233 normalizedComponents[3] = 1; 234 for (int yp=y; yp < (y + h); yp++) 235 { 236 for (int xp=x; xp < (x + w); xp++) 237 { 238 int p = (yp - y) * scansize + (xp - x) + offset; 239 // FIXME: there HAS to be a more efficient mechanism for color mapping 240 normalizedComponents[0] = (float)model.getRed (pixels[p]) / 255F; 241 normalizedComponents[1] = (float)model.getGreen (pixels[p]) / 255F; 242 normalizedComponents[2] = (float)model.getBlue (pixels[p]) / 255F; 243 pixmapColorModel.getUnnormalizedComponents (normalizedComponents, 0, 244 unnormalizedComponents, 0); 245 int pixelColor = pixmapColorModel.getDataElement (unnormalizedComponents, 0); 246 gc.setForeground (pixelColor); 247 gc.drawPoint (xp, yp); 248 } 249 } 250 } 251 setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int offset, int scansize)252 public void setPixels (int x, int y, int w, int h, ColorModel model, byte[] pixels, int offset, int scansize) 253 { 254 int idx = 0; 255 float[] normalizedComponents = new float [4]; 256 int[] unnormalizedComponents = { 0, 0, 0, 0xff }; 257 normalizedComponents[3] = 1; 258 for (int yp=y; yp < (y + h); yp++) 259 { 260 for (int xp=x; xp < (x + w); xp++) 261 { 262 // FIXME: there HAS to be a more efficient mechanism for color mapping 263 int p = (yp - y) * scansize + (xp - x) + offset; 264 normalizedComponents[0] = (float)model.getRed (pixels[p]) / 255F; 265 normalizedComponents[1] = (float)model.getGreen (pixels[p]) / 255F; 266 normalizedComponents[2] = (float)model.getBlue (pixels[p]) / 255F; 267 pixmapColorModel.getUnnormalizedComponents (normalizedComponents, 0, 268 unnormalizedComponents, 0); 269 int pixelColor = pixmapColorModel.getDataElement (unnormalizedComponents, 0); 270 gc.setForeground (pixelColor); 271 gc.drawPoint (xp, yp); 272 } 273 } 274 } 275 setProperties(Hashtable props)276 public void setProperties (Hashtable props) 277 { 278 } 279 280 } 281