Moved attachable URL factory-related comment into the appropriate class.

Added extra special magic to allow the resource: URLs to extract a tile
from an image that is actually made up of a bunch of smaller images. It's
so money.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3083 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2004-08-17 00:49:58 +00:00
parent b7d43b786f
commit 63fad5a1e6
+70 -28
View File
@@ -1,8 +1,9 @@
//
// $Id: Handler.java,v 1.5 2003/07/09 18:44:52 ray Exp $
// $Id: Handler.java,v 1.6 2004/08/17 00:49:58 mdb Exp $
package com.threerings.resource;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -10,7 +11,14 @@ import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import javax.imageio.ImageIO;
import com.samskivert.net.AttachableURLFactory;
import com.samskivert.io.ByteArrayOutInputStream;
import java.awt.image.BufferedImage;
import java.awt.Rectangle;
import com.threerings.geom.GeomUtil;
import com.samskivert.util.StringUtil;
/**
* This class is not used directly, except by a registering ResourceManager
@@ -34,30 +42,8 @@ public class Handler extends URLStreamHandler
}
_rmgr = rmgr;
// There are two ways to do this.
// Method 1, which is the only one that seems to work under
// Java Web Start, is to register a factory.
// This *used* to be scary to me, because you could only have one
// factory, but now we have the attachable factory!
// wire up our handler with the handy dandy attachable URL factory
AttachableURLFactory.attachHandler("resource", Handler.class);
// Method 2 seems like a better idea but doesn't work under
// Java Web Start. We add on a property that registers this
// very class as the handler for the resource property.
// It would be instantiated with Class.forName().
// (And I did check, it's not dasho that is preventing this
// from working under JWS, it's something else.)
/*
// dug up from java.net.URL
String HANDLER_PROP = "java.protocol.handler.pkgs";
String prop = System.getProperty(HANDLER_PROP, "");
if (!"".equals(prop)) {
prop += "|";
}
prop += "com.threerings";
System.setProperty(HANDLER_PROP, prop);
*/
}
// documentation inherited
@@ -69,11 +55,18 @@ public class Handler extends URLStreamHandler
public void connect ()
throws IOException
{
try {
// the host is the bundle name
_stream = _rmgr.getResource(this.url.getHost(),
// and we need to remove the leading '/' from path
this.url.getPath().substring(1));
String bundle = this.url.getHost();
// and we need to remove the leading '/' from path;
String path = this.url.getPath().substring(1);
try {
// if there are query parameters, we need special magic
String query = url.getQuery();
if (!StringUtil.blank(query)) {
_stream = getStream(bundle, path, query);
} else {
_stream = _rmgr.getResource(bundle, path);
}
this.connected = true;
} catch (IOException ioe) {
@@ -97,6 +90,55 @@ public class Handler extends URLStreamHandler
};
}
/**
* Does some magic to allow a subset of an image to be extracted,
* reencoded as a PNG and then spat back out to the Java content
* handler system for inclusion in internal documentation.
*/
protected InputStream getStream (String bundle, String path, String query)
throws IOException
{
// we can only do this with PNGs
if (!path.endsWith(".png")) {
Log.warning("Requested sub-tile of non-PNG resource " +
"[bundle=" + bundle + ", path=" + path +
", dims=" + query + "].");
return _rmgr.getResource(bundle, path);
}
// parse the query string
String[] bits = StringUtil.split(query, "&");
int width = -1, height = -1, tidx = -1;
try {
for (int ii = 0; ii < bits.length; ii++) {
if (bits[ii].startsWith("width=")) {
width = Integer.parseInt(bits[ii].substring(6));
} else if (bits[ii].startsWith("height=")) {
height = Integer.parseInt(bits[ii].substring(7));
} else if (bits[ii].startsWith("tile=")) {
tidx = Integer.parseInt(bits[ii].substring(5));
}
}
} catch (NumberFormatException nfe) {
}
if (width <= 0 || height <= 0 || tidx < 0) {
Log.warning("Bogus sub-image dimensions [bundle=" + bundle +
", path=" + path + ", dims=" + query + "].");
throw new FileNotFoundException(path);
}
// locate the tile image, then write that subimage back out in PNG
// format into memory and return an input stream for that
BufferedImage src = ImageIO.read(_rmgr.getImageResource(bundle, path));
Rectangle trect = GeomUtil.getTile(
src.getWidth(), src.getHeight(), width, height, tidx);
BufferedImage tile = src.getSubimage(
trect.x, trect.y, trect.width, trect.height);
ByteArrayOutInputStream data = new ByteArrayOutInputStream();
ImageIO.write(tile, "PNG", data);
return data.getInputStream();
}
/** Our singleton resource manager. */
protected static ResourceManager _rmgr;
}