summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-09-19 03:21:15 +0200
committerSven Gothel <[email protected]>2013-09-19 03:21:15 +0200
commit8a4a64e1a3e9beb09580ba95fe85026abf2ff106 (patch)
treeaab4881100a2b55c3068cb591caf44414ed2a352
parent94117c091a253903d164a2934ea8ab1d70e9003e (diff)
AWTTilePainter.setupGraphics2DAndClipBounds(): Use 'Shape getClip()'; Use double precicion clip bounds 'all the way'; Explicitly scale image and clip w/ current scaled transform.
- Use 'Shape getClip()' Don't assume Rectangle2D, but use Shape's getBounds2D() - Use double precicion clip bounds 'all the way' Remove rounding error on clip bounds w/ start value, which was _not_ using doubles. - Explicitly scale image and clip w/ current scaled transform. Instead of abusing Graphics2D's clip shape to scale image size and clip-area, explicitly use transform both bounding boxes into transformed space, scale space and transform out (inversion). A possible NoninvertibleTransformException will be thrown while Graphics2D has not been modified.
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java32
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java28
-rw-r--r--src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java73
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java24
4 files changed, 93 insertions, 64 deletions
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index c43f218df..1ab30547a 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -53,6 +53,7 @@ import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
+import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Rectangle2D;
import java.awt.EventQueue;
@@ -835,21 +836,26 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
sendReshape = false; // clear reshape flag
final Graphics2D g2d = (Graphics2D)graphics;
- printAWTTiles.setupGraphics2DAndClipBounds(g2d, getWidth(), getHeight());
try {
- final TileRenderer tileRenderer = printAWTTiles.renderer;
- if( DEBUG ) {
- System.err.println("AWT print.0: "+tileRenderer);
- }
- do {
- if( printGLAD != GLCanvas.this ) {
- tileRenderer.display();
- } else {
- Threading.invoke(true, displayOnEDTAction, getTreeLock());
+ printAWTTiles.setupGraphics2DAndClipBounds(g2d, getWidth(), getHeight());
+ try {
+ final TileRenderer tileRenderer = printAWTTiles.renderer;
+ if( DEBUG ) {
+ System.err.println("AWT print.0: "+tileRenderer);
}
- } while ( !tileRenderer.eot() );
- } finally {
- printAWTTiles.resetGraphics2D();
+ do {
+ if( printGLAD != GLCanvas.this ) {
+ tileRenderer.display();
+ } else {
+ Threading.invoke(true, displayOnEDTAction, getTreeLock());
+ }
+ } while ( !tileRenderer.eot() );
+ } finally {
+ printAWTTiles.resetGraphics2D();
+ }
+ } catch (NoninvertibleTransformException nte) {
+ System.err.println("Catched: Inversion failed of: "+g2d.getTransform());
+ nte.printStackTrace();
}
if( DEBUG ) {
System.err.println("AWT print.X: "+printAWTTiles);
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index c66fba70b..e9d1b38d2 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -48,6 +48,7 @@ import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
+import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
@@ -612,18 +613,23 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
handleReshape = false; // ditto
final Graphics2D g2d = (Graphics2D)graphics;
- printAWTTiles.setupGraphics2DAndClipBounds(g2d, getWidth(), getHeight());
try {
- final TileRenderer tileRenderer = printAWTTiles.renderer;
- do {
- if( printGLAD != GLJPanel.this ) {
- tileRenderer.display();
- } else {
- backend.doPlainPaint();
- }
- } while ( !tileRenderer.eot() );
- } finally {
- printAWTTiles.resetGraphics2D();
+ printAWTTiles.setupGraphics2DAndClipBounds(g2d, getWidth(), getHeight());
+ try {
+ final TileRenderer tileRenderer = printAWTTiles.renderer;
+ do {
+ if( printGLAD != GLJPanel.this ) {
+ tileRenderer.display();
+ } else {
+ backend.doPlainPaint();
+ }
+ } while ( !tileRenderer.eot() );
+ } finally {
+ printAWTTiles.resetGraphics2D();
+ }
+ } catch (NoninvertibleTransformException nte) {
+ System.err.println("Catched: Inversion failed of: "+g2d.getTransform());
+ nte.printStackTrace();
}
if( DEBUG ) {
System.err.println("AWT print.X: "+printAWTTiles);
diff --git a/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java b/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java
index f3aba3902..0b24fadae 100644
--- a/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java
+++ b/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java
@@ -33,6 +33,7 @@ import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
@@ -148,18 +149,22 @@ public class AWTTilePainter {
return new Rectangle((int)Math.round(r.getX()), (int)Math.round(r.getY()),
(int)Math.round(r.getWidth()), (int)Math.round(r.getHeight()));
}
- private static Rectangle clipNegative(Rectangle in) {
+ private static Rectangle2D getClipBounds2D(Graphics2D g) {
+ final Shape shape = g.getClip();
+ return null != shape ? shape.getBounds2D() : null;
+ }
+ private static Rectangle2D clipNegative(Rectangle2D in) {
if( null == in ) { return null; }
- final Rectangle out = new Rectangle(in);
- if( 0 > out.x ) {
- out.width += out.x;
- out.x = 0;
+ double x=in.getX(), y=in.getY(), width=in.getWidth(), height=in.getHeight();
+ if( 0 > x ) {
+ width += x;
+ x = 0;
}
- if( 0 > out.y ) {
- out.height += out.y;
- out.y = 0;
+ if( 0 > y ) {
+ height += y;
+ y = 0;
}
- return out;
+ return new Rectangle2D.Double(x, y, width, height);
}
/**
@@ -177,35 +182,37 @@ public class AWTTilePainter {
* @param g2d Graphics2D instance used for transform and clipping
* @param width width of the AWT component in case clipping is null
* @param height height of the AWT component in case clipping is null
+ * @throws NoninvertibleTransformException if the {@link Graphics2D}'s {@link AffineTransform} {@link AffineTransform#invert() inversion} fails.
+ * Since inversion is tested before scaling the given {@link Graphics2D}, caller shall ignore the whole <i>term</i>.
*/
- public void setupGraphics2DAndClipBounds(Graphics2D g2d, int width, int height) {
+ public void setupGraphics2DAndClipBounds(Graphics2D g2d, int width, int height) throws NoninvertibleTransformException {
this.g2d = g2d;
saveAT = g2d.getTransform();
- final Rectangle gClipOrigR;
- final Rectangle2D dClipOrig, dImageSizeOrig; // double precision for scaling
- // setup original rectangles
- {
- gClipOrigR = g2d.getClipBounds();
- final Rectangle gClipOrig = clipNegative(gClipOrigR);
- dClipOrig = null != gClipOrig ? new Rectangle2D.Double(gClipOrig.getX(), gClipOrig.getY(), gClipOrig.getWidth(), gClipOrig.getHeight()) : null;
- dImageSizeOrig = new Rectangle2D.Double(0, 0, width, height);
- }
- final Rectangle2D dClipScaled, dImageSizeScaled; // double precision for scaling
- // retrieve scaled image-size and clip-bounds
+ // We use double precision for scaling
+ //
+ // Setup original rectangles
+ final Rectangle2D dClipOrigR = getClipBounds2D(g2d);
+ final Rectangle2D dClipOrig = clipNegative(dClipOrigR);
+ final Rectangle2D dImageSizeOrig = new Rectangle2D.Double(0, 0, width, height);
+
+ // Retrieve scaled image-size and clip-bounds
+ final Rectangle2D dImageSizeScaled, dClipScaled;
{
- g2d.setClip(dImageSizeOrig);
- g2d.scale(scaleMatX, scaleMatY);
- dImageSizeScaled = (Rectangle2D) g2d.getClip();
+ final AffineTransform scaledATI;
+ {
+ final AffineTransform scaledAT = g2d.getTransform();
+ scaledAT.scale(scaleMatX, scaleMatY);
+ scaledATI = scaledAT.createInverse(); // -> NoninvertibleTransformException
+ }
+ Shape s0 = saveAT.createTransformedShape(dImageSizeOrig); // user in
+ dImageSizeScaled = scaledATI.createTransformedShape(s0).getBounds2D(); // scaled out
if( null == dClipOrig ) {
- g2d.setClip(null);
dClipScaled = (Rectangle2D) dImageSizeScaled.clone();
} else {
- g2d.setTransform(saveAT); // reset
- g2d.setClip(dClipOrig);
- g2d.scale(scaleMatX, scaleMatY);
- dClipScaled = (Rectangle2D) g2d.getClip();
+ s0 = saveAT.createTransformedShape(dClipOrig); // user in
+ dClipScaled = scaledATI.createTransformedShape(s0).getBounds2D(); // scaled out
}
- }
+ }
final Rectangle iClipScaled = getRoundedRect(dClipScaled);
final Rectangle iImageSizeScaled = getRoundedRect(dImageSizeScaled);
scaledYOffset = iClipScaled.y;
@@ -213,9 +220,13 @@ public class AWTTilePainter {
renderer.clipImageSize(iClipScaled.width, iClipScaled.height);
final int clipH = Math.min(iImageSizeScaled.height, iClipScaled.height);
renderer.setTileOffset(iClipScaled.x, iImageSizeScaled.height - ( iClipScaled.y + clipH ));
+
+ // Scale actual Grahics2D matrix
+ g2d.scale(scaleMatX, scaleMatY);
+
if( verbose ) {
System.err.println("AWT print.0: image "+dImageSizeOrig + " -> " + dImageSizeScaled + " -> " + iImageSizeScaled);
- System.err.println("AWT print.0: clip "+gClipOrigR + " -> " + dClipOrig + " -> " + dClipScaled + " -> " + iClipScaled);
+ System.err.println("AWT print.0: clip "+dClipOrigR + " -> " + dClipOrig + " -> " + dClipScaled + " -> " + iClipScaled);
System.err.println("AWT print.0: "+renderer);
}
}
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index 64e9bb0f6..374a80325 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -37,6 +37,7 @@ import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.KeyboardFocusManager;
+import java.awt.geom.NoninvertibleTransformException;
import java.beans.Beans;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@@ -577,17 +578,22 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
}
final Graphics2D g2d = (Graphics2D)graphics;
- printAWTTiles.setupGraphics2DAndClipBounds(g2d, getWidth(), getHeight());
try {
- final TileRenderer tileRenderer = printAWTTiles.renderer;
- if( DEBUG ) {
- System.err.println("AWT print.0: "+tileRenderer);
+ printAWTTiles.setupGraphics2DAndClipBounds(g2d, getWidth(), getHeight());
+ try {
+ final TileRenderer tileRenderer = printAWTTiles.renderer;
+ if( DEBUG ) {
+ System.err.println("AWT print.0: "+tileRenderer);
+ }
+ do {
+ tileRenderer.display();
+ } while ( !tileRenderer.eot() );
+ } finally {
+ printAWTTiles.resetGraphics2D();
}
- do {
- tileRenderer.display();
- } while ( !tileRenderer.eot() );
- } finally {
- printAWTTiles.resetGraphics2D();
+ } catch (NoninvertibleTransformException nte) {
+ System.err.println("Catched: Inversion failed of: "+g2d.getTransform());
+ nte.printStackTrace();
}
if( DEBUG ) {
System.err.println("AWT print.X: "+printAWTTiles);