Major media subsystem revamp:
- All images are loaded through the image manager - Architected to allow the use of prepared or unprepared images (and volatile images when the day comes that they support alpha) - Tunable caches for images and tiles - Resource manager caches unpacked resources on the filesystem - Various and sundry other cleanups git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2116 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
//
|
||||
// $Id: BobbleAnimation.java,v 1.5 2002/11/20 02:18:49 mdb Exp $
|
||||
// $Id: BobbleAnimation.java,v 1.6 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.animation;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import com.threerings.util.RandomUtil;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.image.Mirage;
|
||||
|
||||
/**
|
||||
* An animation that bobbles an image around within a specific horizontal
|
||||
@@ -29,10 +29,10 @@ public class BobbleAnimation extends Animation
|
||||
* @param duration the time to animate in milliseconds.
|
||||
*/
|
||||
public BobbleAnimation (
|
||||
Image image, int sx, int sy, int rx, int ry, int duration)
|
||||
Mirage image, int sx, int sy, int rx, int ry, int duration)
|
||||
{
|
||||
super(new Rectangle(sx - rx, sy - ry, sx + image.getWidth(null) + rx,
|
||||
sy + image.getHeight(null) + ry));
|
||||
super(new Rectangle(sx - rx, sy - ry, sx + image.getWidth() + rx,
|
||||
sy + image.getHeight() + ry));
|
||||
|
||||
// save things off
|
||||
_image = image;
|
||||
@@ -72,7 +72,7 @@ public class BobbleAnimation extends Animation
|
||||
// documentation inherited
|
||||
public void paint (Graphics2D gfx)
|
||||
{
|
||||
gfx.drawImage(_image, _x, _y, null);
|
||||
_image.paint(gfx, _x, _y);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
@@ -98,7 +98,7 @@ public class BobbleAnimation extends Animation
|
||||
protected int _sx, _sy;
|
||||
|
||||
/** The image to animate. */
|
||||
protected Image _image;
|
||||
protected Mirage _image;
|
||||
|
||||
/** Animation ending timing information. */
|
||||
protected long _duration, _end;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ExplodeAnimation.java,v 1.13 2002/10/01 04:24:34 shaper Exp $
|
||||
// $Id: ExplodeAnimation.java,v 1.14 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.animation;
|
||||
|
||||
@@ -7,14 +7,14 @@ import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.threerings.util.RandomUtil;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.util.RandomUtil;
|
||||
import com.threerings.media.image.Mirage;
|
||||
|
||||
/**
|
||||
* An animation that displays an object exploding into chunks, fading out
|
||||
@@ -88,7 +88,7 @@ public class ExplodeAnimation extends Animation
|
||||
* @param height the height of the object.
|
||||
*/
|
||||
public ExplodeAnimation (
|
||||
Image image, ExplodeInfo info, int x, int y, int width, int height)
|
||||
Mirage image, ExplodeInfo info, int x, int y, int width, int height)
|
||||
{
|
||||
super(info.bounds);
|
||||
|
||||
@@ -233,7 +233,7 @@ public class ExplodeAnimation extends Animation
|
||||
if (_image != null) {
|
||||
// draw the image chunk
|
||||
gfx.clipRect(-_hcwid, -_hchei, _cwid, _chei);
|
||||
gfx.drawImage(_image, -_hcwid + xoff, -_hchei + yoff, null);
|
||||
_image.paint(gfx, -_hcwid + xoff, -_hchei + yoff);
|
||||
|
||||
} else {
|
||||
// draw the color chunk
|
||||
@@ -303,7 +303,7 @@ public class ExplodeAnimation extends Animation
|
||||
protected Color _color;
|
||||
|
||||
/** The image to animate if we're using an image. */
|
||||
protected Image _image;
|
||||
protected Mirage _image;
|
||||
|
||||
/** The starting animation time. */
|
||||
protected long _start;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: FadeAnimation.java,v 1.5 2002/10/01 04:24:34 shaper Exp $
|
||||
// $Id: FadeAnimation.java,v 1.6 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.animation;
|
||||
|
||||
@@ -7,10 +7,10 @@ import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.image.Mirage;
|
||||
|
||||
/**
|
||||
* An animation that displays an image fading from one alpha level to
|
||||
@@ -30,9 +30,9 @@ public class FadeAnimation extends Animation
|
||||
* @param target the target alpha level.
|
||||
*/
|
||||
public FadeAnimation (
|
||||
Image image, int x, int y, float alpha, float step, float target)
|
||||
Mirage image, int x, int y, float alpha, float step, float target)
|
||||
{
|
||||
super(new Rectangle(x, y, image.getWidth(null), image.getHeight(null)));
|
||||
super(new Rectangle(x, y, image.getWidth(), image.getHeight()));
|
||||
|
||||
// save things off
|
||||
_image = image;
|
||||
@@ -90,7 +90,7 @@ public class FadeAnimation extends Animation
|
||||
} else {
|
||||
gfx.setComposite(_comp);
|
||||
}
|
||||
gfx.drawImage(_image, _x, _y, null);
|
||||
_image.paint(gfx, _x, _y);
|
||||
gfx.setComposite(ocomp);
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public class FadeAnimation extends Animation
|
||||
protected int _x, _y;
|
||||
|
||||
/** The image to animate. */
|
||||
protected Image _image;
|
||||
protected Mirage _image;
|
||||
|
||||
/** The starting animation time. */
|
||||
protected long _start;
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
//
|
||||
// $Id: SparkAnimation.java,v 1.1 2002/11/27 01:37:14 shaper Exp $
|
||||
// $Id: SparkAnimation.java,v 1.2 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.animation;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.threerings.media.animation.Animation;
|
||||
|
||||
import com.threerings.util.RandomUtil;
|
||||
|
||||
import com.threerings.media.animation.Animation;
|
||||
import com.threerings.media.image.Mirage;
|
||||
|
||||
/**
|
||||
* Displays a set of spark images originating from a specified position
|
||||
* and flying outward in random directions, fading out as they go, for a
|
||||
@@ -41,7 +41,7 @@ public class SparkAnimation extends Animation
|
||||
public SparkAnimation (Rectangle bounds, int x, int y, int jog,
|
||||
float minxvel, float minyvel,
|
||||
float xvel, float yvel,
|
||||
float g, Image[] images, long delay)
|
||||
float g, Mirage[] images, long delay)
|
||||
{
|
||||
super(bounds);
|
||||
|
||||
@@ -141,7 +141,7 @@ public class SparkAnimation extends Animation
|
||||
gfx.setComposite(_comp);
|
||||
// draw all sparks
|
||||
for (int ii = 0; ii < _icount; ii++) {
|
||||
gfx.drawImage(_images[ii], _xpos[ii], _ypos[ii], null);
|
||||
_images[ii].paint(gfx, _xpos[ii], _ypos[ii]);
|
||||
}
|
||||
// restore the original composite
|
||||
gfx.setComposite(ocomp);
|
||||
@@ -158,7 +158,7 @@ public class SparkAnimation extends Animation
|
||||
}
|
||||
|
||||
/** The spark images we're animating. */
|
||||
protected Image[] _images;
|
||||
protected Mirage[] _images;
|
||||
|
||||
/** The number of images we're animating. */
|
||||
protected int _icount;
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// $Id: BackedVolatileMirage.java,v 1.1 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.image;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
|
||||
/**
|
||||
* Provides a volatile mirage that is backed by a buffered image that is
|
||||
* not obtained from the image manager but is instead provided at
|
||||
* construct time and completely circumvents the image manager's cache. As
|
||||
* such, this should not be used unless you know what you're doing.
|
||||
*/
|
||||
public class BackedVolatileMirage extends VolatileMirage
|
||||
{
|
||||
/**
|
||||
* Creates a mirage with the supplied regeneration informoation and
|
||||
* prepared image.
|
||||
*/
|
||||
public BackedVolatileMirage (ImageManager imgr, BufferedImage source)
|
||||
{
|
||||
super(imgr, new Rectangle(0, 0, source.getWidth(), source.getHeight()));
|
||||
_source = source;
|
||||
|
||||
// create our volatile image for the first time
|
||||
createVolatileImage();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected void refreshVolatileImage ()
|
||||
{
|
||||
Graphics gfx = null;
|
||||
try {
|
||||
gfx = _image.getGraphics();
|
||||
gfx.drawImage(_source, -_bounds.x, -_bounds.y, null);
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.warning("Failure refreshing mirage " + this + ".");
|
||||
Log.logStackTrace(e);
|
||||
|
||||
} finally {
|
||||
gfx.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected void toString (StringBuffer buf)
|
||||
{
|
||||
super.toString(buf);
|
||||
buf.append(", src=").append(_source);
|
||||
}
|
||||
|
||||
protected BufferedImage _source;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// $Id: BlankMirage.java,v 1.1 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.image;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
/**
|
||||
* A mirage implementation that contains no image data. Generally only
|
||||
* useful for testing.
|
||||
*/
|
||||
public class BlankMirage implements Mirage
|
||||
{
|
||||
public BlankMirage (int width, int height)
|
||||
{
|
||||
_width = width;
|
||||
_height = height;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void paint (Graphics2D gfx, int x, int y)
|
||||
{
|
||||
// nothing doing
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int getWidth ()
|
||||
{
|
||||
return _width;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int getHeight ()
|
||||
{
|
||||
return _height;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean hitTest (int x, int y)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public BufferedImage getSnapshot ()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected int _width;
|
||||
protected int _height;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// $Id: BufferedMirage.java,v 1.1 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.image;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
/**
|
||||
* A simple mirage implementation that uses a buffered image.
|
||||
*/
|
||||
public class BufferedMirage implements Mirage
|
||||
{
|
||||
public BufferedMirage (BufferedImage image)
|
||||
{
|
||||
_image = image;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void paint (Graphics2D gfx, int x, int y)
|
||||
{
|
||||
gfx.drawImage(_image, x, y, null);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int getWidth ()
|
||||
{
|
||||
return _image.getWidth();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int getHeight ()
|
||||
{
|
||||
return _image.getHeight();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean hitTest (int x, int y)
|
||||
{
|
||||
return ImageUtil.hitTest(_image, x, y);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public BufferedImage getSnapshot ()
|
||||
{
|
||||
return _image;
|
||||
}
|
||||
|
||||
protected BufferedImage _image;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
//
|
||||
// $Id: CachedVolatileMirage.java,v 1.1 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.image;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
/**
|
||||
* A mirage implementation which allows the image to be maintained in
|
||||
* video memory and refetched from the image manager in the event that our
|
||||
* target screen resolution changes or we are flushed from video memory
|
||||
* for some other reason.
|
||||
*
|
||||
* <p> These objects are never created directly, but always obtained from
|
||||
* the {@link ImageManager}.
|
||||
*/
|
||||
public class CachedVolatileMirage extends VolatileMirage
|
||||
{
|
||||
/**
|
||||
* Creates a mirage with the supplied regeneration informoation and
|
||||
* prepared image.
|
||||
*/
|
||||
protected CachedVolatileMirage (
|
||||
ImageManager imgr, ImageManager.ImageKey source,
|
||||
Rectangle bounds, Colorization[] zations)
|
||||
{
|
||||
super(imgr, bounds);
|
||||
|
||||
_source = source;
|
||||
_zations = zations;
|
||||
|
||||
// create our volatile image for the first time
|
||||
createVolatileImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rerenders our volatile image from the its source image data.
|
||||
*/
|
||||
protected void refreshVolatileImage ()
|
||||
{
|
||||
Graphics gfx = null;
|
||||
try {
|
||||
BufferedImage source = _imgr.getImage(_source, _zations);
|
||||
gfx = _image.getGraphics();
|
||||
gfx.drawImage(source, -_bounds.x, -_bounds.y, null);
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.warning("Failure refreshing mirage " + this + ".");
|
||||
Log.logStackTrace(e);
|
||||
|
||||
} finally {
|
||||
if (gfx != null) {
|
||||
gfx.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected void toString (StringBuffer buf)
|
||||
{
|
||||
super.toString(buf);
|
||||
buf.append(", key=").append(_source);
|
||||
buf.append(", zations=").append(_zations);
|
||||
}
|
||||
|
||||
/** The key that identifies the image data used to create our volatile
|
||||
* image. */
|
||||
protected ImageManager.ImageKey _source;
|
||||
|
||||
/** Optional colorizations that are applied to our source image when
|
||||
* creating our mirage. */
|
||||
protected Colorization[] _zations;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: Colorization.java,v 1.6 2003/01/08 04:09:02 mdb Exp $
|
||||
// $Id: Colorization.java,v 1.7 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.image;
|
||||
|
||||
@@ -100,6 +100,12 @@ public class Colorization
|
||||
return true;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int hashCode ()
|
||||
{
|
||||
return colorizationId ^ rootColor.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this colorization to another based on id.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// $Id: ImageDataProvider.java,v 1.1 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.image;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
/**
|
||||
* Provides access to image data for the image with the specified
|
||||
* path. Images loaded from different data providers (which are
|
||||
* differentiated by reference equality) will be considered distinct
|
||||
* images with respect to caching.
|
||||
*/
|
||||
public interface ImageDataProvider
|
||||
{
|
||||
/**
|
||||
* Returns a string identifier for this image data provider which wil
|
||||
* be used to differentiate it from other providers and thus should be
|
||||
* unique.
|
||||
*/
|
||||
public String getIdent ();
|
||||
|
||||
/**
|
||||
* Returns an input stream from which the image data for the specified
|
||||
* image may be loaded.
|
||||
*/
|
||||
public ImageInputStream loadImageData (String path) throws IOException;
|
||||
}
|
||||
@@ -1,13 +1,22 @@
|
||||
//
|
||||
// $Id: ImageIOLoader.java,v 1.5 2003/01/08 04:09:02 mdb Exp $
|
||||
// $Id: ImageIOLoader.java,v 1.6 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.image;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.stream.MemoryCacheImageInputStream;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
|
||||
/**
|
||||
* Loads images using the <code>ImageIO</code> services provided by J2SE
|
||||
@@ -20,6 +29,16 @@ public class ImageIOLoader implements ImageLoader
|
||||
// we need to reference ImageIO in the constructor to force the
|
||||
// classloader to attempt to load the ImageIO classes
|
||||
ImageIO.setUseCache(true);
|
||||
|
||||
// String[] fmts = ImageIO.getReaderFormatNames();
|
||||
// Log.info("Got formats " + StringUtil.toString(fmts) + ".");
|
||||
|
||||
Iterator iter = ImageIO.getImageReadersByFormatName("png");
|
||||
if (iter.hasNext()) {
|
||||
_reader = (ImageReader)iter.next();
|
||||
} else {
|
||||
Log.warning("Aiya! No reader.");
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
@@ -29,10 +48,18 @@ public class ImageIOLoader implements ImageLoader
|
||||
// this seems to choke when decoding the compressed image data
|
||||
// which may mean it's a JDK bug or something, but I'd like to see
|
||||
// it resolved so that the image manager will work on applets
|
||||
//
|
||||
// ImageInputStream iis = new MemoryCacheImageInputStream(source);
|
||||
// return ImageIO.read(iis);
|
||||
|
||||
// ImageInputStream iis = null;
|
||||
// // // iis = ImageIO.createImageInputStream(source);
|
||||
// iis = new MemoryCacheImageInputStream(source);
|
||||
|
||||
// // // Log.info("Created stream " + iis + "/" + source);
|
||||
// _reader.setInput(iis, true, false);
|
||||
// return _reader.read(0);
|
||||
|
||||
// return ImageIO.read(new MemoryCacheImageInputStream(source));
|
||||
return ImageIO.read(source);
|
||||
}
|
||||
|
||||
protected ImageReader _reader;
|
||||
}
|
||||
|
||||
@@ -1,21 +1,37 @@
|
||||
//
|
||||
// $Id: ImageManager.java,v 1.34 2003/01/08 05:17:35 ray Exp $
|
||||
// $Id: ImageManager.java,v 1.35 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.image;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.sun.imageio.plugins.png.PNGImageReaderSpi;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
import com.samskivert.io.NestableIOException;
|
||||
import com.samskivert.util.ConfigUtil;
|
||||
import com.samskivert.util.LRUHashMap;
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.samskivert.util.Throttle;
|
||||
import com.samskivert.util.Tuple;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.resource.ResourceManager;
|
||||
@@ -25,6 +41,45 @@ import com.threerings.resource.ResourceManager;
|
||||
*/
|
||||
public class ImageManager
|
||||
{
|
||||
/**
|
||||
* Used to identify an image for caching and reconstruction.
|
||||
*/
|
||||
public static class ImageKey
|
||||
{
|
||||
/** The data provider from which this image's data is loaded. */
|
||||
public ImageDataProvider daprov;
|
||||
|
||||
/** The path used to identify the image to the data provider. */
|
||||
public String path;
|
||||
|
||||
protected ImageKey (ImageDataProvider daprov, String path)
|
||||
{
|
||||
this.daprov = daprov;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public int hashCode ()
|
||||
{
|
||||
return path.hashCode() ^ daprov.getIdent().hashCode();
|
||||
}
|
||||
|
||||
public boolean equals (Object other)
|
||||
{
|
||||
if (other == null || !(other instanceof ImageKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ImageKey okey = (ImageKey)other;
|
||||
return ((okey.daprov.getIdent().equals(daprov.getIdent())) &&
|
||||
(okey.path.equals(path)));
|
||||
}
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
return daprov.getIdent() + ":" + path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an image manager with the specified {@link
|
||||
* ResourceManager} from which it will obtain its data. A non-null
|
||||
@@ -37,6 +92,12 @@ public class ImageManager
|
||||
{
|
||||
_rmgr = rmgr;
|
||||
|
||||
// create our image cache
|
||||
int icsize = ConfigUtil.getSystemProperty(
|
||||
"narya.media.image.cache_size", DEFAULT_IMAGE_CACHE_SIZE);
|
||||
Log.debug("Creating image cache [size=" + icsize + "].");
|
||||
_ccache = new LRUHashMap(icsize);
|
||||
|
||||
// try to figure out which image loader we'll be using
|
||||
try {
|
||||
_loader = (ImageLoader)Class.forName(IMAGEIO_LOADER).newInstance();
|
||||
@@ -45,123 +106,253 @@ public class ImageManager
|
||||
"Falling back to Toolkit [error=" + t + "].");
|
||||
_loader = new ToolkitLoader(context);
|
||||
}
|
||||
|
||||
// obtain our graphics configuration
|
||||
if (context != null) {
|
||||
_gc = context.getGraphicsConfiguration();
|
||||
} else {
|
||||
_gc = ImageUtil.getDefGC();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads up the requested image from the specified resource set and
|
||||
* caches it for faster retrieval henceforth.
|
||||
* Creates a buffered image, optimized for display on our graphics
|
||||
* device.
|
||||
*/
|
||||
public Image getImage (String rset, String path)
|
||||
public BufferedImage createImage (int width, int height, int transparency)
|
||||
{
|
||||
if (rset == null || path == null) {
|
||||
String errmsg = "Must supply non-null resource set and path " +
|
||||
"[rset=" + rset + ", path=" + path + "]";
|
||||
return _gc.createCompatibleImage(width, height, transparency);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads (and caches) the specified image from the resource manager
|
||||
* using the supplied path to identify the image.
|
||||
*/
|
||||
public BufferedImage getImage (String path)
|
||||
{
|
||||
return getImage(null, path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getImage(String)} but the specified colorizations are
|
||||
* applied to the image before it is returned.
|
||||
*/
|
||||
public BufferedImage getImage (String path, Colorization[] zations)
|
||||
{
|
||||
return getImage(null, path, zations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getImage(String)} but the image is loaded from the
|
||||
* specified resource set rathern than the default resource set.
|
||||
*/
|
||||
public BufferedImage getImage (String rset, String path)
|
||||
{
|
||||
return getImage(rset, path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getImage(String,String)} but the specified
|
||||
* colorizations are applied to the image before it is returned.
|
||||
*/
|
||||
public BufferedImage getImage (String rset, String path,
|
||||
Colorization[] zations)
|
||||
{
|
||||
if (StringUtil.blank(path)) {
|
||||
String errmsg = "Invalid image path [rset=" + rset +
|
||||
", path=" + path + "]";
|
||||
throw new IllegalArgumentException(errmsg);
|
||||
}
|
||||
|
||||
// periodically report our image cache performance
|
||||
reportCachePerformance();
|
||||
|
||||
String key = rset + ":" + path;
|
||||
Image img = (Image)_imgs.get(key);
|
||||
if (img != null) {
|
||||
// Log.info("Retrieved image from cache [path=" + path + "].");
|
||||
return img;
|
||||
}
|
||||
|
||||
InputStream imgin = null;
|
||||
try {
|
||||
// first attempt to load the image from the specified resource set
|
||||
try {
|
||||
imgin = _rmgr.getResource(rset, path);
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
// fall through and try the classpath
|
||||
}
|
||||
|
||||
// if that fails, attempt to load the image from the classpath
|
||||
if (imgin == null) {
|
||||
imgin = _rmgr.getResource(path);
|
||||
// Log.info("Fell back to classpath [rset=" + rset +
|
||||
// ", path=" + path + "].");
|
||||
}
|
||||
|
||||
// now load up and optimize the image for display
|
||||
img = createImage(imgin);
|
||||
|
||||
} catch (IOException ioe) {
|
||||
Log.warning("Failure loading image [rset=" + rset +
|
||||
", path=" + path + ", error=" + ioe + "].");
|
||||
|
||||
} finally {
|
||||
if (imgin != null) {
|
||||
try {
|
||||
imgin.close();
|
||||
} catch (IOException ioe) {
|
||||
Log.warning("Failure closing image input stream " +
|
||||
"[rset=" + rset + ", path=" + path +
|
||||
", error=" + ioe + "].");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Log.info("Loading image into cache [path=" + path + "].");
|
||||
if (img != null) {
|
||||
_imgs.put(key, img);
|
||||
} else {
|
||||
Log.warning("Unable to load image " +
|
||||
"[rset=" + rset + ", path=" + path + "].");
|
||||
Thread.dumpStack();
|
||||
// fake it so that we don't crap out
|
||||
img = ImageUtil.createImage(1, 1);
|
||||
}
|
||||
return img;
|
||||
return getImage(getImageKey(rset, path), zations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the image via the resource manager using the specified path
|
||||
* and caches it for faster retrieval henceforth.
|
||||
* Returns an image key that can be used to fetch the image identified
|
||||
* by the specified resource set and image path.
|
||||
*/
|
||||
public Image getImage (String path)
|
||||
public ImageKey getImageKey (String rset, String path)
|
||||
{
|
||||
return getImageKey(getDataProvider(rset), path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an image key that can be used to fetch the image identified
|
||||
* by the specified data provider and image path.
|
||||
*/
|
||||
public ImageKey getImageKey (ImageDataProvider daprov, String path)
|
||||
{
|
||||
return new ImageKey(daprov, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the image identified by the specified key, caching if
|
||||
* possible. The image will be recolored using the supplied
|
||||
* colorizations if requested.
|
||||
*/
|
||||
public BufferedImage getImage (ImageKey key, Colorization[] zations)
|
||||
{
|
||||
CacheRecord crec = (CacheRecord)_ccache.get(key);
|
||||
if (crec != null) {
|
||||
// Log.info("Cache hit [key=" + key + ", crec=" + crec + "].");
|
||||
return crec.getImage(zations);
|
||||
}
|
||||
// Log.info("Cache miss [key=" + key + ", crec=" + crec + "].");
|
||||
|
||||
// load up the raw image
|
||||
BufferedImage image = loadImage(key);
|
||||
if (image == null) {
|
||||
Log.warning("Failed to load image " + key + ".");
|
||||
}
|
||||
|
||||
// create a cache record
|
||||
crec = new CacheRecord(image);
|
||||
_ccache.put(key, crec);
|
||||
_keySet.add(key);
|
||||
|
||||
// periodically report our image cache performance
|
||||
reportCachePerformance();
|
||||
|
||||
Image img = (Image)_imgs.get(path);
|
||||
if (img != null) {
|
||||
// Log.info("Retrieved image from cache [path=" + path + "].");
|
||||
return img;
|
||||
return crec.getImage(zations);
|
||||
}
|
||||
|
||||
InputStream imgin = null;
|
||||
/**
|
||||
* Returns the data provider configured to obtain image data from the
|
||||
* specified resource set.
|
||||
*/
|
||||
protected ImageDataProvider getDataProvider (final String rset)
|
||||
{
|
||||
if (rset == null) {
|
||||
return _defaultProvider;
|
||||
}
|
||||
|
||||
ImageDataProvider dprov = (ImageDataProvider)_providers.get(rset);
|
||||
if (dprov == null) {
|
||||
dprov = new ImageDataProvider() {
|
||||
public ImageInputStream loadImageData (String path)
|
||||
throws IOException {
|
||||
// first attempt to load the image from the specified
|
||||
// resource set
|
||||
try {
|
||||
imgin = _rmgr.getResource(path);
|
||||
img = createImage(imgin);
|
||||
return _rmgr.getImageResource(rset, path);
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
// fall back to trying the classpath
|
||||
return _rmgr.getImageResource(path);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (IOException ioe) {
|
||||
Log.warning("Failure loading image [path=" + path +
|
||||
", error=" + ioe + "].");
|
||||
public String getIdent () {
|
||||
return "rmgr:" + rset;
|
||||
}
|
||||
};
|
||||
_providers.put(rset, dprov);
|
||||
}
|
||||
|
||||
return dprov;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads and returns the image with the specified key from the
|
||||
* supplied data provider.
|
||||
*/
|
||||
protected BufferedImage loadImage (ImageKey key)
|
||||
{
|
||||
BufferedImage image = null;
|
||||
ImageInputStream imgin = null;
|
||||
try {
|
||||
Log.debug("Loading image " + key + ".");
|
||||
imgin = key.daprov.loadImageData(key.path);
|
||||
image = loadImage(imgin);
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.warning("Unable to load image '" + key + "'.");
|
||||
Log.logStackTrace(e);
|
||||
|
||||
// create a blank image in its stead
|
||||
image = createImage(1, 1, Transparency.OPAQUE);
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (imgin != null) {
|
||||
try {
|
||||
imgin.close();
|
||||
} catch (IOException ioe) {
|
||||
Log.warning("Failure closing image input stream " +
|
||||
"[path=" + path + ", error=" + ioe + "].");
|
||||
}
|
||||
Log.warning("Failure closing image input '" + key + "'.");
|
||||
Log.logStackTrace(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
// Log.info("Loading image into cache [path=" + path + "].");
|
||||
if (img != null) {
|
||||
_imgs.put(path, img);
|
||||
} else {
|
||||
Log.warning("Unable to load image [path=" + path + "].");
|
||||
Thread.dumpStack();
|
||||
// fake it so that we don't crap out
|
||||
img = ImageUtil.createImage(1, 1);
|
||||
return image;
|
||||
}
|
||||
return img;
|
||||
|
||||
/**
|
||||
* Called by {@link #loadImage(ImageKey)} to do the actual image
|
||||
* loading.
|
||||
*/
|
||||
protected BufferedImage loadImage (ImageInputStream imgin)
|
||||
throws IOException
|
||||
{
|
||||
return ImageIO.read(imgin);
|
||||
// _reader.setInput(imgin, false, false);
|
||||
// return _reader.read(0, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mirage which is an image optimized for display on our
|
||||
* current display device and which will be stored into video memory
|
||||
* if possible.
|
||||
*/
|
||||
public Mirage getMirage (ImageKey key)
|
||||
{
|
||||
return getMirage(key, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getMirage(ImageKey)} but that only the specified
|
||||
* subimage of the source image is used to build the mirage.
|
||||
*/
|
||||
public Mirage getMirage (ImageKey key, Rectangle bounds)
|
||||
{
|
||||
return getMirage(key, bounds, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getMirage(ImageKey)} but the supplied colorizations
|
||||
* are applied to the source image before creating the mirage.
|
||||
*/
|
||||
public Mirage getMirage (ImageKey key, Colorization[] zations)
|
||||
{
|
||||
return getMirage(key, null, zations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getMirage(ImageKey,Colorization[])} except that the
|
||||
* mirage is created using only the specified subset of the original
|
||||
* image.
|
||||
*/
|
||||
public Mirage getMirage (ImageKey key, Rectangle bounds,
|
||||
Colorization[] zations)
|
||||
{
|
||||
if (bounds == null) {
|
||||
BufferedImage src = getImage(key, zations);
|
||||
bounds = new Rectangle(0, 0, src.getWidth(), src.getHeight());
|
||||
// return new BufferedMirage(src);
|
||||
// } else {
|
||||
// BufferedImage src = getImage(key, zations);
|
||||
// src = src.getSubimage(bounds.x, bounds.y,
|
||||
// bounds.width, bounds.height);
|
||||
// return new BufferedMirage(src);
|
||||
}
|
||||
return new CachedVolatileMirage(this, key, bounds, zations);
|
||||
// return new BlankMirage(bounds.width, bounds.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the graphics configuration that should be used to optimize
|
||||
* images for display.
|
||||
*/
|
||||
public GraphicsConfiguration getGraphicsConfiguration ()
|
||||
{
|
||||
return _gc;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,125 +361,74 @@ public class ImageManager
|
||||
*/
|
||||
protected void reportCachePerformance ()
|
||||
{
|
||||
if (!_cacheStatThrottle.throttleOp()) {
|
||||
long size = ImageUtil.getEstimatedMemoryUsage(
|
||||
_imgs.values().iterator());
|
||||
int[] eff = _imgs.getTrackedEffectiveness();
|
||||
Log.debug("ImageManager LRU [mem=" + (size / 1024) + "k" +
|
||||
", size=" + _imgs.size() + ", hits=" + eff[0] +
|
||||
", misses=" + eff[1] + "].");
|
||||
}
|
||||
if (/* Log.getLevel() != Log.log.DEBUG || */
|
||||
_cacheStatThrottle.throttleOp()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the image via the resource manager using the specified
|
||||
* path. Does no caching and does not convert the image for optimized
|
||||
* display on the target graphics configuration. Instead the original
|
||||
* image as returned by the image loader is returned.
|
||||
*/
|
||||
public Image loadImage (String path)
|
||||
throws IOException
|
||||
// compute our estimated memory usage
|
||||
long size = 0;
|
||||
Iterator iter = _ccache.values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
size += ((CacheRecord)iter.next()).getEstimatedMemoryUsage();
|
||||
}
|
||||
|
||||
int[] eff = _ccache.getTrackedEffectiveness();
|
||||
Log.info("ImageManager LRU [mem=" + (size / 1024) + "k" +
|
||||
", size=" + _ccache.size() + ", hits=" + eff[0] +
|
||||
", misses=" + eff[1] + ", totalKeys=" + _keySet.size() + "].");
|
||||
}
|
||||
|
||||
/** Maintains a source image and a set of colorized versions in the
|
||||
* image cache. */
|
||||
protected static class CacheRecord
|
||||
{
|
||||
InputStream imgin = null;
|
||||
try {
|
||||
imgin = _rmgr.getResource(path);
|
||||
return _loader.loadImage(new BufferedInputStream(imgin));
|
||||
|
||||
} catch (IllegalArgumentException iae) {
|
||||
String errmsg = "Error loading image [path=" + path + "]";
|
||||
throw new NestableIOException(errmsg, iae);
|
||||
|
||||
} finally {
|
||||
if (imgin != null) {
|
||||
imgin.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the image from the given resource set using the specified
|
||||
* path. Does no caching and does not convert the image for optimized
|
||||
* display on the target graphics configuration. Instead the original
|
||||
* image as returned by the image loader is returned.
|
||||
*/
|
||||
public Image loadImage (String rset, String path)
|
||||
throws IOException
|
||||
public CacheRecord (BufferedImage source)
|
||||
{
|
||||
InputStream imgin = null;
|
||||
try {
|
||||
imgin = _rmgr.getResource(rset, path);
|
||||
return _loader.loadImage(new BufferedInputStream(imgin));
|
||||
|
||||
} catch (Throwable t) {
|
||||
String errmsg = "Error loading image " +
|
||||
"[rset=" + rset + ", path=" + path + "]";
|
||||
throw new NestableIOException(errmsg, t);
|
||||
|
||||
} finally {
|
||||
if (imgin != null) {
|
||||
imgin.close();
|
||||
}
|
||||
}
|
||||
_source = source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the image from the supplied input stream. Does no caching and
|
||||
* does not convert the image for optimized display on the target
|
||||
* graphics configuration. Instead the original image as returned by
|
||||
* the image loader is returned.
|
||||
*/
|
||||
public Image loadImage (InputStream source)
|
||||
throws IOException
|
||||
public BufferedImage getImage (Colorization[] zations)
|
||||
{
|
||||
try {
|
||||
return _loader.loadImage(new BufferedInputStream(source));
|
||||
} catch (IllegalArgumentException iae) {
|
||||
String errmsg = "Error loading image";
|
||||
throw new NestableIOException(errmsg, iae);
|
||||
if (zations == null) {
|
||||
return _source;
|
||||
}
|
||||
|
||||
if (_colorized == null) {
|
||||
_colorized = new ArrayList();
|
||||
}
|
||||
|
||||
// we search linearly through our list of colorized copies
|
||||
// because it is not likely to be very long
|
||||
int csize = _colorized.size();
|
||||
for (int ii = 0; ii < csize; ii++) {
|
||||
Tuple tup = (Tuple)_colorized.get(ii);
|
||||
Colorization[] tzations = (Colorization[])tup.left;
|
||||
if (Arrays.equals(zations, tzations)) {
|
||||
return (BufferedImage)tup.right;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an image that is optimized for rendering in the client's
|
||||
* environment and decodes the image data from the specified source
|
||||
* image into that target image. The resulting image is not cached.
|
||||
*/
|
||||
public Image createImage (InputStream source)
|
||||
throws IOException
|
||||
BufferedImage cimage = ImageUtil.recolorImage(_source, zations);
|
||||
_colorized.add(new Tuple(zations, cimage));
|
||||
return cimage;
|
||||
}
|
||||
|
||||
public long getEstimatedMemoryUsage ()
|
||||
{
|
||||
return createImage(loadImage(source));
|
||||
return ImageUtil.getEstimatedMemoryUsage(_source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an image that is optimized for rendering in the client's
|
||||
* environment and renders the supplied image into the optimized
|
||||
* image. The resulting image is not cached.
|
||||
*/
|
||||
public Image createImage (Image src)
|
||||
public String toString ()
|
||||
{
|
||||
// not to freak out if we get this far and have no image
|
||||
if (src == null) {
|
||||
return null;
|
||||
return "[wid=" + _source.getWidth() +
|
||||
", hei=" + _source.getHeight() +
|
||||
", ccount=" + ((_colorized == null) ? 0 : _colorized.size()) +
|
||||
"]";
|
||||
}
|
||||
|
||||
int swidth = src.getWidth(null);
|
||||
int sheight = src.getHeight(null);
|
||||
BufferedImage dest = null;
|
||||
|
||||
// use the same kind of transparency as the source image if we can
|
||||
// when converting the image to a format optimized for display
|
||||
if (src instanceof BufferedImage) {
|
||||
int trans = ((BufferedImage)src).getColorModel().getTransparency();
|
||||
dest = ImageUtil.createImage(swidth, sheight, trans);
|
||||
} else {
|
||||
dest = ImageUtil.createImage(swidth, sheight);
|
||||
}
|
||||
|
||||
Graphics2D gfx = dest.createGraphics();
|
||||
gfx.drawImage(src, 0, 0, null);
|
||||
gfx.dispose();
|
||||
|
||||
return dest;
|
||||
protected BufferedImage _source;
|
||||
protected ArrayList _colorized;
|
||||
}
|
||||
|
||||
/** A reference to the resource manager via which we load image data
|
||||
@@ -300,11 +440,37 @@ public class ImageManager
|
||||
protected ImageLoader _loader;
|
||||
|
||||
/** A cache of loaded images. */
|
||||
protected LRUHashMap _imgs = new LRUHashMap(IMAGE_CACHE_SIZE);
|
||||
protected LRUHashMap _ccache;
|
||||
|
||||
/** The set of all keys we've ever seen. */
|
||||
protected HashSet _keySet = new HashSet();
|
||||
|
||||
/** Throttle our cache status logging to once every 30 seconds. */
|
||||
protected Throttle _cacheStatThrottle = new Throttle(1, 30000L);
|
||||
|
||||
/** The graphics configuration for the default screen device. */
|
||||
protected GraphicsConfiguration _gc;
|
||||
|
||||
/** Our default data provider. */
|
||||
protected ImageDataProvider _defaultProvider = new ImageDataProvider() {
|
||||
public ImageInputStream loadImageData (String path)
|
||||
throws IOException {
|
||||
return _rmgr.getImageResource(path);
|
||||
}
|
||||
|
||||
public String getIdent () {
|
||||
return "rmgr:default";
|
||||
}
|
||||
};
|
||||
|
||||
// /** Temporary hacked PNG reader that actually closes its
|
||||
// * InflaterInputStream when it's done with it. */
|
||||
// protected PNGImageReader _reader =
|
||||
// new PNGImageReader(new PNGImageReaderSpi());
|
||||
|
||||
/** Data providers for different resource sets. */
|
||||
protected HashMap _providers = new HashMap();
|
||||
|
||||
/** The classname of the ImageIO-based image loader which we attempt
|
||||
* to use but fallback from if we're not running a JVM that has
|
||||
* ImageIO support. */
|
||||
@@ -312,5 +478,5 @@ public class ImageManager
|
||||
"com.threerings.media.image.ImageIOLoader";
|
||||
|
||||
/** The maximum number of images that may be cached at any one time. */
|
||||
protected static final int IMAGE_CACHE_SIZE = 30;
|
||||
protected static final int DEFAULT_IMAGE_CACHE_SIZE = 100;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ImageUtil.java,v 1.21 2003/01/08 04:28:13 ray Exp $
|
||||
// $Id: ImageUtil.java,v 1.22 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.image;
|
||||
|
||||
@@ -426,8 +426,8 @@ public class ImageUtil
|
||||
|
||||
// copy the RGB from the base image
|
||||
for (int ii=0; ii < 3; ii++) {
|
||||
int[] cdata = basedata.getSamples(0, 0, wid, hei,
|
||||
ii, (int[]) null);
|
||||
int[] cdata = basedata.getSamples(
|
||||
0, 0, wid, hei, ii, (int[]) null);
|
||||
target.setSamples(0, 0, wid, hei, ii, cdata);
|
||||
}
|
||||
|
||||
@@ -490,22 +490,11 @@ public class ImageUtil
|
||||
* Returns true if the supplied image contains a non-transparent pixel
|
||||
* at the specified coordinates, false otherwise.
|
||||
*/
|
||||
public static boolean hitTest (Image image, int x, int y)
|
||||
public static boolean hitTest (BufferedImage image, int x, int y)
|
||||
{
|
||||
if (image instanceof BufferedImage) {
|
||||
BufferedImage bimage = (BufferedImage)image;
|
||||
int argb = bimage.getRGB(x, y);
|
||||
// int alpha = argb >> 24;
|
||||
// Log.info("Checking [x=" + x + ", y=" + y + ", " + alpha);
|
||||
|
||||
// it's only a hit if the pixel is non-transparent
|
||||
int argb = image.getRGB(x, y);
|
||||
return (argb >> 24) != 0;
|
||||
|
||||
} else {
|
||||
Log.warning("Can't check for transparent pixel " +
|
||||
"[image=" + image + "].");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// $Id: Mirage.java,v 1.1 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.image;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
/**
|
||||
* Provides an interface via which images can be accessed in a way that
|
||||
* allows them to optionally be located in video memory where that affords
|
||||
* performance improvements.
|
||||
*/
|
||||
public interface Mirage
|
||||
{
|
||||
/**
|
||||
* Renders this mirage at the specified position in the supplied
|
||||
* graphics context.
|
||||
*/
|
||||
public void paint (Graphics2D gfx, int x, int y);
|
||||
|
||||
/**
|
||||
* Returns the width of this mirage.
|
||||
*/
|
||||
public int getWidth ();
|
||||
|
||||
/**
|
||||
* Returns the height of this mirage.
|
||||
*/
|
||||
public int getHeight ();
|
||||
|
||||
/**
|
||||
* Returns true if this mirage contains a non-transparent pixel at the
|
||||
* specified coordinate.
|
||||
*/
|
||||
public boolean hitTest (int x, int y);
|
||||
|
||||
/**
|
||||
* Returns a snapshot of this mirage as a buffered image. The snapshot
|
||||
* should <em>not</em> be modified by the caller.
|
||||
*/
|
||||
public BufferedImage getSnapshot ();
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// $Id: MirageIcon.java,v 1.1 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.image;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Graphics;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
/**
|
||||
* Implements the Swing {@link Icon} interface with a mirage providing the
|
||||
* image information.
|
||||
*/
|
||||
public class MirageIcon implements Icon
|
||||
{
|
||||
public MirageIcon (Mirage mirage)
|
||||
{
|
||||
_mirage = mirage;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void paintIcon (Component c, Graphics g, int x, int y)
|
||||
{
|
||||
_mirage.paint((Graphics2D)g, x, y);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int getIconWidth()
|
||||
{
|
||||
return _mirage.getWidth();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int getIconHeight()
|
||||
{
|
||||
return _mirage.getHeight();
|
||||
}
|
||||
|
||||
protected Mirage _mirage;
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
//
|
||||
// $Id: VolatileMirage.java,v 1.1 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.image;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.VolatileImage;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
/**
|
||||
* A mirage implementation which allows the image to be maintained in
|
||||
* video memory and rebuilt from some source image or images in the event
|
||||
* that our target screen resolution changes or we are flushed from video
|
||||
* memory for some other reason.
|
||||
*/
|
||||
public abstract class VolatileMirage implements Mirage
|
||||
{
|
||||
/**
|
||||
* Informs the base class of its image manager and image bounds.
|
||||
*/
|
||||
protected VolatileMirage (ImageManager imgr, Rectangle bounds)
|
||||
{
|
||||
_imgr = imgr;
|
||||
_bounds = bounds;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void paint (Graphics2D gfx, int x, int y)
|
||||
{
|
||||
// create our volatile image for the first time if necessary
|
||||
if (_image == null) {
|
||||
createVolatileImage();
|
||||
}
|
||||
|
||||
// int renders = 0;
|
||||
// do {
|
||||
// // validate that our image is compatible with the target GC
|
||||
// switch (_image.validate(_imgr.getGraphicsConfiguration())) {
|
||||
// case VolatileImage.IMAGE_RESTORED:
|
||||
// refreshVolatileImage(); // need to rerender it
|
||||
// break;
|
||||
// case VolatileImage.IMAGE_INCOMPATIBLE:
|
||||
// createVolatileImage(); // need to recreate it
|
||||
// break;
|
||||
// }
|
||||
|
||||
// now we can render it
|
||||
gfx.drawImage(_image, x, y, null);
|
||||
// renders++;
|
||||
|
||||
// // don't try forever
|
||||
// } while (_image.contentsLost() && (renders < 10));
|
||||
|
||||
// TODO: note number of attempted renders for performance
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int getWidth ()
|
||||
{
|
||||
return _bounds.width;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int getHeight ()
|
||||
{
|
||||
return _bounds.height;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean hitTest (int x, int y)
|
||||
{
|
||||
// return ImageUtil.hitTest(_image.getSnapshot(), x, y);
|
||||
return ImageUtil.hitTest(_image, x, y);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public BufferedImage getSnapshot ()
|
||||
{
|
||||
// return _image.getSnapshot();
|
||||
return _image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates our volatile image from the information in our source
|
||||
* image.
|
||||
*/
|
||||
protected void createVolatileImage ()
|
||||
{
|
||||
// release any previous volatile image we might hold
|
||||
if (_image != null) {
|
||||
_image.flush();
|
||||
}
|
||||
|
||||
// create a new, compatible, volatile image
|
||||
GraphicsConfiguration gc = _imgr.getGraphicsConfiguration();
|
||||
// _image = gc.createCompatibleVolatileImage(
|
||||
// _bounds.width, _bounds.height);
|
||||
_image = gc.createCompatibleImage(
|
||||
_bounds.width, _bounds.height, Transparency.BITMASK);
|
||||
|
||||
// render our source image into the volatile image
|
||||
refreshVolatileImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rerenders our volatile image from the its source image data.
|
||||
*/
|
||||
protected abstract void refreshVolatileImage ();
|
||||
|
||||
/**
|
||||
* Generates a string representation of this instance.
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer("[");
|
||||
toString(buf);
|
||||
return buf.append("]").toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a string representation of this instance.
|
||||
*/
|
||||
protected void toString (StringBuffer buf)
|
||||
{
|
||||
buf.append("bounds=").append(StringUtil.toString(_bounds));
|
||||
}
|
||||
|
||||
/** The image manager with whom we interoperate. */
|
||||
protected ImageManager _imgr;
|
||||
|
||||
/** The bounds of the region of our source image which we desire for
|
||||
* this mirage (possibly the whole thing). */
|
||||
protected Rectangle _bounds;
|
||||
|
||||
/** Our volatile image which lives in video memory and can go away at
|
||||
* any time. */
|
||||
// protected VolatileImage _image;
|
||||
protected BufferedImage _image;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ImageSprite.java,v 1.16 2002/11/20 05:33:20 mdb Exp $
|
||||
// $Id: ImageSprite.java,v 1.17 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.sprite;
|
||||
|
||||
@@ -8,7 +8,6 @@ import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
@@ -16,6 +15,7 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.image.Mirage;
|
||||
import com.threerings.media.util.MultiFrameImage;
|
||||
import com.threerings.media.util.SingleFrameImageImpl;
|
||||
|
||||
@@ -75,7 +75,7 @@ public class ImageSprite extends Sprite
|
||||
* Constructs an image sprite that will display the supplied single
|
||||
* image when rendering itself.
|
||||
*/
|
||||
public ImageSprite (Image image)
|
||||
public ImageSprite (Mirage image)
|
||||
{
|
||||
this(new SingleFrameImageImpl(image));
|
||||
}
|
||||
@@ -85,8 +85,9 @@ public class ImageSprite extends Sprite
|
||||
{
|
||||
super.init();
|
||||
|
||||
// now that we have our spritemanager, we can initialize our frames
|
||||
setFrameIndex(0, true);
|
||||
// now that we have our sprite manager, we can lay ourselves out
|
||||
// and initialize our frames
|
||||
layout();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,7 +158,19 @@ public class ImageSprite extends Sprite
|
||||
|
||||
// set and init our frames
|
||||
_frames = frames;
|
||||
setFrameIndex(0, true);
|
||||
_frameIdx = 0;
|
||||
layout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs this sprite to lay out its current frame and any
|
||||
* accoutrements.
|
||||
*/
|
||||
public void layout ()
|
||||
{
|
||||
if (_frames != null) {
|
||||
setFrameIndex(_frameIdx, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// $Id: IMImageProvider.java,v 1.1 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import com.threerings.media.image.Colorization;
|
||||
import com.threerings.media.image.ImageDataProvider;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.Mirage;
|
||||
|
||||
/**
|
||||
* Provides images to a tileset given a reference to the image manager and
|
||||
* an image data provider.
|
||||
*/
|
||||
public class IMImageProvider implements ImageProvider
|
||||
{
|
||||
public IMImageProvider (ImageManager imgr, ImageDataProvider dprov)
|
||||
{
|
||||
_imgr = imgr;
|
||||
_dprov = dprov;
|
||||
}
|
||||
|
||||
public IMImageProvider (ImageManager imgr, String rset)
|
||||
{
|
||||
_imgr = imgr;
|
||||
_rset = rset;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public BufferedImage getTileSetImage (String path, Colorization[] zations)
|
||||
{
|
||||
return _imgr.getImage(getImageKey(path), zations);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public Mirage getTileImage (String path, Rectangle bounds,
|
||||
Colorization[] zations)
|
||||
{
|
||||
return _imgr.getMirage(getImageKey(path), bounds, zations);
|
||||
}
|
||||
|
||||
protected final ImageManager.ImageKey getImageKey (String path)
|
||||
{
|
||||
return (_dprov == null) ?
|
||||
_imgr.getImageKey(_rset, path) :
|
||||
_imgr.getImageKey(_dprov, path);
|
||||
}
|
||||
|
||||
protected ImageManager _imgr;
|
||||
protected ImageDataProvider _dprov;
|
||||
protected String _rset;
|
||||
}
|
||||
@@ -1,26 +1,45 @@
|
||||
//
|
||||
// $Id: ImageProvider.java,v 1.2 2001/12/07 01:33:29 mdb Exp $
|
||||
// $Id: ImageProvider.java,v 1.3 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.io.IOException;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import com.threerings.media.image.Colorization;
|
||||
import com.threerings.media.image.Mirage;
|
||||
|
||||
/**
|
||||
* A tileset needs to load its images from some location. That will
|
||||
* generally either be via the {@link TileManager} that constructed it or
|
||||
* the {@link TileSetRepository} that constructed it. The tile manager
|
||||
* loads images via the resource manager, whereas the tileset repository
|
||||
* will likely obtain images via its own resource bundles.
|
||||
* Provides a generic interface via which tileset images may be loaded. In
|
||||
* most cases, a running application will want to obtain images via the
|
||||
* {@link ImageManager}, but in some circumstances a simpler image
|
||||
* provider may be desirable to avoid the overhead of the image manager
|
||||
* infrastructure when simple image loading is all that is desired.
|
||||
*/
|
||||
public interface ImageProvider
|
||||
{
|
||||
/**
|
||||
* Loads the image with the specified path.
|
||||
* Returns the raw tileset image with the specified path.
|
||||
*
|
||||
* @exception IOException thrown if an error occurs loading the image
|
||||
* data.
|
||||
* @param path the path that identifies the desired image (corresponds
|
||||
* to the image path from the tileset).
|
||||
* @param zations if non-null, colorizations to apply to the source
|
||||
* image before returning it.
|
||||
*/
|
||||
public Image loadImage (String path)
|
||||
throws IOException;
|
||||
public BufferedImage getTileSetImage (String path, Colorization[] zations);
|
||||
|
||||
/**
|
||||
* Obtains the tile image with the specified path in the form of a
|
||||
* {@link Mirage}. It should be cropped from the tileset image
|
||||
* identified by the supplied path.
|
||||
*
|
||||
* @param path the path that identifies the desired image (corresponds
|
||||
* to the image path from the tileset).
|
||||
* @param bounds if non-null, the region of the image to be returned
|
||||
* as a mirage. If null, the entire image should be returned.
|
||||
* @param zations if non-null, colorizations to apply to the image
|
||||
* before converting it into a mirage.
|
||||
*/
|
||||
public Mirage getTileImage (String path, Rectangle bounds,
|
||||
Colorization[] zations);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: NoSuchTileException.java,v 1.1 2001/10/11 00:41:26 shaper Exp $
|
||||
// $Id: NoSuchTileException.java,v 1.2 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
@@ -7,7 +7,7 @@ package com.threerings.media.tile;
|
||||
* Thrown when an attempt is made to retrieve a non-existent tile from the
|
||||
* tile manager.
|
||||
*/
|
||||
public class NoSuchTileException extends TileException
|
||||
public class NoSuchTileException extends RuntimeException
|
||||
{
|
||||
public NoSuchTileException (int tid)
|
||||
{
|
||||
|
||||
@@ -1,24 +1,21 @@
|
||||
//
|
||||
// $Id: NoSuchTileSetException.java,v 1.1 2001/10/11 00:41:26 shaper Exp $
|
||||
// $Id: NoSuchTileSetException.java,v 1.2 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
/**
|
||||
* Thrown when an attempt is made to retrieve a non-existent tile set
|
||||
* from the tile set manager.
|
||||
* Thrown when an attempt is made to retrieve a non-existent tile set from
|
||||
* the tile set manager.
|
||||
*/
|
||||
public class NoSuchTileSetException extends TileException
|
||||
public class NoSuchTileSetException extends Exception
|
||||
{
|
||||
public NoSuchTileSetException (int tsid)
|
||||
public NoSuchTileSetException (String tileSetName)
|
||||
{
|
||||
super("No such tile set [tsid=" + tsid + "]");
|
||||
_tsid = tsid;
|
||||
super("No tile set named '" + tileSetName + "'");
|
||||
}
|
||||
|
||||
public int getTileSetId ()
|
||||
public NoSuchTileSetException (int tileSetId)
|
||||
{
|
||||
return _tsid;
|
||||
super("No tile set with id '" + tileSetId + "'");
|
||||
}
|
||||
|
||||
protected int _tsid;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
//
|
||||
// $Id: ObjectTile.java,v 1.12 2003/01/08 04:09:02 mdb Exp $
|
||||
// $Id: ObjectTile.java,v 1.13 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import com.threerings.media.image.Mirage;
|
||||
|
||||
/**
|
||||
* An object tile extends the base tile to provide support for objects
|
||||
* whose image spans more than one unit tile. An object tile has
|
||||
* dimensions (in tile units) that represent its footprint or "shadow".
|
||||
* whose image spans more than one unit tile.
|
||||
*
|
||||
* <p> An object tile is generally positioned based on its origin rather
|
||||
* than the upper left of its image. Generally this origin is in the
|
||||
* bottom center of the object image, but can be configured to be anywhere
|
||||
* that the natural center point of "contact" is for the object. Note that
|
||||
* this does not automatically adjust the semantics of {@link #paint}, it
|
||||
* is just expected that the caller will account for the object tile's
|
||||
* origin when painting, if appropriate.
|
||||
*
|
||||
* <p> An object tile has dimensions (in tile units) that represent its
|
||||
* footprint or "shadow".
|
||||
*/
|
||||
public class ObjectTile extends Tile
|
||||
{
|
||||
@@ -17,21 +26,9 @@ public class ObjectTile extends Tile
|
||||
* Constructs a new object tile with the specified image. The base
|
||||
* width and height should be set before using this tile.
|
||||
*/
|
||||
public ObjectTile (Image image, Rectangle bounds)
|
||||
public ObjectTile (Mirage image)
|
||||
{
|
||||
super(image, bounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new object tile with the specified base width and
|
||||
* height.
|
||||
*/
|
||||
public ObjectTile (Image image, Rectangle bounds,
|
||||
int baseWidth, int baseHeight)
|
||||
{
|
||||
super(image, bounds);
|
||||
_baseWidth = baseWidth;
|
||||
_baseHeight = baseHeight;
|
||||
super(image);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,7 +50,7 @@ public class ObjectTile extends Tile
|
||||
/**
|
||||
* Sets the object footprint in tile units.
|
||||
*/
|
||||
public void setBase (int width, int height)
|
||||
protected void setBase (int width, int height)
|
||||
{
|
||||
_baseWidth = width;
|
||||
_baseHeight = height;
|
||||
@@ -91,7 +88,7 @@ public class ObjectTile extends Tile
|
||||
* the origin tile and the left side of the image is aligned with the
|
||||
* left edge of the left-most base tile.
|
||||
*/
|
||||
public void setOrigin (int x, int y)
|
||||
protected void setOrigin (int x, int y)
|
||||
{
|
||||
_originX = x;
|
||||
_originY = y;
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
//
|
||||
// $Id: ObjectTileSet.java,v 1.8 2003/01/08 04:09:02 mdb Exp $
|
||||
// $Id: ObjectTileSet.java,v 1.9 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
|
||||
import com.threerings.media.image.Mirage;
|
||||
|
||||
/**
|
||||
* The object tileset supports the specification of object information for
|
||||
@@ -69,24 +66,15 @@ public class ObjectTileSet extends SwissArmyTileSet
|
||||
* Creates instances of {@link ObjectTile}, which can span more than a
|
||||
* single tile's space in a display.
|
||||
*/
|
||||
protected Tile createTile (int tileIndex, Image tilesetImage)
|
||||
protected Tile createTile (int tileIndex, Mirage image)
|
||||
{
|
||||
// default object dimensions to (1, 1)
|
||||
int wid = 1, hei = 1;
|
||||
|
||||
// retrieve object dimensions if known
|
||||
ObjectTile tile = new ObjectTile(image);
|
||||
if (_owidths != null) {
|
||||
wid = _owidths[tileIndex];
|
||||
hei = _oheights[tileIndex];
|
||||
tile.setBase(_owidths[tileIndex], _oheights[tileIndex]);
|
||||
}
|
||||
|
||||
Rectangle bounds = computeTileBounds(tileIndex, tilesetImage);
|
||||
ObjectTile tile = new ObjectTile(tilesetImage, bounds, wid, hei);
|
||||
|
||||
if (_xorigins != null) {
|
||||
tile.setOrigin(_xorigins[tileIndex], _yorigins[tileIndex]);
|
||||
}
|
||||
|
||||
return tile;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// $Id: SimpleCachingImageProvider.java,v 1.1 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.samskivert.util.LRUHashMap;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.image.Colorization;
|
||||
import com.threerings.media.image.Mirage;
|
||||
|
||||
/**
|
||||
* An image provider that can be used by command line tools to load images
|
||||
* and provide them to tilesets when doing things like preprocessing
|
||||
* tileset images.
|
||||
*/
|
||||
public abstract class SimpleCachingImageProvider implements ImageProvider
|
||||
{
|
||||
// documentation inherited from interface
|
||||
public BufferedImage getTileSetImage (String path, Colorization[] zations)
|
||||
{
|
||||
BufferedImage image = (BufferedImage)_cache.get(path);
|
||||
if (image == null) {
|
||||
try {
|
||||
image = loadImage(path);
|
||||
_cache.put(path, image);
|
||||
} catch (IOException ioe) {
|
||||
Log.warning("Failed to load image [path=" + path +
|
||||
", ioe=" + ioe + "].");
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public Mirage getTileImage (String path, Rectangle bounds,
|
||||
Colorization[] zations)
|
||||
{
|
||||
// since we're just doing batch processing, we don't prepare
|
||||
// images for the screen
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes must implement this method to actually load the raw
|
||||
* source images.
|
||||
*/
|
||||
protected abstract BufferedImage loadImage (String path)
|
||||
throws IOException;
|
||||
|
||||
protected LRUHashMap _cache = new LRUHashMap(10);
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
//
|
||||
// $Id: SwissArmyTileSet.java,v 1.8 2002/05/06 18:08:32 mdb Exp $
|
||||
// $Id: SwissArmyTileSet.java,v 1.9 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Image;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
@@ -128,7 +127,7 @@ public class SwissArmyTileSet extends TileSet
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected Rectangle computeTileBounds (int tileIndex, Image tilesetImage)
|
||||
protected Rectangle computeTileBounds (int tileIndex)
|
||||
{
|
||||
// find the row number containing the sought-after tile
|
||||
int ridx, tcount, ty, tx;
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
//
|
||||
// $Id: Tile.java,v 1.25 2003/01/08 04:09:02 mdb Exp $
|
||||
// $Id: Tile.java,v 1.26 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.image.ImageUtil;
|
||||
import com.threerings.media.image.Mirage;
|
||||
|
||||
/**
|
||||
* A tile represents a single square in a single layer in a scene.
|
||||
@@ -20,40 +13,14 @@ import com.threerings.media.image.ImageUtil;
|
||||
public class Tile implements Cloneable
|
||||
{
|
||||
/**
|
||||
* Constructs a tile with the specified tileset image.
|
||||
* Constructs a tile with the specified image.
|
||||
*
|
||||
* @param image the tileset image from which our tile image is
|
||||
* extracted.
|
||||
* @param bounds the bounds of the tile image within the greater
|
||||
* tileset image.
|
||||
* @param image our tile image in mirage form (which is optimized for
|
||||
* screen rendering).
|
||||
*/
|
||||
public Tile (Image image, Rectangle bounds)
|
||||
public Tile (Mirage image)
|
||||
{
|
||||
_image = image;
|
||||
_bounds = bounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to create our subimage.
|
||||
*/
|
||||
protected void createSubImage ()
|
||||
{
|
||||
if (_image instanceof BufferedImage) {
|
||||
try {
|
||||
_subimage = ImageUtil.getSubimage(
|
||||
_image, _bounds.x, _bounds.y,
|
||||
_bounds.width, _bounds.height);
|
||||
} catch (RuntimeException rte) {
|
||||
Log.warning("Failure creating subimage [src=" + _image +
|
||||
", bounds=" + StringUtil.toString(_bounds) +
|
||||
", error=" + rte + "].");
|
||||
throw rte;
|
||||
}
|
||||
|
||||
} else {
|
||||
String errmsg = "Can't obtain tile image [tile=" + this + "].";
|
||||
throw new RuntimeException(errmsg);
|
||||
}
|
||||
_mirage = image;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +28,7 @@ public class Tile implements Cloneable
|
||||
*/
|
||||
public int getWidth ()
|
||||
{
|
||||
return _bounds.width;
|
||||
return _mirage.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,16 +36,16 @@ public class Tile implements Cloneable
|
||||
*/
|
||||
public int getHeight ()
|
||||
{
|
||||
return _bounds.height;
|
||||
return _mirage.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the tile image at the specified position in the given
|
||||
* graphics context.
|
||||
*/
|
||||
public void paint (Graphics gfx, int x, int y)
|
||||
public void paint (Graphics2D gfx, int x, int y)
|
||||
{
|
||||
gfx.drawImage(getImage(), x, y, null);
|
||||
_mirage.paint(gfx, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,22 +54,7 @@ public class Tile implements Cloneable
|
||||
*/
|
||||
public boolean hitTest (int x, int y)
|
||||
{
|
||||
return ImageUtil.hitTest(_image, _bounds.x + x, _bounds.y + y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image used to render this tile, if access to that image
|
||||
* can be obtained. The tile must have been created with a {@link
|
||||
* BufferedImage} and derived classes may refuse to implement this
|
||||
* function if they do special stuff that hampers their ability to
|
||||
* return a single image describing the tile.
|
||||
*/
|
||||
public Image getImage ()
|
||||
{
|
||||
if (_subimage == null) {
|
||||
createSubImage();
|
||||
}
|
||||
return _subimage;
|
||||
return _mirage.hitTest(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,18 +87,10 @@ public class Tile implements Cloneable
|
||||
*/
|
||||
protected void toString (StringBuffer buf)
|
||||
{
|
||||
buf.append("srcimg=").append(_image.getClass().getName());
|
||||
buf.append("[").append(_image.getWidth(null)).append("x");
|
||||
buf.append(_image.getHeight(null)).append("]");
|
||||
buf.append(", bounds=").append(StringUtil.toString(_bounds));
|
||||
buf.append(_mirage.getWidth()).append("x");
|
||||
buf.append(_mirage.getHeight());
|
||||
}
|
||||
|
||||
/** Our tileset image. */
|
||||
protected Image _image;
|
||||
|
||||
/** Our cropped tileset image. */
|
||||
protected Image _subimage;
|
||||
|
||||
/** The bounds of the tile image within the tileset image. */
|
||||
protected Rectangle _bounds;
|
||||
protected Mirage _mirage;
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
//
|
||||
// $Id: TileException.java,v 1.1 2001/10/11 00:41:26 shaper Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
/**
|
||||
* Thrown when an error occurs while working with tiles.
|
||||
*/
|
||||
public class TileException extends Exception
|
||||
{
|
||||
public TileException (String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
//
|
||||
// $Id: TileIcon.java,v 1.1 2002/05/06 18:08:32 mdb Exp $
|
||||
// $Id: TileIcon.java,v 1.2 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Graphics;
|
||||
|
||||
import javax.swing.Icon;
|
||||
@@ -25,7 +26,7 @@ public class TileIcon implements Icon
|
||||
// documentation inherited from interface
|
||||
public void paintIcon (Component c, Graphics g, int x, int y)
|
||||
{
|
||||
_tile.paint(g, x, y);
|
||||
_tile.paint((Graphics2D)g, x, y);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
//
|
||||
// $Id: TileManager.java,v 1.26 2003/01/08 04:09:02 mdb Exp $
|
||||
// $Id: TileManager.java,v 1.27 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.samskivert.io.PersistenceException;
|
||||
import com.samskivert.util.HashIntMap;
|
||||
import com.samskivert.util.IntTuple;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.image.Colorization;
|
||||
import com.threerings.media.image.ImageDataProvider;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.Mirage;
|
||||
import com.samskivert.util.LRUHashMap;
|
||||
|
||||
/**
|
||||
* The tile manager provides a simplified interface for retrieving and
|
||||
@@ -27,17 +35,8 @@ import com.threerings.media.image.ImageManager;
|
||||
* Loading tilesets from a repository supports games with vast numbers of
|
||||
* tiles to which more tiles may be added on the fly (think the tiles for
|
||||
* an isometric-display graphical MUD).
|
||||
*
|
||||
* <p> When the tile manager is used to load tiles via the tileset
|
||||
* repository, it caches the resulting tile instance so that they can be
|
||||
* fetched again without rebuilding the tile image. Tilesets that are
|
||||
* fetched by hand are not cached and it is assumed that the requesting
|
||||
* application will cache the tile objects itself (probably by retaining
|
||||
* references directly to the tile instances in which it is interested).
|
||||
* The tile creation process is not hugely expensive, but does involve
|
||||
* extracting the tile image from the larger tileset image.
|
||||
*/
|
||||
public class TileManager implements ImageProvider
|
||||
public class TileManager
|
||||
{
|
||||
/**
|
||||
* Creates a tile manager and provides it with a reference to the
|
||||
@@ -48,8 +47,8 @@ public class TileManager implements ImageProvider
|
||||
*/
|
||||
public TileManager (ImageManager imgr)
|
||||
{
|
||||
// keep this guy around for later
|
||||
_imgr = imgr;
|
||||
_defaultProvider = new IMImageProvider(_imgr, (String)null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,13 +58,7 @@ public class TileManager implements ImageProvider
|
||||
public UniformTileSet loadTileSet (
|
||||
String imgPath, int count, int width, int height)
|
||||
{
|
||||
UniformTileSet uts = new UniformTileSet();
|
||||
uts.setImageProvider(this);
|
||||
uts.setImagePath(imgPath);
|
||||
uts.setTileCount(count);
|
||||
uts.setWidth(width);
|
||||
uts.setHeight(height);
|
||||
return uts;
|
||||
return loadCachedTileSet("", imgPath, count, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,15 +66,40 @@ public class TileManager implements ImageProvider
|
||||
* specified resource set) with the specified metadata parameters.
|
||||
*/
|
||||
public UniformTileSet loadTileSet (
|
||||
final String rset, String imgPath, int count, int width, int height)
|
||||
String rset, String imgPath, int count, int width, int height)
|
||||
{
|
||||
UniformTileSet uts = loadTileSet(imgPath, count, width, height);
|
||||
// load up the image data from the image manager
|
||||
uts.setImageProvider(new ImageProvider() {
|
||||
public Image loadImage (String path) throws IOException {
|
||||
return _imgr.getImage(rset, path);
|
||||
UniformTileSet uts = loadCachedTileSet(
|
||||
rset, imgPath, count, width, height);
|
||||
uts.setImageProvider(getImageProvider(rset));
|
||||
return uts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an image provider that will load images from the specified
|
||||
* resource set.
|
||||
*/
|
||||
public ImageProvider getImageProvider (String rset)
|
||||
{
|
||||
return new IMImageProvider(_imgr, rset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to load and cache tilesets loaded via {@link #loadTileSet}.
|
||||
*/
|
||||
protected UniformTileSet loadCachedTileSet (
|
||||
String bundle, String imgPath, int count, int width, int height)
|
||||
{
|
||||
String key = bundle + "::" + imgPath;
|
||||
UniformTileSet uts = (UniformTileSet)_handcache.get(key);
|
||||
if (uts == null) {
|
||||
uts = new UniformTileSet();
|
||||
uts.setImageProvider(_defaultProvider);
|
||||
uts.setImagePath(imgPath);
|
||||
uts.setTileCount(count);
|
||||
uts.setWidth(width);
|
||||
uts.setHeight(height);
|
||||
_handcache.put(key, uts);
|
||||
}
|
||||
});
|
||||
return uts;
|
||||
}
|
||||
|
||||
@@ -122,20 +140,49 @@ public class TileManager implements ImageProvider
|
||||
}
|
||||
|
||||
try {
|
||||
TileSet set = (TileSet)_cache.get(tileSetId);
|
||||
TileSet set = (TileSet)_setcache.get(tileSetId);
|
||||
if (set == null) {
|
||||
set = _setrep.getTileSet(tileSetId);
|
||||
_cache.put(tileSetId, set);
|
||||
_setcache.put(tileSetId, set);
|
||||
}
|
||||
return set;
|
||||
|
||||
} catch (PersistenceException pe) {
|
||||
Log.warning("Unable to load tileset [id=" + tileSetId +
|
||||
Log.warning("Failure loading tileset [id=" + tileSetId +
|
||||
", error=" + pe + "].");
|
||||
throw new NoSuchTileSetException(tileSetId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tileset with the specified name.
|
||||
*
|
||||
* @throws NoSuchTileSetException if no tileset with the specified
|
||||
* name is available via our configured tile set repository.
|
||||
*/
|
||||
public TileSet getTileSet (String name)
|
||||
throws NoSuchTileSetException
|
||||
{
|
||||
// make sure we have a repository configured
|
||||
if (_setrep == null) {
|
||||
throw new NoSuchTileSetException(name);
|
||||
}
|
||||
|
||||
try {
|
||||
TileSet set = (TileSet)_byname.get(name);
|
||||
if (set == null) {
|
||||
set = _setrep.getTileSet(name);
|
||||
_byname.put(name, set);
|
||||
}
|
||||
return set;
|
||||
|
||||
} catch (PersistenceException pe) {
|
||||
Log.warning("Failure loading tileset [name=" + name +
|
||||
", error=" + pe + "].");
|
||||
throw new NoSuchTileSetException(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Tile} object from the specified tileset at the
|
||||
* specified index.
|
||||
@@ -152,20 +199,21 @@ public class TileManager implements ImageProvider
|
||||
return set.getTile(tileIndex);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Image loadImage (String path)
|
||||
throws IOException
|
||||
{
|
||||
// load up the image data from the resource manager
|
||||
return _imgr.getImage(path);
|
||||
}
|
||||
|
||||
/** The entity through which we decode and cache images. */
|
||||
protected ImageManager _imgr;
|
||||
|
||||
/** Cache of tilesets that have been requested thus far. */
|
||||
protected HashIntMap _cache = new HashIntMap();
|
||||
protected HashIntMap _setcache = new HashIntMap();
|
||||
|
||||
/** A cache of tilesets that have been loaded by hand. */
|
||||
protected HashMap _handcache = new HashMap();
|
||||
|
||||
/** A mapping from tileset name to tileset. */
|
||||
protected HashMap _byname = new HashMap();
|
||||
|
||||
/** The tile set repository. */
|
||||
protected TileSetRepository _setrep;
|
||||
|
||||
/** Used to load tileset images from the default resource source. */
|
||||
protected ImageProvider _defaultProvider;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// $Id: TileMultiFrameImage.java,v 1.1 2002/09/17 20:39:03 mdb Exp $
|
||||
// $Id: TileMultiFrameImage.java,v 1.2 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.util.MultiFrameImage;
|
||||
@@ -32,52 +32,25 @@ public class TileMultiFrameImage implements MultiFrameImage
|
||||
// documentation inherited from interface
|
||||
public int getWidth (int index)
|
||||
{
|
||||
try {
|
||||
return _source.getTile(index).getWidth();
|
||||
} catch (NoSuchTileException nste) {
|
||||
Log.warning("Eh? Tile set reported 'no such tile' " +
|
||||
"[tcount=" + _source.getTileCount() +
|
||||
", tindex=" + index + "].");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int getHeight (int index)
|
||||
{
|
||||
try {
|
||||
return _source.getTile(index).getHeight();
|
||||
} catch (NoSuchTileException nste) {
|
||||
Log.warning("Eh? Tile set reported 'no such tile' " +
|
||||
"[tcount=" + _source.getTileCount() +
|
||||
", tindex=" + index + "].");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void paintFrame (Graphics g, int index, int x, int y)
|
||||
public void paintFrame (Graphics2D g, int index, int x, int y)
|
||||
{
|
||||
try {
|
||||
_source.getTile(index).paint(g, x, y);
|
||||
} catch (NoSuchTileException nste) {
|
||||
Log.warning("Eh? Tile set reported 'no such tile' " +
|
||||
"[tcount=" + _source.getTileCount() +
|
||||
", tindex=" + index + "].");
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean hitTest (int index, int x, int y)
|
||||
{
|
||||
try {
|
||||
return _source.getTile(index).hitTest(x, y);
|
||||
} catch (NoSuchTileException nste) {
|
||||
Log.warning("Eh? Tile set reported 'no such tile' " +
|
||||
"[tcount=" + _source.getTileCount() +
|
||||
", tindex=" + index + "].");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected TileSet _source;
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
//
|
||||
// $Id: TileSet.java,v 1.35 2003/01/08 04:09:02 mdb Exp $
|
||||
// $Id: TileSet.java,v 1.36 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.samskivert.util.ConfigUtil;
|
||||
import com.samskivert.util.LRUHashMap;
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.samskivert.util.Tuple;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.image.Colorization;
|
||||
import com.threerings.media.image.ImageUtil;
|
||||
import com.threerings.media.image.Mirage;
|
||||
|
||||
/**
|
||||
* A tileset stores information on a single logical set of tiles. It
|
||||
@@ -70,10 +69,6 @@ public abstract class TileSet
|
||||
public void setImagePath (String imagePath)
|
||||
{
|
||||
_imagePath = imagePath;
|
||||
|
||||
// clear out any reference to a loaded image and cached tiles
|
||||
_tilesetImg = null;
|
||||
_tiles = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,14 +85,16 @@ public abstract class TileSet
|
||||
public abstract int getTileCount ();
|
||||
|
||||
/**
|
||||
* Creates a copy of this tileset with the supplied colorizations
|
||||
* applied to its source image.
|
||||
* Creates a copy of this tileset which will apply the supplied
|
||||
* colorizations to its tileset image when creating tiles.
|
||||
*/
|
||||
public TileSet cloneColorized (Colorization[] zations)
|
||||
public TileSet clone (Colorization[] zations)
|
||||
{
|
||||
TileSet tset = null;
|
||||
try {
|
||||
tset = (TileSet)clone();
|
||||
TileSet tset = (TileSet)clone();
|
||||
tset._zations = zations;
|
||||
return tset;
|
||||
|
||||
} catch (CloneNotSupportedException cnse) {
|
||||
Log.warning("Unable to clone tileset prior to colorization " +
|
||||
"[tset=" + this +
|
||||
@@ -105,37 +102,6 @@ public abstract class TileSet
|
||||
", error=" + cnse + "].");
|
||||
return null;
|
||||
}
|
||||
|
||||
// make sure the tileset was able to load its image
|
||||
Image timg = tset.getTileSetImage();
|
||||
if (timg == null) {
|
||||
Log.warning("Failed to load tileset image in preparation " +
|
||||
"for colorization [tset=" + tset + "].");
|
||||
// return the uncolorized tileset since it has no freaking
|
||||
// source image anyway
|
||||
return tset;
|
||||
|
||||
} else if (!(timg instanceof BufferedImage)) {
|
||||
Log.warning("Can't recolor tileset with non-buffered " +
|
||||
"image source [source=" + timg + "].");
|
||||
return tset;
|
||||
}
|
||||
|
||||
// create the recolored image and update the tileset
|
||||
tset._tilesetImg =
|
||||
ImageUtil.recolorImage((BufferedImage)timg, zations);
|
||||
|
||||
return tset;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Object clone ()
|
||||
throws CloneNotSupportedException
|
||||
{
|
||||
TileSet dup = (TileSet)super.clone();
|
||||
// clear out the tileset cache
|
||||
dup._tiles = null;
|
||||
return dup;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,35 +136,81 @@ public abstract class TileSet
|
||||
public Tile getTile (int tileIndex)
|
||||
throws NoSuchTileException
|
||||
{
|
||||
int tcount = getTileCount();
|
||||
checkTileIndex(tileIndex);
|
||||
|
||||
// bail if there's no such tile
|
||||
if (tileIndex < 0 || tileIndex >= tcount) {
|
||||
throw new NoSuchTileException(tileIndex);
|
||||
}
|
||||
|
||||
// create our tile cache array if necessary
|
||||
// create our tile cache if necessary
|
||||
if (_tiles == null) {
|
||||
_tiles = new Tile[tcount];
|
||||
int tcsize = ConfigUtil.getSystemProperty(
|
||||
"narya.media.tile.cache_size", DEFAULT_TILE_CACHE_SIZE);
|
||||
Log.debug("Creating tile cache [size=" + tcsize + "].");
|
||||
_tiles = new LRUHashMap(tcsize);
|
||||
}
|
||||
|
||||
// fill in the cache if necessary
|
||||
if (_tiles[tileIndex] == null) {
|
||||
// get our tileset image
|
||||
Image tsimg = getTileSetImage();
|
||||
if (tsimg == null) {
|
||||
// we already logged an error, so we can just freak out
|
||||
throw new NoSuchTileException(tileIndex);
|
||||
}
|
||||
|
||||
// create, initialize and cache the tile object
|
||||
Tile tile = createTile(tileIndex, tsimg);
|
||||
// fetch and cache the tile
|
||||
Tuple key = new Tuple(this, new Integer(tileIndex));
|
||||
Tile tile = (Tile)_tiles.get(key);
|
||||
if (tile == null) {
|
||||
// create and initialize the tile object
|
||||
tile = createTile(tileIndex, getTileMirage(tileIndex));
|
||||
initTile(tile);
|
||||
// _tiles[tileIndex] = tile;
|
||||
_tiles.put(key, tile);
|
||||
}
|
||||
|
||||
return tile;
|
||||
}
|
||||
|
||||
return _tiles[tileIndex];
|
||||
/**
|
||||
* Returns the entire, raw, uncut, unprepared tileset source image.
|
||||
*/
|
||||
public BufferedImage getTileSetImage ()
|
||||
{
|
||||
return _improv.getTileSetImage(_imagePath, _zations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw (unprepared) image that would be used by the tile
|
||||
* at the specified index.
|
||||
*/
|
||||
public BufferedImage getTileImage (int tileIndex)
|
||||
throws NoSuchTileException
|
||||
{
|
||||
checkTileIndex(tileIndex);
|
||||
Rectangle bounds = computeTileBounds(tileIndex);
|
||||
BufferedImage timg = getTileSetImage();
|
||||
return timg.getSubimage(bounds.x, bounds.y,
|
||||
bounds.width, bounds.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a prepared version of the image that would be used by the
|
||||
* tile at the specified index. Because tilesets are often used simply
|
||||
* to provide access to a collection of uniform images, this method is
|
||||
* provided to bypass the creation of a {@link Tile} object when all
|
||||
* that is desired is access to the underlying image.
|
||||
*/
|
||||
public Mirage getTileMirage (int tileIndex)
|
||||
throws NoSuchTileException
|
||||
{
|
||||
checkTileIndex(tileIndex);
|
||||
Rectangle bounds = computeTileBounds(tileIndex);
|
||||
if (_improv == null) {
|
||||
Log.warning("Aiya! Tile set missing image provider " +
|
||||
"[path=" + _imagePath + "].");
|
||||
}
|
||||
return _improv.getTileImage(_imagePath, bounds, _zations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to ensure that the specified tile index is valid.
|
||||
*/
|
||||
protected void checkTileIndex (int tileIndex)
|
||||
throws NoSuchTileException
|
||||
{
|
||||
// bail if there's no such tile
|
||||
int tcount = getTileCount();
|
||||
if (tileIndex < 0 || tileIndex >= tcount) {
|
||||
throw new NoSuchTileException(tileIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,25 +222,20 @@ public abstract class TileSet
|
||||
*
|
||||
* @param tileIndex the index of the tile whose bounds are to be
|
||||
* computed.
|
||||
* @param tilesetImage the tileset image that contains the imagery for
|
||||
* the tile in question.
|
||||
*/
|
||||
protected abstract Rectangle computeTileBounds (
|
||||
int tileIndex, Image tilesetImage);
|
||||
protected abstract Rectangle computeTileBounds (int tileIndex);
|
||||
|
||||
/**
|
||||
* Creates a tile for the specified tile index.
|
||||
*
|
||||
* @param tileIndex the index of the tile to be created.
|
||||
* @param tilesetImage the tileset image that contains the imagery for
|
||||
* the tile to be created.
|
||||
* @param image the tile image in the form of a {@link Mirage}.
|
||||
*
|
||||
* @return a configured tile.
|
||||
*/
|
||||
protected Tile createTile (int tileIndex, Image tilesetImage)
|
||||
protected Tile createTile (int tileIndex, Mirage image)
|
||||
{
|
||||
return new Tile(tilesetImage,
|
||||
computeTileBounds(tileIndex, tilesetImage));
|
||||
return new Tile(image);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -243,42 +250,6 @@ public abstract class TileSet
|
||||
// nothing for now
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tileset image (which is loaded if it has not yet been
|
||||
* loaded). Generally this is not called by external entities, rather
|
||||
* {@link #getTile} is used and the image rendered by rendering the
|
||||
* tile.
|
||||
*
|
||||
* @return the tileset image or null if an error occurred loading the
|
||||
* image.
|
||||
*/
|
||||
public Image getTileSetImage ()
|
||||
{
|
||||
// return it straight away if it's already loaded
|
||||
if (_tilesetImg != null) {
|
||||
return _tilesetImg;
|
||||
}
|
||||
|
||||
// load up the tileset image via the image provider
|
||||
try {
|
||||
_tilesetImg = _improv.loadImage(_imagePath);
|
||||
|
||||
// HACKOLA: if we're a vessel tileset, colorize ourselves
|
||||
if (_name != null && (this instanceof ObjectTileSet) &&
|
||||
_name.indexOf("Vessel") != -1) {
|
||||
_tilesetImg = ImageUtil.recolorImage(
|
||||
(BufferedImage)_tilesetImg, ZATIONS);
|
||||
}
|
||||
|
||||
} catch (IOException ioe) {
|
||||
Log.warning("Failed to retrieve tileset image " +
|
||||
"[name=" + _name + ", path=" + _imagePath +
|
||||
", error=" + ioe + "].");
|
||||
}
|
||||
|
||||
return _tilesetImg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a string representation of the tileset information.
|
||||
*/
|
||||
@@ -307,18 +278,12 @@ public abstract class TileSet
|
||||
/** The tileset name. */
|
||||
protected String _name;
|
||||
|
||||
/** A sparse array containing the tiles that have been requested from
|
||||
* this tileset. */
|
||||
protected transient Tile[] _tiles;
|
||||
/** Colorizations to be applied to tiles created from this tileset. */
|
||||
protected transient Colorization[] _zations;
|
||||
|
||||
/** The entity from which we obtain our tile image. */
|
||||
protected transient ImageProvider _improv;
|
||||
|
||||
/** The image containing all tile images for this set. This is private
|
||||
* because it should be accessed via {@link #getTileSetImage} even by
|
||||
* derived classes. */
|
||||
private transient Image _tilesetImg;
|
||||
|
||||
/** Increase this value when object's serialized state is impacted by
|
||||
* a class change (modification of fields, inheritance). */
|
||||
private static final long serialVersionUID = 1;
|
||||
@@ -332,4 +297,10 @@ public abstract class TileSet
|
||||
new float[] { .1f, .3f, 0.6f },
|
||||
new float[] { .71f, 0f, .07f }),
|
||||
};
|
||||
|
||||
/** A weak cache of our tiles. */
|
||||
protected static LRUHashMap _tiles;
|
||||
|
||||
/** The default tile cache size. */
|
||||
protected static final int DEFAULT_TILE_CACHE_SIZE = 500;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
//
|
||||
// $Id: TileSetRepository.java,v 1.3 2001/11/29 00:12:11 mdb Exp $
|
||||
// $Id: TileSetRepository.java,v 1.4 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import java.util.Iterator;
|
||||
import com.samskivert.io.PersistenceException;
|
||||
|
||||
import com.threerings.media.image.ImageDataProvider;
|
||||
|
||||
/**
|
||||
* The tileset repository interface should be implemented by classes that
|
||||
* provide access to tilesets keyed on a unique tileset identifier. The
|
||||
@@ -28,7 +30,9 @@ public interface TileSetRepository
|
||||
throws PersistenceException;
|
||||
|
||||
/**
|
||||
* Returns the {@link TileSet} with the specified tile set identifier.
|
||||
* Returns the {@link TileSet} with the specified tile set
|
||||
* identifier. The repository is responsible for configuring the tile
|
||||
* set with an image provider.
|
||||
*
|
||||
* @exception NoSuchTileSetException thrown if no tileset exists with
|
||||
* the specified identifier.
|
||||
@@ -37,4 +41,17 @@ public interface TileSetRepository
|
||||
*/
|
||||
public TileSet getTileSet (int tileSetId)
|
||||
throws NoSuchTileSetException, PersistenceException;
|
||||
|
||||
/**
|
||||
* Returns the {@link TileSet} with the specified tile set name. The
|
||||
* repository is responsible for configuring the tile set with an
|
||||
* image provider.
|
||||
*
|
||||
* @exception NoSuchTileSetException thrown if no tileset exists with
|
||||
* the specified name.
|
||||
* @exception PersistenceException thrown if an error occurs
|
||||
* communicating with the underlying persistence mechanism.
|
||||
*/
|
||||
public TileSet getTileSet (String setName)
|
||||
throws NoSuchTileSetException, PersistenceException;
|
||||
}
|
||||
|
||||
@@ -1,40 +1,13 @@
|
||||
//
|
||||
// $Id: TileUtil.java,v 1.3 2002/05/06 18:08:32 mdb Exp $
|
||||
// $Id: TileUtil.java,v 1.4 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
|
||||
/**
|
||||
* Miscellaneous utility routines for working with tiles.
|
||||
*/
|
||||
public class TileUtil
|
||||
{
|
||||
/**
|
||||
* Returns the image associated with the given tile from the given
|
||||
* tile manager, or null if an error occurred. Any exceptions that
|
||||
* occur are logged.
|
||||
*
|
||||
* @param tilemgr the tile manager via which the tile should be
|
||||
* fetched.
|
||||
* @param tileSetId the id of the tileset from which to fetch the
|
||||
* tile.
|
||||
* @param tileIndex the index of the tile to be fetched.
|
||||
*/
|
||||
public static Tile getTile (
|
||||
TileManager tilemgr, int tileSetId, int tileIndex)
|
||||
{
|
||||
try {
|
||||
TileSet set = tilemgr.getTileSet(tileSetId);
|
||||
return set.getTile(tileIndex);
|
||||
|
||||
} catch (TileException te) {
|
||||
Log.warning("Error retrieving tile [tsid=" + tileSetId +
|
||||
", tidx=" + tileIndex + ", error=" + te + "].");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a fully-qualified tileid given the supplied tileset id
|
||||
* and tile index. This fully-qualified id can be used to fetch the
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
//
|
||||
// $Id: TrimmedObjectTileSet.java,v 1.2 2003/01/12 01:19:58 shaper Exp $
|
||||
// $Id: TrimmedObjectTileSet.java,v 1.3 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -12,6 +11,7 @@ import java.io.OutputStream;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.image.Mirage;
|
||||
import com.threerings.media.tile.util.TileSetTrimmer;
|
||||
|
||||
/**
|
||||
@@ -30,16 +30,15 @@ public class TrimmedObjectTileSet extends TileSet
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected Rectangle computeTileBounds (int tileIndex, Image tilesetImage)
|
||||
protected Rectangle computeTileBounds (int tileIndex)
|
||||
{
|
||||
// N/A
|
||||
return null;
|
||||
return _bounds[tileIndex];
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected Tile createTile (int tileIndex, Image tilesetImage)
|
||||
protected Tile createTile (int tileIndex, Mirage tileImage)
|
||||
{
|
||||
ObjectTile tile = new ObjectTile(tilesetImage, _bounds[tileIndex]);
|
||||
ObjectTile tile = new ObjectTile(tileImage);
|
||||
tile.setBase(_ometrics[tileIndex].width, _ometrics[tileIndex].height);
|
||||
tile.setOrigin(_ometrics[tileIndex].x, _ometrics[tileIndex].y);
|
||||
return tile;
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
//
|
||||
// $Id: TrimmedTile.java,v 1.4 2003/01/08 04:09:02 mdb Exp $
|
||||
// $Id: TrimmedTile.java,v 1.5 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.media.image.ImageUtil;
|
||||
import com.threerings.media.image.Mirage;
|
||||
|
||||
/**
|
||||
* Behaves just like a regular tile, but contains a "trimmed" image which
|
||||
@@ -28,61 +24,48 @@ public class TrimmedTile extends Tile
|
||||
*
|
||||
* @param tilesetSource the tileset image that contains our trimmed
|
||||
* tile image.
|
||||
* @param bounds contains the width and height of the
|
||||
* @param tbounds contains the width and height of the
|
||||
* <em>untrimmed</em> tile, but the x and y offset of the
|
||||
* <em>trimmed</em> tile image in the supplied tileset source image.
|
||||
* @param tbounds the bounds of the trimmed image in the coordinate
|
||||
* system defined by the untrimmed image.
|
||||
* <em>trimmed</em> tile image in the original untrimmed tile image.
|
||||
*/
|
||||
public TrimmedTile (Image image, Rectangle bounds, Rectangle tbounds)
|
||||
public TrimmedTile (Mirage image, Rectangle tbounds)
|
||||
{
|
||||
super(image, bounds);
|
||||
super(image);
|
||||
_tbounds = tbounds;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void paint (Graphics gfx, int x, int y)
|
||||
public int getWidth ()
|
||||
{
|
||||
if (_subimage == null) {
|
||||
createSubImage();
|
||||
}
|
||||
gfx.drawImage(_subimage, x + _tbounds.x, y + _tbounds.y, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounds of the trimmed image within the coordinate
|
||||
* system defined by the complete virtual tile. The returned rectangle
|
||||
* should <em>not</em> be modified.
|
||||
*/
|
||||
public Rectangle getTrimmedBounds ()
|
||||
{
|
||||
return _tbounds;
|
||||
return _tbounds.width;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Image getImage ()
|
||||
public int getHeight ()
|
||||
{
|
||||
String errmsg = "Can't convert trimmed tile to image " +
|
||||
"[tile=" + this + "].";
|
||||
throw new RuntimeException(errmsg);
|
||||
return _tbounds.height;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void paint (Graphics2D gfx, int x, int y)
|
||||
{
|
||||
_mirage.paint(gfx, x + _tbounds.x, y + _tbounds.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills in the bounds of the trimmed image within the coordinate
|
||||
* system defined by the complete virtual tile.
|
||||
*/
|
||||
public void getTrimmedBounds (Rectangle tbounds)
|
||||
{
|
||||
tbounds.setBounds(_tbounds.x, _tbounds.y,
|
||||
_mirage.getWidth(), _mirage.getHeight());
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public boolean hitTest (int x, int y)
|
||||
{
|
||||
return ImageUtil.hitTest(_image, _bounds.x + x, _bounds.y + y);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected void createSubImage ()
|
||||
{
|
||||
if (_image instanceof BufferedImage) {
|
||||
_subimage = ImageUtil.getSubimage(_image, _bounds.x, _bounds.y,
|
||||
_tbounds.width, _tbounds.height);
|
||||
} else {
|
||||
String errmsg = "Can't obtain tile image [tile=" + this + "].";
|
||||
throw new RuntimeException(errmsg);
|
||||
}
|
||||
return super.hitTest(x - _tbounds.x, y - _tbounds.y);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
@@ -91,7 +74,6 @@ public class TrimmedTile extends Tile
|
||||
buf.append(", tbounds=").append(StringUtil.toString(_tbounds));
|
||||
}
|
||||
|
||||
/** The dimensions of the trimmed image in the coordinate space
|
||||
* defined by the untrimmed image. */
|
||||
/** Our extra trimmed image dimension information. */
|
||||
protected Rectangle _tbounds;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
//
|
||||
// $Id: TrimmedTileSet.java,v 1.5 2002/08/19 22:58:15 mdb Exp $
|
||||
// $Id: TrimmedTileSet.java,v 1.6 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.threerings.media.image.Mirage;
|
||||
import com.threerings.media.tile.util.TileSetTrimmer;
|
||||
|
||||
/**
|
||||
@@ -24,17 +24,15 @@ public class TrimmedTileSet extends TileSet
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected Rectangle computeTileBounds (int tileIndex, Image tilesetImage)
|
||||
protected Rectangle computeTileBounds (int tileIndex)
|
||||
{
|
||||
// N/A
|
||||
return null;
|
||||
return _obounds[tileIndex];
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected Tile createTile (int tileIndex, Image tilesetImage)
|
||||
protected Tile createTile (int tileIndex, Mirage image)
|
||||
{
|
||||
return new TrimmedTile(
|
||||
tilesetImage, _obounds[tileIndex], _tbounds[tileIndex]);
|
||||
return new TrimmedTile(image, _tbounds[tileIndex]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,23 +49,13 @@ public class TrimmedTileSet extends TileSet
|
||||
final TrimmedTileSet tset = new TrimmedTileSet();
|
||||
tset.setName(source.getName());
|
||||
int tcount = source.getTileCount();
|
||||
tset._tbounds = new Rectangle[tcount];
|
||||
tset._obounds = new Rectangle[tcount];
|
||||
|
||||
// grab the dimensions of the original tiles
|
||||
tset._obounds = new Rectangle[tcount];
|
||||
for (int ii = 0; ii < tcount; ii++) {
|
||||
try {
|
||||
Tile tile = source.getTile(ii);
|
||||
tset._obounds[ii] = new Rectangle();
|
||||
tset._obounds[ii].width = tile.getWidth();
|
||||
tset._obounds[ii].height = tile.getHeight();
|
||||
} catch (NoSuchTileException nste) {
|
||||
String errmsg = "Urk! TileSet is ill-behaved. " +
|
||||
"Claimed to have " + tcount + " tiles, but choked when " +
|
||||
"we asked for tile " + ii + " [tset=" + source + "].";
|
||||
throw new RuntimeException(errmsg);
|
||||
tset._tbounds[ii] = source.computeTileBounds(ii);
|
||||
}
|
||||
}
|
||||
tset._tbounds = new Rectangle[tcount];
|
||||
|
||||
// create the trimmed tileset image
|
||||
TileSetTrimmer.TrimMetricsReceiver tmr =
|
||||
@@ -75,10 +63,10 @@ public class TrimmedTileSet extends TileSet
|
||||
public void trimmedTile (int tileIndex, int imageX, int imageY,
|
||||
int trimX, int trimY,
|
||||
int trimWidth, int trimHeight) {
|
||||
tset._obounds[tileIndex].x = imageX;
|
||||
tset._obounds[tileIndex].y = imageY;
|
||||
tset._tbounds[tileIndex] =
|
||||
new Rectangle(trimX, trimY, trimWidth, trimHeight);
|
||||
tset._tbounds[tileIndex].x = trimX;
|
||||
tset._tbounds[tileIndex].y = trimY;
|
||||
tset._obounds[tileIndex] =
|
||||
new Rectangle(imageX, imageY, trimWidth, trimHeight);
|
||||
}
|
||||
};
|
||||
TileSetTrimmer.trimTileSet(source, destImage, tmr);
|
||||
@@ -86,11 +74,11 @@ public class TrimmedTileSet extends TileSet
|
||||
return tset;
|
||||
}
|
||||
|
||||
/** The width and height of the untrimmed tile, and the x and y offset
|
||||
/** The width and height of the trimmed tile, and the x and y offset
|
||||
* of the trimmed image within our tileset image. */
|
||||
protected Rectangle[] _obounds;
|
||||
|
||||
/** The width and height of the trimmed image and the x and y offset
|
||||
/** The width and height of the untrimmed image and the x and y offset
|
||||
* within the untrimmed image at which the trimmed image should be
|
||||
* rendered. */
|
||||
protected Rectangle[] _tbounds;
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
//
|
||||
// $Id: UniformTileSet.java,v 1.10 2003/01/08 04:09:02 mdb Exp $
|
||||
// $Id: UniformTileSet.java,v 1.11 2003/01/13 22:49:46 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.image.ImageUtil;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
/**
|
||||
* A uniform tileset is one that is composed of tiles that are all the
|
||||
@@ -65,28 +62,13 @@ public class UniformTileSet extends TileSet
|
||||
return _height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image that would be used by the tile at the specified
|
||||
* index. Because the uniform tileset is often used simply to provide
|
||||
* access to a collection of uniform images, this method is provided
|
||||
* to bypass the creation of a {@link Tile} object when all that is
|
||||
* desired is access to the underlying image.
|
||||
*/
|
||||
public Image getTileImage (int tileIndex)
|
||||
{
|
||||
Image tsimg = getTileSetImage();
|
||||
if (tsimg == null) {
|
||||
return null;
|
||||
}
|
||||
Rectangle tb = computeTileBounds(tileIndex, tsimg);
|
||||
return ImageUtil.getSubimage(tsimg, tb.x, tb.y, tb.width, tb.height);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected Rectangle computeTileBounds (int tileIndex, Image tilesetImage)
|
||||
protected Rectangle computeTileBounds (int tileIndex)
|
||||
{
|
||||
BufferedImage tsimg = getTileSetImage();
|
||||
|
||||
// figure out from whence to crop the tile
|
||||
int tilesPerRow = tilesetImage.getWidth(null) / _width;
|
||||
int tilesPerRow = tsimg.getWidth() / _width;
|
||||
int row = tileIndex / tilesPerRow;
|
||||
int col = tileIndex % tilesPerRow;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: BundledTileSetRepository.java,v 1.8 2003/01/08 04:09:02 mdb Exp $
|
||||
// $Id: BundledTileSetRepository.java,v 1.9 2003/01/13 22:49:47 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile.bundle;
|
||||
|
||||
@@ -16,7 +16,10 @@ import com.threerings.resource.ResourceBundle;
|
||||
import com.threerings.resource.ResourceManager;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.image.ImageDataProvider;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
|
||||
import com.threerings.media.tile.IMImageProvider;
|
||||
import com.threerings.media.tile.NoSuchTileSetException;
|
||||
import com.threerings.media.tile.TileSet;
|
||||
import com.threerings.media.tile.TileSetRepository;
|
||||
@@ -35,13 +38,13 @@ public class BundledTileSetRepository
|
||||
*
|
||||
* @param rmgr the resource manager from which to obtain our resource
|
||||
* set.
|
||||
* @param imgr the image manager that we'll use to decode and cache
|
||||
* images.
|
||||
* @param imgr the image manager through which we will configure the
|
||||
* tile sets to load their images.
|
||||
* @param name the name of the resource set from which we will be
|
||||
* loading our tile data.
|
||||
*/
|
||||
public BundledTileSetRepository (
|
||||
ResourceManager rmgr, ImageManager imgr, String name)
|
||||
public BundledTileSetRepository (ResourceManager rmgr, ImageManager imgr,
|
||||
String name)
|
||||
{
|
||||
// first we obtain the resource set from which we will load up our
|
||||
// tileset bundles
|
||||
@@ -64,7 +67,7 @@ public class BundledTileSetRepository
|
||||
// unserialize our tileset bundle
|
||||
TileSetBundle tsb = BundleUtil.extractBundle(rbundles[i]);
|
||||
// initialize it and add it to the list
|
||||
tsb.init(rbundles[i], imgr);
|
||||
tsb.init(rbundles[i]);
|
||||
tbundles.add(tsb);
|
||||
|
||||
} catch (Exception e) {
|
||||
@@ -78,43 +81,15 @@ public class BundledTileSetRepository
|
||||
// finally create one big fat array of all of the tileset bundles
|
||||
_bundles = new TileSetBundle[tbundles.size()];
|
||||
tbundles.toArray(_bundles);
|
||||
|
||||
// create image providers for our bundles
|
||||
_improvs = new IMImageProvider[_bundles.length];
|
||||
for (int ii = 0; ii < _bundles.length; ii++) {
|
||||
_improvs[ii] = new IMImageProvider(imgr, _bundles[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for the tileset with the specified name, which must reside
|
||||
* in a tileset bundle identified by the supplied bundle identifying
|
||||
* string.
|
||||
*
|
||||
* @param bundleId a string that will be substring matched against the
|
||||
* names of all known tileset bundles. Only bundles whose bundle file
|
||||
* path contains this string will be searched.
|
||||
* @param setName the name of the tileset to be located.
|
||||
*
|
||||
* @return The first tileset matching the supplied parameters or null
|
||||
* if no matching tileset could be found.
|
||||
*/
|
||||
public TileSet locateTileSet (String bundleId, String setName)
|
||||
{
|
||||
int bcount = _bundles.length;
|
||||
for (int ii = 0; ii < bcount; ii++) {
|
||||
TileSetBundle tsb = _bundles[ii];
|
||||
// skip non-matching bundles
|
||||
if (tsb.getSource().getPath().indexOf(bundleId) == -1) {
|
||||
continue;
|
||||
}
|
||||
// search for the tileset in this bundle
|
||||
Iterator tsiter = tsb.enumerateTileSets();
|
||||
while (tsiter.hasNext()) {
|
||||
TileSet set = (TileSet)tsiter.next();
|
||||
if (set.getName().equals(setName)) {
|
||||
return set;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
// documentation inherited from interface
|
||||
public Iterator enumerateTileSetIds ()
|
||||
throws PersistenceException
|
||||
{
|
||||
@@ -130,7 +105,7 @@ public class BundledTileSetRepository
|
||||
});
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
// documentation inherited from interface
|
||||
public Iterator enumerateTileSets ()
|
||||
throws PersistenceException
|
||||
{
|
||||
@@ -146,7 +121,7 @@ public class BundledTileSetRepository
|
||||
});
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
// documentation inherited from interface
|
||||
public TileSet getTileSet (int tileSetId)
|
||||
throws NoSuchTileSetException, PersistenceException
|
||||
{
|
||||
@@ -155,12 +130,36 @@ public class BundledTileSetRepository
|
||||
for (int i = 0; i < blength; i++) {
|
||||
tset = _bundles[i].getTileSet(tileSetId);
|
||||
if (tset != null) {
|
||||
tset.setImageProvider(_improvs[i]);
|
||||
return tset;
|
||||
}
|
||||
}
|
||||
throw new NoSuchTileSetException(tileSetId);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public TileSet getTileSet (String setName)
|
||||
throws NoSuchTileSetException, PersistenceException
|
||||
{
|
||||
int bcount = _bundles.length;
|
||||
for (int ii = 0; ii < bcount; ii++) {
|
||||
TileSetBundle tsb = _bundles[ii];
|
||||
// search for the tileset in this bundle
|
||||
Iterator tsiter = tsb.enumerateTileSets();
|
||||
while (tsiter.hasNext()) {
|
||||
TileSet set = (TileSet)tsiter.next();
|
||||
if (set.getName().equals(setName)) {
|
||||
set.setImageProvider(_improvs[ii]);
|
||||
return set;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** An array of tileset bundles from which we obtain tilesets. */
|
||||
protected TileSetBundle[] _bundles;
|
||||
|
||||
/** Image providers for each of our tile set bundles. */
|
||||
protected IMImageProvider[] _improvs;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
//
|
||||
// $Id: TileSetBundle.java,v 1.12 2003/01/08 04:09:02 mdb Exp $
|
||||
// $Id: TileSetBundle.java,v 1.13 2003/01/13 22:49:47 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile.bundle;
|
||||
|
||||
import java.awt.Image;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.stream.FileImageInputStream;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
@@ -20,8 +22,7 @@ import com.samskivert.util.HashIntMap;
|
||||
|
||||
import com.threerings.resource.ResourceBundle;
|
||||
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.tile.ImageProvider;
|
||||
import com.threerings.media.image.ImageDataProvider;
|
||||
import com.threerings.media.tile.TileSet;
|
||||
|
||||
/**
|
||||
@@ -29,17 +30,16 @@ import com.threerings.media.tile.TileSet;
|
||||
* bundle of tilesets stored on the local filesystem.
|
||||
*/
|
||||
public class TileSetBundle extends HashIntMap
|
||||
implements Serializable, ImageProvider
|
||||
implements Serializable, ImageDataProvider
|
||||
{
|
||||
/**
|
||||
* Initializes this resource bundle with a reference to the jarfile
|
||||
* from which it was loaded and from which it can load image data. The
|
||||
* image manager will be used to decode the images.
|
||||
*/
|
||||
public void init (ResourceBundle bundle, ImageManager imgr)
|
||||
public void init (ResourceBundle bundle)
|
||||
{
|
||||
_bundle = bundle;
|
||||
_imgr = imgr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,19 +82,17 @@ public class TileSetBundle extends HashIntMap
|
||||
return values().iterator();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Image loadImage (String path)
|
||||
// documentation inherited from interface
|
||||
public String getIdent ()
|
||||
{
|
||||
return "tsb:" + _bundle.getSource();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public ImageInputStream loadImageData (String path)
|
||||
throws IOException
|
||||
{
|
||||
// obtain the image data from our jarfile
|
||||
InputStream imgin = _bundle.getResource(path);
|
||||
if (imgin == null) {
|
||||
String errmsg = "No such image in resource bundle " +
|
||||
"[bundle=" + _bundle + ", path=" + path + "].";
|
||||
throw new FileNotFoundException(errmsg);
|
||||
}
|
||||
// return _imgr.createImage(imgin);
|
||||
return ImageIO.read(imgin);
|
||||
return new FileImageInputStream(_bundle.getResourceFile(path));
|
||||
}
|
||||
|
||||
// custom serialization process
|
||||
@@ -120,7 +118,6 @@ public class TileSetBundle extends HashIntMap
|
||||
for (int i = 0; i < count; i++) {
|
||||
int tileSetId = in.readInt();
|
||||
TileSet set = (TileSet)in.readObject();
|
||||
set.setImageProvider(this);
|
||||
put(tileSetId, set);
|
||||
}
|
||||
}
|
||||
@@ -128,10 +125,7 @@ public class TileSetBundle extends HashIntMap
|
||||
/** That from which we load our tile images. */
|
||||
protected transient ResourceBundle _bundle;
|
||||
|
||||
/** We use the image manager to decode our images. */
|
||||
protected transient ImageManager _imgr;
|
||||
|
||||
/** Increase this value when object's serialized state is impacted by
|
||||
* a class change (modification of fields, inheritance). */
|
||||
private static final long serialVersionUID = 1;
|
||||
private static final long serialVersionUID = 2;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: DumpBundle.java,v 1.8 2003/01/08 04:09:02 mdb Exp $
|
||||
// $Id: DumpBundle.java,v 1.9 2003/01/13 22:49:47 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile.bundle.tools;
|
||||
|
||||
@@ -9,8 +9,6 @@ import java.util.Iterator;
|
||||
import com.threerings.resource.ResourceManager;
|
||||
import com.threerings.resource.ResourceBundle;
|
||||
|
||||
import com.threerings.media.image.ImageManager;
|
||||
|
||||
import com.threerings.media.tile.TileSet;
|
||||
import com.threerings.media.tile.bundle.BundleUtil;
|
||||
import com.threerings.media.tile.bundle.TileSetBundle;
|
||||
@@ -34,7 +32,6 @@ public class DumpBundle
|
||||
// create a resource and image manager in case they want to dump
|
||||
// the tiles
|
||||
ResourceManager rmgr = new ResourceManager("rsrc");
|
||||
ImageManager imgr = new ImageManager(rmgr, null);
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
// oh the hackery
|
||||
@@ -47,7 +44,7 @@ public class DumpBundle
|
||||
try {
|
||||
ResourceBundle bundle = new ResourceBundle(file);
|
||||
TileSetBundle tsb = BundleUtil.extractBundle(bundle);
|
||||
tsb.init(bundle, imgr);
|
||||
tsb.init(bundle);
|
||||
|
||||
Iterator tsids = tsb.enumerateTileSetIds();
|
||||
while (tsids.hasNext()) {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
//
|
||||
// $Id: TileSetBundler.java,v 1.9 2003/01/12 01:19:33 shaper Exp $
|
||||
// $Id: TileSetBundler.java,v 1.10 2003/01/13 22:49:47 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile.bundle.tools;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import java.io.File;
|
||||
@@ -31,9 +32,11 @@ import com.samskivert.io.NestableIOException;
|
||||
import com.samskivert.io.PersistenceException;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.image.Colorization;
|
||||
import com.threerings.media.image.Mirage;
|
||||
|
||||
import com.threerings.media.tile.ImageProvider;
|
||||
import com.threerings.media.tile.ObjectTileSet;
|
||||
import com.threerings.media.tile.SimpleCachingImageProvider;
|
||||
import com.threerings.media.tile.TileSet;
|
||||
import com.threerings.media.tile.TileSetIDBroker;
|
||||
import com.threerings.media.tile.TrimmedObjectTileSet;
|
||||
@@ -54,39 +57,39 @@ import com.threerings.media.tile.tools.xml.TileSetRuleSet;
|
||||
* parsers. An example configuration follows:
|
||||
*
|
||||
* <pre>
|
||||
* <bundler-config>
|
||||
* <mapping>
|
||||
* <path>bundle.tilesets.uniform</path>
|
||||
* <ruleset>
|
||||
* <bundler-config>
|
||||
* <mapping>
|
||||
* <path>bundle.tilesets.uniform</path>
|
||||
* <ruleset>
|
||||
* com.threerings.media.tile.tools.xml.UniformTileSetRuleSet
|
||||
* </ruleset>
|
||||
* </mapping>
|
||||
* <mapping>
|
||||
* <path>bundle.tilesets.object</path>
|
||||
* <ruleset>
|
||||
* </ruleset>
|
||||
* </mapping>
|
||||
* <mapping>
|
||||
* <path>bundle.tilesets.object</path>
|
||||
* <ruleset>
|
||||
* com.threerings.media.tile.tools.xml.ObjectTileSetRuleSet
|
||||
* </ruleset>
|
||||
* </mapping>
|
||||
* </bundler-config>
|
||||
* </ruleset>
|
||||
* </mapping>
|
||||
* </bundler-config>
|
||||
* </pre>
|
||||
*
|
||||
* This configuration would be used to parse a bundle description that
|
||||
* looked something like the following:
|
||||
*
|
||||
* <pre>
|
||||
* <bundle>
|
||||
* <tilesets>
|
||||
* <uniform>
|
||||
* <tileset>
|
||||
* <!-- ... -->
|
||||
* </tileset>
|
||||
* </uniform>
|
||||
* <object>
|
||||
* <tileset>
|
||||
* <!-- ... -->
|
||||
* </tileset>
|
||||
* </object>
|
||||
* </tilesets>
|
||||
* <bundle>
|
||||
* <tilesets>
|
||||
* <uniform>
|
||||
* <tileset>
|
||||
* <!-- ... -->
|
||||
* </tileset>
|
||||
* </uniform>
|
||||
* <object>
|
||||
* <tileset>
|
||||
* <!-- ... -->
|
||||
* </tileset>
|
||||
* </object>
|
||||
* </tilesets>
|
||||
* </pre>
|
||||
*
|
||||
* The class specified in the <code>ruleset</code> element must derive
|
||||
@@ -277,6 +280,14 @@ public class TileSetBundler
|
||||
Manifest manifest = new Manifest();
|
||||
JarOutputStream jar = new JarOutputStream(fout, manifest);
|
||||
|
||||
// create an image provider for loading our tileset images
|
||||
SimpleCachingImageProvider improv = new SimpleCachingImageProvider() {
|
||||
protected BufferedImage loadImage (String path)
|
||||
throws IOException {
|
||||
return ImageIO.read(new File(bundleDesc.getParent(), path));
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
// write all of the image files to the bundle, converting the
|
||||
// tilesets to trimmed tilesets in the process
|
||||
@@ -300,14 +311,8 @@ public class TileSetBundler
|
||||
if (set instanceof ObjectTileSet) {
|
||||
// set the tileset up with an image provider; we need to
|
||||
// do this so that we can trim it!
|
||||
set.setImageProvider(new ImageProvider() {
|
||||
public Image loadImage (String path)
|
||||
throws IOException {
|
||||
File source = new File(bundleDesc.getParent(),
|
||||
path);
|
||||
return ImageIO.read(source);
|
||||
}
|
||||
});
|
||||
set.setImageProvider(improv);
|
||||
|
||||
// create a trimmed object tileset, which will write
|
||||
// the trimmed tileset image to the jar output stream
|
||||
TrimmedObjectTileSet tset =
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: TileSetTrimmer.java,v 1.5 2003/01/08 04:09:03 mdb Exp $
|
||||
// $Id: TileSetTrimmer.java,v 1.6 2003/01/13 22:49:47 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile.util;
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.samskivert.util.StringUtil;
|
||||
import com.threerings.media.Log;
|
||||
|
||||
import com.threerings.media.image.ImageUtil;
|
||||
import com.threerings.media.tile.NoSuchTileException;
|
||||
import com.threerings.media.tile.Tile;
|
||||
import com.threerings.media.tile.TileSet;
|
||||
|
||||
@@ -88,17 +87,11 @@ public class TileSetTrimmer
|
||||
for (int ii = 0; ii < tcount; ii++) {
|
||||
// extract the image from the original tileset
|
||||
try {
|
||||
Tile tile = source.getTile(ii);
|
||||
timgs[ii] = (BufferedImage)tile.getImage();
|
||||
|
||||
timgs[ii] = source.getTileImage(ii);
|
||||
} catch (RasterFormatException rfe) {
|
||||
throw new IOException("Failed to get tile image " +
|
||||
"[tidx=" + ii + ", tset=" + source +
|
||||
", rfe=" + rfe + "].");
|
||||
|
||||
} catch (NoSuchTileException nste) {
|
||||
throw new RuntimeException("WTF? No such tile [tset=" + source +
|
||||
", tidx=" + ii + "]");
|
||||
}
|
||||
|
||||
// figure out how tightly we can trim it
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
//
|
||||
// $Id: MultiFrameImage.java,v 1.3 2002/09/17 19:11:13 mdb Exp $
|
||||
// $Id: MultiFrameImage.java,v 1.4 2003/01/13 22:49:47 mdb Exp $
|
||||
|
||||
package com.threerings.media.util;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
/**
|
||||
* The multi-frame image interface provides encapsulated access to a set
|
||||
@@ -31,7 +30,7 @@ public interface MultiFrameImage
|
||||
* Renders the specified frame into the specified graphics object at
|
||||
* the specified coordinates.
|
||||
*/
|
||||
public void paintFrame (Graphics g, int index, int x, int y);
|
||||
public void paintFrame (Graphics2D g, int index, int x, int y);
|
||||
|
||||
/**
|
||||
* Returns true if the specified frame contains a non-transparent
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
//
|
||||
// $Id: MultiFrameImageImpl.java,v 1.4 2003/01/08 04:09:03 mdb Exp $
|
||||
// $Id: MultiFrameImageImpl.java,v 1.5 2003/01/13 22:49:47 mdb Exp $
|
||||
|
||||
package com.threerings.media.util;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import com.threerings.media.image.ImageUtil;
|
||||
import com.threerings.media.image.Mirage;
|
||||
|
||||
/**
|
||||
* A basic implementation of the {@link MultiFrameImage} interface
|
||||
@@ -18,41 +17,41 @@ public class MultiFrameImageImpl implements MultiFrameImage
|
||||
/**
|
||||
* Constructs a multiple frame image object.
|
||||
*/
|
||||
public MultiFrameImageImpl (Image[] imgs)
|
||||
public MultiFrameImageImpl (Mirage[] mirages)
|
||||
{
|
||||
_imgs = imgs;
|
||||
_mirages = mirages;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getFrameCount ()
|
||||
{
|
||||
return _imgs.length;
|
||||
return _mirages.length;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int getWidth (int index)
|
||||
{
|
||||
return _imgs[index].getWidth(null);
|
||||
return _mirages[index].getWidth();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int getHeight (int index)
|
||||
{
|
||||
return _imgs[index].getHeight(null);
|
||||
return _mirages[index].getHeight();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void paintFrame (Graphics g, int index, int x, int y)
|
||||
public void paintFrame (Graphics2D g, int index, int x, int y)
|
||||
{
|
||||
g.drawImage(_imgs[index], x, y, null);
|
||||
_mirages[index].paint(g, x, y);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean hitTest (int index, int x, int y)
|
||||
{
|
||||
return ImageUtil.hitTest(_imgs[index], x, y);
|
||||
return _mirages[index].hitTest(x, y);
|
||||
}
|
||||
|
||||
/** The frame images. */
|
||||
protected Image _imgs[];
|
||||
protected Mirage[] _mirages;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
//
|
||||
// $Id: SingleFrameImageImpl.java,v 1.4 2003/01/08 04:09:03 mdb Exp $
|
||||
// $Id: SingleFrameImageImpl.java,v 1.5 2003/01/13 22:49:47 mdb Exp $
|
||||
|
||||
package com.threerings.media.util;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import com.threerings.media.image.ImageUtil;
|
||||
import com.threerings.media.image.Mirage;
|
||||
|
||||
/**
|
||||
* The single frame image class is a basic implementation of the {@link
|
||||
@@ -18,9 +17,9 @@ public class SingleFrameImageImpl implements MultiFrameImage
|
||||
/**
|
||||
* Constructs a single frame image object.
|
||||
*/
|
||||
public SingleFrameImageImpl (Image img)
|
||||
public SingleFrameImageImpl (Mirage mirage)
|
||||
{
|
||||
_img = img;
|
||||
_mirage = mirage;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
@@ -32,27 +31,27 @@ public class SingleFrameImageImpl implements MultiFrameImage
|
||||
// documentation inherited from interface
|
||||
public int getWidth (int index)
|
||||
{
|
||||
return _img.getWidth(null);
|
||||
return _mirage.getWidth();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int getHeight (int index)
|
||||
{
|
||||
return _img.getHeight(null);
|
||||
return _mirage.getHeight();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void paintFrame (Graphics g, int index, int x, int y)
|
||||
public void paintFrame (Graphics2D g, int index, int x, int y)
|
||||
{
|
||||
g.drawImage(_img, x, y, null);
|
||||
_mirage.paint(g, x, y);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean hitTest (int index, int x, int y)
|
||||
{
|
||||
return ImageUtil.hitTest(_img, x, y);
|
||||
return _mirage.hitTest(x, y);
|
||||
}
|
||||
|
||||
/** The frame image. */
|
||||
protected Image _img;
|
||||
protected Mirage _mirage;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// $Id: SingleTileImageImpl.java,v 1.1 2003/01/13 22:49:47 mdb Exp $
|
||||
|
||||
package com.threerings.media.util;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import com.threerings.media.tile.Tile;
|
||||
|
||||
/**
|
||||
* The single frame image class is a basic implementation of the {@link
|
||||
* MultiFrameImage} interface intended to facilitate the creation of MFIs
|
||||
* whose display frames consist of only a single tile image.
|
||||
*/
|
||||
public class SingleTileImageImpl implements MultiFrameImage
|
||||
{
|
||||
/**
|
||||
* Constructs a single frame image object.
|
||||
*/
|
||||
public SingleTileImageImpl (Tile tile)
|
||||
{
|
||||
_tile = tile;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getFrameCount ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int getWidth (int index)
|
||||
{
|
||||
return _tile.getWidth();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int getHeight (int index)
|
||||
{
|
||||
return _tile.getHeight();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void paintFrame (Graphics2D g, int index, int x, int y)
|
||||
{
|
||||
_tile.paint(g, x, y);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean hitTest (int index, int x, int y)
|
||||
{
|
||||
return _tile.hitTest(x, y);
|
||||
}
|
||||
|
||||
/** The frame image. */
|
||||
protected Tile _tile;
|
||||
}
|
||||
Reference in New Issue
Block a user