Source for gnu.awt.xlib.XOffScreenImage

   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:    */
  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:    */
  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:    */
  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:    */
  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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 203:   public GraphicsConfiguration getGraphicsConfiguration ()
 204:   {
 205:     return config;
 206:   }
 207:   
 208:   public void imageComplete (int status)
 209:   {
 210:   }
 211:   
 212:   public void setColorModel (ColorModel model)
 213:   {
 214:   }
 215:   
 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:   
 224:   public void setHints (int flags)
 225:   {
 226:   }
 227:   
 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:   
 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:   
 276:   public void setProperties (Hashtable props)
 277:   {
 278:   }
 279:   
 280: }