package gnu.java.awt.peer.gtk;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.ColorModel;
import java.awt.image.ImageConsumer;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.util.Hashtable;
import java.util.Vector;
public class GtkImage extends Image implements ImageConsumer
{
int width = -1, height = -1;
Hashtable props = null;
boolean isLoaded = false;
boolean isCacheable = true;
boolean loading = false;
Vector widthObservers = new Vector ();
Vector heightObservers = new Vector ();
Vector propertyObservers = new Vector ();
ImageProducer source;
ImageObserver observer;
Graphics g;
int[] pixelCache;
ColorModel model;
public
GtkImage (ImageProducer producer, Graphics g)
{
source = producer;
this.g = g;
if (source != null)
source.addConsumer (this);
}
public void setObserver (ImageObserver observer)
{
this.observer = observer;
}
public synchronized int
getWidth (ImageObserver observer)
{
if (width == -1)
widthObservers.addElement (observer);
return width;
}
public synchronized int
getHeight (ImageObserver observer)
{
if (height == -1)
heightObservers.addElement (observer);
return height;
}
public ImageProducer
getSource ()
{
return source;
}
public Graphics
getGraphics ()
{
return g;
}
public synchronized Object
getProperty (String name, ImageObserver observer)
{
if (props == null)
{
propertyObservers.addElement (observer);
return null;
}
Object value = props.get (name);
return (value == null) ? UndefinedProperty : value;
}
public synchronized void
flush ()
{
isLoaded = false;
isCacheable = true;
width = height = -1;
props = null;
pixelCache = null;
model = null;
if (source != null)
{
source.removeConsumer (this);
source.addConsumer (this);
}
}
public boolean
isLoaded ()
{
return isLoaded;
}
public synchronized void
setDimensions (int width, int height)
{
pixelCache = new int[width*height];
this.width = width;
this.height = height;
for (int i = 0; i < widthObservers.size (); i++)
{
ImageObserver io = (ImageObserver) widthObservers.elementAt (i);
if (io != null)
io.imageUpdate (this, ImageObserver.WIDTH, -1, -1, width, height);
}
for (int i = 0; i < heightObservers.size (); i++)
{
ImageObserver io = (ImageObserver) heightObservers.elementAt (i);
if (io != null)
io.imageUpdate (this, ImageObserver.HEIGHT, -1, -1, width, height);
}
if (observer != null)
observer.imageUpdate (this,
(ImageObserver.WIDTH
| ImageObserver.HEIGHT),
-1, -1, width, height);
}
public synchronized void
setProperties (Hashtable props)
{
this.props = props;
for (int i = 0; i < propertyObservers.size (); i++)
{
ImageObserver io = (ImageObserver) propertyObservers.elementAt (i);
if (io != null)
io.imageUpdate (this, ImageObserver.PROPERTIES, -1, -1, width, height);
}
}
public synchronized void
setColorModel (ColorModel model)
{
if (this.model == null || this.model == model)
this.model = model;
else
isCacheable = false;
}
public synchronized void
setHints (int flags)
{
}
public synchronized void
setPixels (int x, int y, int width, int height, ColorModel cm, byte[] pixels,
int offset, int scansize)
{
setPixels (x, y, width, height, cm, convertPixels (pixels), offset,
scansize);
if (observer != null)
observer.imageUpdate (this,
ImageObserver.SOMEBITS,
x, y, width, height);
}
public synchronized void
setPixels (int x, int y, int width, int height, ColorModel cm, int[] pixels,
int offset, int scansize)
{
loading = true;
if (!isCacheable)
return;
if (cm != model || pixelCache == null)
{
isCacheable = false;
return;
}
if (scansize == width)
{
System.arraycopy (pixels, offset,
pixelCache, y * this.width + x,
pixels.length - offset);
}
else {
for (int i = 0; i < height; i++)
System.arraycopy (pixels, offset + (i * scansize),
pixelCache, (y + i) * this.width + x,
width);
}
}
public synchronized void
imageComplete (int status)
{
if (status == ImageConsumer.STATICIMAGEDONE && isCacheable)
isLoaded = true;
if (status == ImageConsumer.SINGLEFRAMEDONE)
isCacheable = false;
if (observer != null)
{
if (status == ImageConsumer.IMAGEERROR)
observer.imageUpdate (null,
ImageObserver.ERROR,
-1, -1, -1, -1);
else
observer.imageUpdate (null,
ImageObserver.ALLBITS,
-1, -1, -1, -1);
}
if (source != null)
source.removeConsumer (this);
}
public synchronized void
startProduction (GtkImagePainter painter)
{
if (isLoaded)
{
painter.setDimensions (width, height);
painter.setPixels (0, 0, width, height, model, pixelCache, 0, width);
}
else
{
if (source != null)
{
source.startProduction (painter);
source.removeConsumer (painter);
}
}
}
private int[]
convertPixels (byte[] pixels)
{
int ret[] = new int[pixels.length];
for (int i = 0; i < pixels.length; i++)
ret[i] = pixels[i];
return ret;
}
synchronized int
checkImage ()
{
int bits = 0;
if (width != -1)
bits |= ImageObserver.WIDTH;
if (height != -1)
bits |= ImageObserver.HEIGHT;
if (props != null)
bits |= ImageObserver.PROPERTIES;
if (loading)
bits |= ImageObserver.SOMEBITS;
if (isLoaded)
bits |= ImageObserver.ALLBITS;
return bits;
}
}