8d54026f63
git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@918 ed5b42cb-e716-0410-a449-f6a68f950b19
153 lines
4.7 KiB
Java
153 lines
4.7 KiB
Java
//
|
|
// $Id$
|
|
//
|
|
// Nenya library - tools for developing networked games
|
|
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
|
// http://www.threerings.net/code/nenya/
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it
|
|
// under the terms of the GNU Lesser General Public License as published
|
|
// by the Free Software Foundation; either version 2.1 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this library; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
package com.threerings.media.image;
|
|
|
|
import java.awt.Graphics2D;
|
|
import java.awt.Point;
|
|
import java.awt.Rectangle;
|
|
import java.awt.geom.AffineTransform;
|
|
import java.awt.geom.NoninvertibleTransformException;
|
|
import java.awt.image.BufferedImage;
|
|
|
|
/**
|
|
* Draws a mirage combined with an arbitrary AffineTransform.
|
|
*/
|
|
public class TransformedMirage
|
|
implements Mirage
|
|
{
|
|
/**
|
|
* Constructor for backwards compatibility that automatically repositions the transformed
|
|
* mirage so its new upper-left corner is still at the origin.
|
|
*/
|
|
public TransformedMirage (Mirage base, AffineTransform transform)
|
|
{
|
|
this(base, transform, true);
|
|
}
|
|
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
public TransformedMirage (Mirage base, AffineTransform transform, boolean reposition)
|
|
{
|
|
_base = base;
|
|
|
|
// clone the transform so that it doesn't get changed on us.
|
|
_transform = (AffineTransform) transform.clone();
|
|
computeTransformedBounds();
|
|
if (reposition) {
|
|
_transform.preConcatenate(
|
|
AffineTransform.getTranslateInstance(-_bounds.x, -_bounds.y));
|
|
}
|
|
}
|
|
|
|
// documentation inherited from interface Mirage
|
|
public void paint (Graphics2D gfx, int x, int y)
|
|
{
|
|
AffineTransform otrans = gfx.getTransform();
|
|
gfx.translate(x, y);
|
|
gfx.transform(_transform);
|
|
_base.paint(gfx, 0, 0);
|
|
gfx.setTransform(otrans);
|
|
}
|
|
|
|
// documentation inherited from interface Mirage
|
|
public int getWidth ()
|
|
{
|
|
return _bounds.width;
|
|
}
|
|
|
|
// documentation inherited from interface Mirage
|
|
public int getHeight ()
|
|
{
|
|
return _bounds.height;
|
|
}
|
|
|
|
// documentation inherited from interface Mirage
|
|
public boolean hitTest (int x, int y)
|
|
{
|
|
Point p = new Point(x, y);
|
|
try {
|
|
_transform.createInverse().transform(p, p);
|
|
return _base.hitTest(p.x, p.y);
|
|
|
|
} catch (NoninvertibleTransformException nte) {
|
|
// grumble, grumble
|
|
// TODO: log something?
|
|
return ImageUtil.hitTest(getSnapshot(), x, y);
|
|
}
|
|
}
|
|
|
|
// documentation inherited from interface Mirage
|
|
public BufferedImage getSnapshot ()
|
|
{
|
|
BufferedImage baseSnap = _base.getSnapshot();
|
|
BufferedImage img = new BufferedImage(_bounds.width, _bounds.height,
|
|
baseSnap.getType());
|
|
Graphics2D gfx = (Graphics2D) img.getGraphics();
|
|
try {
|
|
gfx.transform(_transform);
|
|
gfx.drawImage(baseSnap, 0, 0, null);
|
|
} finally {
|
|
gfx.dispose();
|
|
}
|
|
return img;
|
|
}
|
|
|
|
// documentation inherited from interface Mirage
|
|
public long getEstimatedMemoryUsage ()
|
|
{
|
|
return _base.getEstimatedMemoryUsage();
|
|
}
|
|
|
|
/**
|
|
* Compute the bounds of the base Mirage after it has been transformed.
|
|
*/
|
|
protected void computeTransformedBounds ()
|
|
{
|
|
int w = _base.getWidth();
|
|
int h = _base.getHeight();
|
|
Point[] points = new Point[] {
|
|
new Point(0, 0), new Point(w, 0), new Point(0, h), new Point(w, h) };
|
|
_transform.transform(points, 0, points, 0, 4);
|
|
int minX, minY, maxX, maxY;
|
|
minX = minY = Integer.MAX_VALUE;
|
|
maxX = maxY = Integer.MIN_VALUE;
|
|
for (int ii=0; ii < 4; ii++) {
|
|
minX = Math.min(minX, points[ii].x);
|
|
maxX = Math.max(maxX, points[ii].x);
|
|
minY = Math.min(minY, points[ii].y);
|
|
maxY = Math.max(maxY, points[ii].y);
|
|
}
|
|
|
|
_bounds = new Rectangle(minX, minY, maxX - minX, maxY - minY);
|
|
}
|
|
|
|
/** The base mirage. */
|
|
protected Mirage _base;
|
|
|
|
/** Our transformed bounds. */
|
|
protected Rectangle _bounds;
|
|
|
|
/** The transform we apply when painting the base mirage. */
|
|
protected AffineTransform _transform;
|
|
}
|