/**
* Copyright (c) 2003-2009, Xith3D Project Group all rights reserved.
*
* Portions based on the Java3D interface, Copyright by Sun Microsystems.
* Many thanks to the developers of Java3D and Sun Microsystems for their
* innovation and design.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the 'Xith3D Project Group' nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) A
* RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE
*/
package net.ctdp.rfdynhud.render;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ImageObserver;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage;
import java.text.AttributedCharacterIterator;
import java.util.Map;
import org.openmali.types.twodee.Rect2i;
/**
* This is an adapter for pixel-perfect drawing onto a Texture2D.
*
* @author Marvin Froehlich (CTDP) (aka Qudus)
*/
public class Texture2DCanvas extends Graphics2D
{
private final TextureImage2D texImg;
private Graphics2D graphics;
private final AffineTransform baseAffineTransform;
private boolean isIdentityTransform = true;
private Rect2i currentUpdateRect = null;
private int currentlyAppliedUpdateRects = 0;
private final Rect2i[] clipStack = new Rect2i[ 32 ];
private int clipStackSize = 0;
public final TextureImage2D getImage()
{
return ( texImg );
}
private final java.awt.geom.Point2D.Float pUL = new java.awt.geom.Point2D.Float();
private final java.awt.geom.Point2D.Float pUR = new java.awt.geom.Point2D.Float();
private final java.awt.geom.Point2D.Float pLL = new java.awt.geom.Point2D.Float();
private final java.awt.geom.Point2D.Float pLR = new java.awt.geom.Point2D.Float();
private final void markDirty( int x, int y, int width, int height, final boolean doIt, Rect2i dirtyRect )
{
if ( ( texImg == null ) || ( !doIt && ( dirtyRect == null ) ) )
return;
if ( !isIdentityTransform )
{
pUL.setLocation( x, y );
pUR.setLocation( x + width - 1, y );
pLL.setLocation( x, y + height - 1 );
pLR.setLocation( x + width - 1, y + height - 1 );
java.awt.geom.AffineTransform t = getTransform();
t.transform( pUL, pUL );
t.transform( pUR, pUR );
t.transform( pLL, pLL );
t.transform( pLR, pLR );
x = Math.round( Math.min( Math.min( Math.min( pUL.x, pUR.x ), pLL.x ), pLR.x ) );
y = Math.round( Math.min( Math.min( Math.min( pUL.y, pUR.y ), pLL.y ), pLR.y ) );
int x1 = Math.round( Math.max( Math.max( Math.max( pUL.x, pUR.x ), pLL.x ), pLR.x ) );
int y1 = Math.round( Math.max( Math.max( Math.max( pUL.y, pUR.y ), pLL.y ), pLR.y ) );
width = x1 - x + 1;
height = y1 - y + 1;
}
if ( currentUpdateRect != null )
{
if ( ( x >= currentUpdateRect.getLeft() ) &&
( y >= currentUpdateRect.getTop() ) &&
( x + width <= currentUpdateRect.getLeft() + currentUpdateRect.getWidth() ) &&
( y + height <= currentUpdateRect.getTop() + currentUpdateRect.getHeight() )
)
{
return;
}
}
if ( doIt )
{
texImg.markDirty( x, y, width, height, true, true, dirtyRect );
}
else if ( dirtyRect != null )
{
dirtyRect.set( x, y, width, height );
texImg.clampToClipRect( dirtyRect );
}
}
private final void markDirty()
{
markDirty( 0, 0, texImg.getWidth(), texImg.getHeight(), true, null );
}
public final void beginUpdateRegion( int x, int y, int width, int height )
{
if ( currentUpdateRect != null )
{
currentUpdateRect.combine( x, y, width, height );
}
else
{
currentUpdateRect = Rect2i.fromPool( x, y, width, height );
}
currentlyAppliedUpdateRects++;
}
public final void beginUpdateRegionComplete()
{
beginUpdateRegion( 0, 0, texImg.getWidth(), texImg.getHeight() );
}
public final void finishUpdateRegion()
{
if ( currentUpdateRect == null )
return;
currentlyAppliedUpdateRects--;
if ( currentlyAppliedUpdateRects == 0 )
{
int l = currentUpdateRect.getLeft();
int t = currentUpdateRect.getTop();
int w = currentUpdateRect.getWidth();
int h = currentUpdateRect.getHeight();
Rect2i.toPool( currentUpdateRect );
currentUpdateRect = null;
markDirty( l, t, w, h, true, null );
}
}
/*
public final java.awt.geom.AffineTransform getBaseAffineTransform()
{
return ( baseAffineTransform );
}
*/
@Override
public GraphicsConfiguration getDeviceConfiguration()
{
return ( graphics.getDeviceConfiguration() );
}
@Override
public final void clearRect( int x, int y, int width, int height )
{
graphics.clearRect( x, y, width, height );
markDirty( x, y, width, height, true, null );
}
public final void clearRect( Rect2i rect )
{
clearRect( rect.getLeft(), rect.getTop(), rect.getWidth(), rect.getHeight() );
}
@Override
public void clipRect( int x, int y, int width, int height )
{
graphics.clipRect( x, y, width, height );
}
public final void clip( Rect2i rect )
{
clipRect( rect.getLeft(), rect.getTop(), rect.getWidth(), rect.getHeight() );
}
@Override
public final void clip( Shape shape )
{
graphics.clip( shape );
}
@Override
public final void copyArea( int x, int y, int width, int height, int dx, int dy )
{
graphics.copyArea( x, y, width, height, dx, dy );
markDirty( dx, dy, width, height, true, null );
}
public final void copyArea( Rect2i rect, int dx, int dy )
{
copyArea( rect.getLeft(), rect.getTop(), rect.getWidth(), rect.getHeight(), dx, dy );
}
@Override
public final void draw( Shape shape )
{
graphics.draw( shape );
java.awt.Rectangle rect = shape.getBounds();
markDirty( rect.x, rect.y, rect.width, rect.height, true, null );
}
@Override
public final void drawArc( int x, int y, int width, int height, int startAngle, int arcAngle )
{
graphics.drawArc( x, y, width, height, startAngle, arcAngle );
markDirty( x, y, width, height, true, null );
}
public final void drawCircle( int x, int y, int radius )
{
drawArc( x - radius, y - radius, radius + radius, radius + radius, 0, 360 );
}
@Override
public final void drawBytes( byte[] data, int offset, int length, int x, int y )
{
graphics.drawBytes( data, offset, length, x, y );
markDirty( x, y, texImg.getWidth() - x, texImg.getHeight() - y, true, null );
}
@Override
public final void drawChars( char[] data, int offset, int length, int x, int y )
{
graphics.drawChars( data, offset, length, x, y );
markDirty( x, y, texImg.getWidth() - x, texImg.getHeight() - y, true, null );
}
@Override
public final void drawGlyphVector( GlyphVector g, float x, float y )
{
graphics.drawGlyphVector( g, x, y );
markDirty( (int)x, (int)y, texImg.getWidth() - (int)x, texImg.getHeight() - (int)y, true, null );
}
@Override
public final boolean drawImage( Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver imgOb )
{
if ( ( dx2 < 0 ) || ( dy2 < 0 ) || ( dx1 >= texImg.getWidth() ) || ( dy1 >= texImg.getHeight() ) )
return ( true );
final boolean result = graphics.drawImage( img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, imgOb );
markDirty( dx1, dy1, dx2 - dx1 + 1, dy2 - dy1 + 1, true, null );
return ( result );
}
public final void drawImage( Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2 )
{
drawImage( img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, (ImageObserver)null );
}
@Override
public final boolean drawImage( Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgColor, ImageObserver imgOb )
{
final boolean result = graphics.drawImage( img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bgColor, imgOb );
markDirty( dx1, dy1, dx2 - dx1 + 1, dy2 - dy1 + 1, true, null );
return ( result );
}
public final void drawImage( Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgColor )
{
drawImage( img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bgColor, (ImageObserver)null );
}
@Override
public final boolean drawImage( Image img, AffineTransform xform, ImageObserver imgOb )
{
final boolean result = graphics.drawImage( img, xform, imgOb );
markDirty();
return ( result );
}
@Override
public final void drawImage( BufferedImage img, BufferedImageOp op, int x, int y )
{
graphics.drawImage( img, op, x, y );
markDirty( x, y, img.getWidth(), img.getHeight(), true, null );
}
@Override
public final boolean drawImage( Image img, int x, int y, ImageObserver imgOb )
{
final boolean result = graphics.drawImage( img, x, y, imgOb );
markDirty( x, y, img.getWidth( null ), img.getHeight( null ), true, null );
return ( result );
}
public final void drawImage( Image img, int x, int y )
{
drawImage( img, x, y, (ImageObserver)null );
}
@Override
public final boolean drawImage( Image img, int x, int y, Color bgColor, ImageObserver imgOb )
{
final boolean result = graphics.drawImage( img, x, y, bgColor, imgOb );
markDirty( x, y, img.getWidth( null ), img.getHeight( null ), true, null );
return ( result );
}
public final void drawImage( Image img, int x, int y, Color bgColor )
{
drawImage( img, x, y, bgColor, (ImageObserver)null );
}
@Override
public final boolean drawImage( Image img, int x, int y, int width, int height, ImageObserver imgOb )
{
final boolean result = graphics.drawImage( img, x, y, width, height, null );
markDirty( x, y, width, height, true, null );
return ( result );
}
public final void drawImage( Image img, int x, int y, int width, int height )
{
drawImage( img, x, y, width, height, (ImageObserver)null );
}
@Override
public final boolean drawImage( Image img, int x, int y, int width, int height, Color bgColor, ImageObserver imgOb )
{
final boolean result = graphics.drawImage( img, x, y, width, height, bgColor, imgOb );
markDirty( x, y, width, height, true, null );
return ( result );
}
public final void drawImage( Image img, int x, int y, int width, int height, Color bgColor )
{
drawImage( img, x, y, width, height, bgColor, (ImageObserver)null );
}
@Override
public void drawRenderableImage( RenderableImage img, AffineTransform xform )
{
graphics.drawRenderableImage( img, xform );
markDirty();
}
@Override
public void drawRenderedImage( RenderedImage img, AffineTransform xform )
{
graphics.drawRenderedImage( img, xform );
markDirty();
}
@Override
public final void drawLine( int x1, int y1, int x2, int y2 )
{
//graphics.drawLine( x1, yy( y1 ), x2, yy( y2 ) );
graphics.drawLine( x1, y1, x2, y2 );
markDirty( x1, y1, x2 - x1, y2 - y1, true, null );
}
public final void drawLineOffset( int x, int y, int dx, int dy )
{
drawLine( x, y, x + dx, y + dy );
}
@Override
public final void drawOval( int x, int y, int width, int height )
{
graphics.drawOval( x, y, width, height );
markDirty( x, y, width, height, true, null );
}
@Override
public final void drawPolygon( Polygon polygon )
{
graphics.drawPolygon( polygon );
java.awt.Rectangle rect = polygon.getBounds();
markDirty( rect.x, rect.y, rect.width, rect.height, true, null );
}
@Override
public final void drawPolygon( int[] xPoints, int[] yPoints, int nPoints )
{
int minX = Integer.MAX_VALUE;
int minY = Integer.MAX_VALUE;
int maxX = Integer.MIN_VALUE;
int maxY = Integer.MIN_VALUE;
for ( int i = 0; i < nPoints; i++ )
{
if ( xPoints[i] < minX )
minX = xPoints[i];
if ( xPoints[i] > maxX )
maxX = xPoints[i];
}
for ( int i = 0; i < nPoints; i++ )
{
if ( yPoints[i] < minY )
minY = yPoints[i];
if ( yPoints[i] > maxY )
maxY = yPoints[i];
}
int width = maxX - minX + 1;
int height = maxY - minY + 1;
if ( ( width > 0 ) && ( height > 0 ) )
{
graphics.drawPolygon( xPoints, yPoints, nPoints );
markDirty( minX, minY, width, height, true, null );
}
}
@Override
public final void drawPolyline( int[] xPoints, int[] yPoints, int nPoints )
{
int minX = Integer.MAX_VALUE;
int minY = Integer.MAX_VALUE;
int maxX = Integer.MIN_VALUE;
int maxY = Integer.MIN_VALUE;
for ( int i = 0; i < nPoints; i++ )
{
if ( xPoints[i] < minX )
minX = xPoints[i];
if ( xPoints[i] > maxX )
maxX = xPoints[i];
}
for ( int i = 0; i < nPoints; i++ )
{
if ( yPoints[i] < minY )
minY = yPoints[i];
if ( yPoints[i] > maxY )
maxY = yPoints[i];
}
int width = maxX - minX + 1;
int height = maxY - minY + 1;
if ( ( width > 0 ) && ( height > 0 ) )
{
graphics.drawPolyline( xPoints, yPoints, nPoints );
markDirty( minX, minY, width, height, true, null );
}
}
@Override
public final void drawRect( int x, int y, int width, int height )
{
graphics.drawRect( x, y, width, height );
markDirty( x, y, width, height, true, null );
}
public final void drawRect( Rect2i rect )
{
drawRect( rect.getLeft(), rect.getTop(), rect.getWidth(), rect.getHeight() );
}
@Override
public final void drawRoundRect( int x, int y, int width, int height, int arcWidth, int arcHeight )
{
graphics.drawRoundRect( x, y, width, height, arcWidth, arcHeight );
markDirty( x, y, width, height, true, null );
}
public final void drawRoundRect( Rect2i rect, int arcWidth, int arcHeight )
{
drawRoundRect( rect.getLeft(), rect.getTop(), rect.getWidth(), rect.getHeight(), arcWidth, arcHeight );
}
@Override
public final void drawString( AttributedCharacterIterator iterator, float x, float y )
{
graphics.drawString( iterator, x, y );
markDirty( (int)x, (int)y, texImg.getWidth() - (int)x, texImg.getHeight() - (int)y, true, null );
}
@Override
public final void drawString( AttributedCharacterIterator iterator, int x, int y )
{
graphics.drawString( iterator, x, y );
markDirty( x, y, texImg.getWidth() - x, texImg.getHeight() - y, true, null );
}
@Override
public final void drawString( String s, float x, float y )
{
graphics.drawString( s, x, y );
markDirty( (int)x, (int)y, texImg.getWidth() - (int)x, texImg.getHeight() - (int)y, true, null );
}
public final void drawString( String s, int x, int y, int baselineOffset, int boundsWidth, int boundsHeight, boolean markDirty, Rect2i dirtyRect )
{
graphics.drawString( s, x, y );
markDirty( x, y - baselineOffset, boundsWidth, boundsHeight, markDirty, dirtyRect );
}
public final void drawString( String s, int x, int y, Rectangle2D bounds, boolean markDirty, Rect2i dirtyRect )
{
graphics.drawString( s, x, y );
markDirty( x, y + (int)bounds.getY(), (int)bounds.getWidth(), (int)bounds.getHeight(), markDirty, dirtyRect );
}
public final void drawString( String s, int x, int y, Rectangle2D bounds, Font font, boolean antiAliased, Color color, boolean markDirty, Rect2i dirtyRect )
{
Font oldFont = getFont();
Color oldColor = getColor();
Object oldAntiAliasing = getRenderingHint( RenderingHints.KEY_ANTIALIASING );
try
{
setFont( font );
setColor( color );
setRenderingHint( RenderingHints.KEY_ANTIALIASING, antiAliased ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF );
graphics.drawString( s, x, y );
if ( markDirty || ( dirtyRect != null ) && ( bounds == null ) )
bounds = getFontMetrics().getStringBounds( s, this );
markDirty( x, y + (int)bounds.getY(), (int)bounds.getWidth(), (int)bounds.getHeight(), markDirty, dirtyRect );
}
finally
{
setFont( oldFont );
setColor( oldColor );
setRenderingHint( RenderingHints.KEY_ANTIALIASING, oldAntiAliasing );
}
}
@Override
public final void drawString( String s, int x, int y )
{
drawString( s, x, y, graphics.getFontMetrics().getStringBounds( s, graphics ), true, null );
}
@Override
public final void fill( Shape shape )
{
graphics.fill( shape );
java.awt.Rectangle rect = shape.getBounds();
markDirty( rect.x, rect.y, rect.width, rect.height, true, null );
}
@Override
public final void fillArc( int x, int y, int width, int height, int startAngle, int arcAngle )
{
graphics.fillArc( x, y, width, height, startAngle, arcAngle );
markDirty( x, y, width, height, true, null );
}
public final void fillCircle( int x, int y, int radius )
{
fillArc( x - radius, y - radius, radius + radius, radius + radius, 0, 360 );
}
@Override
public final void fillOval( int x, int y, int width, int height )
{
graphics.fillOval( x, y, width, height );
markDirty( x, y, width, height, true, null );
}
@Override
public final void fillPolygon( int[] xPoints, int[] yPoints, int nPoints )
{
int minX = Integer.MAX_VALUE;
int minY = Integer.MAX_VALUE;
int maxX = Integer.MIN_VALUE;
int maxY = Integer.MIN_VALUE;
for ( int i = 0; i < nPoints; i++ )
{
if ( xPoints[i] < minX )
minX = xPoints[i];
if ( xPoints[i] > maxX )
maxX = xPoints[i];
}
for ( int i = 0; i < nPoints; i++ )
{
if ( yPoints[i] < minY )
minY = yPoints[i];
if ( yPoints[i] > maxY )
maxY = yPoints[i];
}
int width = maxX - minX + 1;
int height = maxY - minY + 1;
if ( ( width > 0 ) && ( height > 0 ) )
{
graphics.fillPolygon( xPoints, yPoints, nPoints );
markDirty( minX, minY, width, height, true, null );
}
}
@Override
public final void fillRect( int x, int y, int width, int height )
{
graphics.fillRect( x, y, width, height );
markDirty( x + 1, y + 1, width - 2, height - 2, true, null );
}
public final void fillRect( Rect2i rect )
{
fillRect( rect.getLeft(), rect.getTop(), rect.getWidth(), rect.getHeight() );
}
@Override
public final void fillRoundRect( int x, int y, int width, int height, int arcWidth, int arcHeight )
{
graphics.fillRoundRect( x, y, width, height, arcWidth, arcHeight );
markDirty( x, y, width, height, true, null );
}
public final void fillRoundRect( Rect2i rect, int arcWidth, int arcHeight )
{
fillRoundRect( rect.getLeft(), rect.getTop(), rect.getWidth(), rect.getHeight(), arcWidth, arcHeight );
}
@Override
public Color getBackground()
{
return ( graphics.getBackground() );
}
@Override
public final java.awt.Shape getClip()
{
return ( graphics.getClip() );
}
public final Rect2i getClipRect2i()
{
java.awt.Rectangle awtRect = graphics.getClipBounds();
if ( awtRect == null )
return ( new Rect2i( 0, 0, getImage().getMaxWidth(), getImage().getMaxHeight() ) );
return ( new Rect2i( awtRect.x, awtRect.y, awtRect.width, awtRect.height ) );
}
@Override
public final Rectangle getClipBounds()
{
return ( graphics.getClipBounds() );
}
public final Rect2i getClipBounds( Rect2i rect )
{
java.awt.Rectangle awtRect = new java.awt.Rectangle( rect.getLeft(), rect.getTop(), rect.getWidth(), rect.getHeight() );
graphics.getClipBounds( awtRect );
return ( rect );
}
@Override
public final Color getColor()
{
return ( graphics.getColor() );
}
@Override
public final java.awt.Font getFont()
{
return ( graphics.getFont() );
}
@Override
public final java.awt.FontMetrics getFontMetrics()
{
return ( graphics.getFontMetrics() );
}
@Override
public FontMetrics getFontMetrics( Font font )
{
return ( graphics.getFontMetrics( font ) );
}
@Override
public final java.awt.font.FontRenderContext getFontRenderContext()
{
return ( graphics.getFontRenderContext() );
}
@Override
public final java.awt.Paint getPaint()
{
return ( graphics.getPaint() );
}
@Override
public final Object getRenderingHint( java.awt.RenderingHints.Key hintKey )
{
return ( graphics.getRenderingHint( hintKey ) );
}
@Override
public final java.awt.RenderingHints getRenderingHints()
{
return ( graphics.getRenderingHints() );
}
@Override
public final java.awt.Stroke getStroke()
{
return ( graphics.getStroke() );
}
@Override
public final java.awt.geom.AffineTransform getTransform()
{
return ( graphics.getTransform() );
}
@Override
public final boolean hitClip( int x, int y, int width, int height )
{
return ( graphics.hitClip( x, y, width, height ) );
}
@Override
public boolean hit( Rectangle rect, Shape s, boolean onStroke )
{
return ( graphics.hit( rect, s, onStroke ) );
}
@Override
public final void rotate( double theta )
{
graphics.rotate( theta );
this.isIdentityTransform = false;
}
@Override
public final void rotate( double theta, double x, double y )
{
graphics.rotate( theta, x, y );
this.isIdentityTransform = false;
}
@Override
public final void scale( double sx, double sy )
{
graphics.scale( sx, sy );
this.isIdentityTransform = false;
}
@Override
public final void setBackground( Color color )
{
graphics.setBackground( color );
}
@Override
public final void setClip( java.awt.Shape clip )
{
graphics.setClip( clip );
}
@Override
public final void setClip( int x, int y, int width, int height )
{
int right = Math.min( x + width - 1, getImage().getMaxWidth() - 1 );
int bottom = Math.min( y + height - 1, getImage().getMaxHeight() - 1 );
graphics.setClip( Math.max( 0, x ), Math.max( 0, y ), right - x + 1, bottom - y + 1 );
getImage().setClipRect( x, y, width, height );
}
public final void setClip( Rect2i rect )
{
if ( rect == null )
setClip( 0, 0, getImage().getMaxWidth(), getImage().getMaxHeight() );
else
setClip( rect.getLeft(), rect.getTop(), rect.getWidth(), rect.getHeight() );
}
public final <Rect2i_ extends Rect2i> Rect2i_ getClip( Rect2i_ rect )
{
return ( getImage().getClipRect( rect ) );
}
public final void pushClip( int x, int y, int width, int height, boolean intersectWithCurrent )
{
getClip( clipStack[clipStackSize - 1] );
if ( clipStack[clipStackSize] == null )
clipStack[clipStackSize] = new Rect2i();
clipStack[clipStackSize].set( x, y, width, height );
if ( intersectWithCurrent )
{
clipStack[clipStackSize].clamp( clipStack[clipStackSize - 1] );
setClip( clipStack[clipStackSize] );
}
else
{
setClip( x, y, width, height );
}
clipStackSize++;
}
public final void pushClip( int x, int y, int width, int height )
{
pushClip( x, y, width, height, false );
}
public final void pushClip( Rect2i rect, boolean intersectWithCurrent )
{
pushClip( rect.getLeft(), rect.getTop(), rect.getWidth(), rect.getHeight(), intersectWithCurrent );
}
public final void pushClip( Rect2i rect )
{
pushClip( rect.getLeft(), rect.getTop(), rect.getWidth(), rect.getHeight(), false );
}
public final void popClip()
{
clipStackSize--;
setClip( clipStack[clipStackSize - 1] );
}
@Override
public void setColor( Color color )
{
graphics.setColor( color );
}
@Override
public final void setFont( java.awt.Font font )
{
graphics.setFont( font );
}
@Override
public final void setPaint( java.awt.Paint paint )
{
graphics.setPaint( paint );
}
@Override
public final void setPaintMode()
{
graphics.setPaintMode();
}
@Override
public final void setRenderingHint( java.awt.RenderingHints.Key hintKey, Object hintValue )
{
graphics.setRenderingHint( hintKey, hintValue );
}
public final void setRenderingHints( java.awt.RenderingHints hints )
{
graphics.setRenderingHints( hints );
}
@Override
public void setRenderingHints( Map< ?, ? > hints )
{
graphics.setRenderingHints( hints );
}
@Override
public void addRenderingHints( Map< ?, ? > hints )
{
graphics.addRenderingHints( hints );
}
public final void setAntialiazingEnabled( boolean enabled )
{
Object value = enabled ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF;
graphics.setRenderingHint( RenderingHints.KEY_ANTIALIASING, value );
}
public final boolean isAntialiazingEnabled()
{
Object value = graphics.getRenderingHint( RenderingHints.KEY_ANTIALIASING );
return ( value == RenderingHints.VALUE_ANTIALIAS_ON );
}
@Override
public final void setStroke( java.awt.Stroke stroke )
{
graphics.setStroke( stroke );
}
@Override
public final void setTransform( java.awt.geom.AffineTransform Tx )
{
graphics.setTransform( Tx );
this.isIdentityTransform = false;
}
@Override
public final void setXORMode( Color color )
{
graphics.setXORMode( color );
}
@Override
public final void shear( double shx, double shy )
{
graphics.shear( shx, shy );
this.isIdentityTransform = false;
}
@Override
public final void transform( java.awt.geom.AffineTransform Tx )
{
graphics.transform( Tx );
this.isIdentityTransform = false;
}
@Override
public final void translate( double tx, double ty )
{
graphics.translate( tx, ty );
this.isIdentityTransform = false;
}
@Override
public final void translate( int tx, int ty )
{
graphics.translate( tx, ty );
this.isIdentityTransform = false;
}
private void updateAffineTransform()
{
baseAffineTransform.setToIdentity();
/*
//if ( texImg.getYUp() )
{
baseAffineTransform.concatenate( new AffineTransform( 1f, 0f, 0f, -1f, 0f, 0f ) );
baseAffineTransform.concatenate( new AffineTransform( 1f, 0f, 0f, 1f, 0f, -texImg.getUsedHeight() ) );
}
*/
this.graphics.setTransform( baseAffineTransform );
this.isIdentityTransform = true;
}
public void resetTransform()
{
updateAffineTransform();
}
/*
public final void notifyImagesizeChanged( int imgWidth, int imgHeight, Graphics2D graphics )
{
this.imgWidth = imgWidth;
this.imgHeight = imgHeight;
if ( ( graphics != null ) && ( graphics != this.graphics ) )
{
graphics.setBackground( this.graphics.getBackground() );
graphics.setClip( this.graphics.getClip() );
graphics.setColor( this.graphics.getColor() );
graphics.setComposite( this.graphics.getComposite() );
graphics.setFont( this.graphics.getFont() );
graphics.setPaint( this.graphics.getPaint() );
graphics.setRenderingHints( this.graphics.getRenderingHints() );
graphics.setStroke( this.graphics.getStroke() );
//graphics.setXORMode( this.graphics.getXORMode() );
this.graphics = graphics;
}
updateAffineTransform();
}
*/
@Override
public void setComposite( Composite comp )
{
graphics.setComposite( comp );
}
@Override
public Composite getComposite()
{
return ( graphics.getComposite() );
}
@Override
public Graphics create()
{
throw new Error( "create() is not supported for this kind of Graphics2D." );
}
@Override
public void dispose()
{
graphics.dispose();
}
protected Texture2DCanvas( TextureImage2D ti, Graphics2D graphics )
{
if ( graphics == null )
throw new IllegalArgumentException( "graphics must not be null." );
this.texImg = ti;
this.graphics = graphics;
this.baseAffineTransform = new AffineTransform( 1f, 0f, 0f, 1f, 0f, 0f );
updateAffineTransform();
clipStack[0] = getClipRect2i();
clipStackSize++;
}
protected Texture2DCanvas( TextureImage2D ti )
{
this( ti, ti.createGraphics2D() );
}
}