aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-09-15 23:27:16 +0200
committerSven Gothel <[email protected]>2013-09-15 23:27:16 +0200
commitc2ce31e11eefcf1b900c0e9b41264f5d5566dc46 (patch)
tree09cc72c0b515bb18062e2bdf14f651981759f6bc /src
parent5a946df8fd812570826f267d4123b59d79c97cf7 (diff)
Fix AWT printing issues w/ overlapping and/or non-opaque contents ; Change AWTPrintLifecycle's lifecycle
- AWTPrintLifecycle: - Should decorate: PrinterJob.print(..), instead of within Printable.print(..) { .. container.printAll(..); .. } This is due to AWT print implementation, i.e. AWT will issue Printable.print(..) multiple times for 'overlapping' or non-opaque elements! - Move from javax.media.opengl.awt -> com.jogamp.nativewindow.awt - Make _interface_ AWT agnostic, i.e. remove Graphics2D from 'setup(..)' - Add 'int numSamples' to 'setup(..)' to determine the number of samples - AWTTilePrinter: - Use double precision when scaling image-size and clip-rect, then round them to integer values. Otherwise AWT will use the bounding box for the clipping-rectangular. - Clip negative portion of clip-rect, this removes redundant overpaints, as well as increasing the tile count due to the increased clipping-size. - Clip the image-size in the tile-renderer according to the clip-rect. - DEBUG_TILES: Dump tiles to file - Use sub-image of final BuffereImage instead of adding another clipping region. This might increase performance if no clip-rect has been set. TODO: TestTiledPrintingGearsSwingAWT overlapping tests exposes a 'off by one' bug of the first layer's background! Note: The GL content seems to be correct though - maybe it's simply an AWT rounding error ..
Diffstat (limited to 'src')
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java33
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java47
-rw-r--r--src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java189
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTPrintLifecycle.java (renamed from src/jogl/classes/javax/media/opengl/awt/AWTPrintLifecycle.java)54
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java63
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsAWT.java14
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsNewtAWT.java14
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsSwingAWT.java73
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/tile/TiledPrintingAWTBase.java123
9 files changed, 363 insertions, 247 deletions
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 4e0fdba5d..a519e33bb 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -53,7 +53,6 @@ import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
-import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.EventQueue;
@@ -94,6 +93,7 @@ import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.nativewindow.awt.AWTGraphicsConfiguration;
import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
import com.jogamp.nativewindow.awt.AWTGraphicsScreen;
+import com.jogamp.nativewindow.awt.AWTPrintLifecycle;
import com.jogamp.nativewindow.awt.AWTWindowClosingProtocol;
import com.jogamp.nativewindow.awt.JAWTWindow;
import com.jogamp.opengl.JoglVersion;
@@ -725,13 +725,13 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
private volatile boolean printActive = false;
- private boolean printUseAA = false;
+ private int printNumSamples = 0;
private GLAnimatorControl printAnimator = null;
private GLAutoDrawable printGLAD = null;
private AWTTilePainter printAWTTiles = null;
@Override
- public void setupPrint(Graphics2D g2d, double scaleMatX, double scaleMatY) {
+ public void setupPrint(double scaleMatX, double scaleMatY, int numSamples) {
if( !validateGLDrawable() ) {
if(DEBUG) {
System.err.println(getThreadName()+": Info: GLCanvas setupPrint - skipped GL render, drawable not valid yet");
@@ -746,14 +746,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
printActive = true;
sendReshape = false; // clear reshape flag
- final RenderingHints rHints = g2d.getRenderingHints();
- {
- final Object _useAA = rHints.get(RenderingHints.KEY_ANTIALIASING);
- printUseAA = null != _useAA && ( _useAA == RenderingHints.VALUE_ANTIALIAS_DEFAULT || _useAA == RenderingHints.VALUE_ANTIALIAS_ON );
- }
+ printNumSamples = AWTTilePainter.getNumSamples(numSamples, getChosenGLCapabilities());
if( DEBUG ) {
- System.err.println("AWT print.setup: canvasSize "+getWidth()+"x"+getWidth()+", scaleMat "+scaleMatX+" x "+scaleMatY+", useAA "+printUseAA+", printAnimator "+printAnimator);
- AWTTilePainter.dumpHintsAndScale(g2d);
+ System.err.println("AWT print.setup: canvasSize "+getWidth()+"x"+getWidth()+", scaleMat "+scaleMatX+" x "+scaleMatY+", numSamples "+numSamples+" -> "+printNumSamples+", printAnimator "+printAnimator);
}
final int componentCount = isOpaque() ? 3 : 4;
final TileRenderer printRenderer = new TileRenderer();
@@ -769,23 +764,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
printAnimator.remove(GLCanvas.this);
}
final GLCapabilities caps = (GLCapabilities)getChosenGLCapabilities().cloneMutable();
- final GLProfile glp = caps.getGLProfile();
if( caps.getSampleBuffers() ) {
- // bug / issue w/ swapGLContextAndAllGLEventListener and onscreen MSAA w/ NV/GLX
+ // Bug 830: swapGLContextAndAllGLEventListener and onscreen MSAA w/ NV/GLX
printGLAD = GLCanvas.this;
} else {
caps.setDoubleBuffered(false);
caps.setOnscreen(false);
- if( printUseAA && !caps.getSampleBuffers() ) {
- if ( !glp.isGL2ES3() ) {
- if( DEBUG ) {
- System.err.println("Ignore MSAA due to gl-profile < GL2ES3");
- }
- printUseAA = false;
- } else {
- caps.setSampleBuffers(true);
- caps.setNumSamples(8);
- }
+ if( printNumSamples != caps.getNumSamples() ) {
+ caps.setSampleBuffers(0 < printNumSamples);
+ caps.setNumSamples(printNumSamples);
}
final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
printGLAD = factory.createOffscreenAutoDrawable(null, caps, null, DEFAULT_PRINT_TILE_SIZE, DEFAULT_PRINT_TILE_SIZE, null);
@@ -796,7 +783,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
printAWTTiles.renderer.attachToAutoDrawable(printGLAD);
if( DEBUG ) {
System.err.println("AWT print.setup "+printAWTTiles);
- System.err.println("AWT print.setup AA "+printUseAA+", "+caps);
+ System.err.println("AWT print.setup AA "+printNumSamples+", "+caps);
System.err.println("AWT print.setup "+printGLAD);
}
}
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index 02f4e54a7..f0c6b7beb 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -48,7 +48,6 @@ import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
-import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
@@ -90,6 +89,7 @@ import jogamp.opengl.awt.Java2D;
import jogamp.opengl.util.glsl.GLSLTextureRaster;
import com.jogamp.common.util.awt.AWTEDTExecutor;
+import com.jogamp.nativewindow.awt.AWTPrintLifecycle;
import com.jogamp.nativewindow.awt.AWTWindowClosingProtocol;
import com.jogamp.opengl.FBObject;
import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes;
@@ -424,7 +424,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
createAndInitializeBackend();
}
- if (!isInitialized) {
+ if (!isInitialized || printActive) {
return;
}
@@ -498,13 +498,13 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
private volatile boolean printActive = false;
- private boolean printUseAA = false;
+ private int printNumSamples = 0;
private GLAnimatorControl printAnimator = null;
private GLAutoDrawable printGLAD = null;
private AWTTilePainter printAWTTiles = null;
@Override
- public void setupPrint(Graphics2D g2d, double scaleMatX, double scaleMatY) {
+ public void setupPrint(double scaleMatX, double scaleMatY, int numSamples) {
if (!isInitialized) {
if(DEBUG) {
System.err.println(getThreadName()+": Info: GLJPanel setupPrint - skipped GL render, drawable not valid yet");
@@ -520,14 +520,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
printActive = true;
sendReshape = false; // clear reshape flag
handleReshape = false; // ditto
- final RenderingHints rHints = g2d.getRenderingHints();
- {
- final Object _useAA = rHints.get(RenderingHints.KEY_ANTIALIASING);
- printUseAA = null != _useAA && ( _useAA == RenderingHints.VALUE_ANTIALIAS_DEFAULT || _useAA == RenderingHints.VALUE_ANTIALIAS_ON );
- }
+ printNumSamples = AWTTilePainter.getNumSamples(numSamples, getChosenGLCapabilities());
if( DEBUG ) {
- System.err.println("AWT print.setup: canvasSize "+getWidth()+"x"+getWidth()+", scaleMat "+scaleMatX+" x "+scaleMatY+", useAA "+printUseAA+", printAnimator "+printAnimator);
- AWTTilePainter.dumpHintsAndScale(g2d);
+ System.err.println("AWT print.setup: canvasSize "+getWidth()+"x"+getWidth()+", scaleMat "+scaleMatX+" x "+scaleMatY+", numSamples "+numSamples+" -> "+printNumSamples+", printAnimator "+printAnimator);
}
final int componentCount = isOpaque() ? 3 : 4;
final TileRenderer printRenderer = new TileRenderer();
@@ -546,30 +541,21 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
printGLAD = GLJPanel.this; // default: re-use
final GLCapabilities caps = (GLCapabilities)getChosenGLCapabilities().cloneMutable();
- final GLProfile glp = caps.getGLProfile();
- if( printUseAA && !caps.getSampleBuffers() ) {
- if ( !glp.isGL2ES3() ) {
- if( DEBUG ) {
- System.err.println("Ignore MSAA due to gl-profile < GL2ES3");
- }
- printUseAA = false;
- } else {
- // MSAA FBO ..
- caps.setDoubleBuffered(false);
- caps.setOnscreen(false);
- caps.setSampleBuffers(true);
- caps.setNumSamples(8);
- final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
- printGLAD = factory.createOffscreenAutoDrawable(null, caps, null, DEFAULT_PRINT_TILE_SIZE, DEFAULT_PRINT_TILE_SIZE, null);
- GLDrawableUtil.swapGLContextAndAllGLEventListener(GLJPanel.this, printGLAD);
- }
+ if( printNumSamples != caps.getNumSamples() ) {
+ caps.setDoubleBuffered(false);
+ caps.setOnscreen(false);
+ caps.setSampleBuffers(0 < printNumSamples);
+ caps.setNumSamples(printNumSamples);
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
+ printGLAD = factory.createOffscreenAutoDrawable(null, caps, null, DEFAULT_PRINT_TILE_SIZE, DEFAULT_PRINT_TILE_SIZE, null);
+ GLDrawableUtil.swapGLContextAndAllGLEventListener(GLJPanel.this, printGLAD);
}
printAWTTiles.setIsGLOriented(printGLAD.isGLOriented());
printAWTTiles.renderer.setTileSize(printGLAD.getWidth(), printGLAD.getHeight(), 0);
printAWTTiles.renderer.attachToAutoDrawable(printGLAD);
if( DEBUG ) {
System.err.println("AWT print.setup "+printAWTTiles);
- System.err.println("AWT print.setup AA "+printUseAA+", "+caps);
+ System.err.println("AWT print.setup AA "+printNumSamples+", "+caps);
System.err.println("AWT print.setup "+printGLAD);
}
}
@@ -624,9 +610,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
printAWTTiles.setupGraphics2DAndClipBounds(g2d, getWidth(), getHeight());
try {
final TileRenderer tileRenderer = printAWTTiles.renderer;
- if( DEBUG ) {
- System.err.println("AWT print.0: "+tileRenderer);
- }
do {
if( printGLAD != GLJPanel.this ) {
tileRenderer.display();
diff --git a/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java b/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java
index 0ff733457..b16273b35 100644
--- a/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java
+++ b/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java
@@ -33,16 +33,25 @@ import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.Set;
import java.util.Map.Entry;
+import javax.imageio.ImageIO;
+import javax.media.nativewindow.util.DimensionImmutable;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLEventListener;
+import jogamp.opengl.Debug;
+
import com.jogamp.opengl.util.TileRenderer;
import com.jogamp.opengl.util.TileRendererBase;
import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes;
@@ -56,6 +65,8 @@ import com.jogamp.opengl.util.awt.AWTGLPixelBuffer.AWTGLPixelBufferProvider;
* </p>
*/
public class AWTTilePainter {
+ private static final boolean DEBUG_TILES = Debug.debug("TileRenderer");
+
public final TileRenderer renderer;
public final int componentCount;
public final double scaleMatX, scaleMatY;
@@ -76,8 +87,28 @@ public class AWTTilePainter {
System.err.println("Hint["+count+"]: "+rEntry.getKey()+" -> "+rEntry.getValue());
}
final AffineTransform aTrans = g2d.getTransform();
+ System.err.println(" type "+aTrans.getType());
System.err.println(" scale "+aTrans.getScaleX()+" x "+aTrans.getScaleY());
System.err.println(" move "+aTrans.getTranslateX()+" x "+aTrans.getTranslateY());
+ System.err.println(" mat "+aTrans);
+ }
+
+ /**
+ * @param numSamples multisampling value: < 0 turns off, == 0 leaves as-is, > 0 enables using given num samples
+ * @param caps used capabilties
+ * @return resulting number of samples, 0 if disabled
+ */
+ public static int getNumSamples(int numSamples, GLCapabilitiesImmutable caps) {
+ if( 0 > numSamples ) {
+ return 0;
+ } else if( 0 < numSamples ) {
+ if ( !caps.getGLProfile().isGL2ES3() ) {
+ return 0;
+ }
+ return Math.max(caps.getNumSamples(), numSamples);
+ } else {
+ return caps.getNumSamples();
+ }
}
/**
@@ -104,7 +135,6 @@ public class AWTTilePainter {
this.scaleMatY = scaleMatY;
this.verbose = verbose;
this.flipVertical = true;
- this.renderer.setRowOrder(TileRenderer.TR_TOP_TO_BOTTOM);
}
public String toString() { return renderer.toString(); }
@@ -113,6 +143,25 @@ public class AWTTilePainter {
flipVertical = v;
}
+ private static Rectangle getRoundedRect(Rectangle2D r) {
+ if( null == r ) { return null; }
+ 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) {
+ if( null == in ) { return null; }
+ final Rectangle out = new Rectangle(in);
+ if( 0 > out.x ) {
+ out.width += out.x;
+ out.x = 0;
+ }
+ if( 0 > out.y ) {
+ out.height += out.y;
+ out.y = 0;
+ }
+ return out;
+ }
+
/**
* Caches the {@link Graphics2D} instance for rendering.
* <p>
@@ -132,31 +181,49 @@ public class AWTTilePainter {
public void setupGraphics2DAndClipBounds(Graphics2D g2d, int width, int height) {
this.g2d = g2d;
saveAT = g2d.getTransform();
- final Rectangle gClipOrig = g2d.getClipBounds();
- if( null == gClipOrig ) {
- g2d.setClip(0, 0, width, height);
+ 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);
}
- g2d.scale(scaleMatX, scaleMatY);
-
- final Rectangle gClipScaled = g2d.getClipBounds();
- if( 0 > gClipScaled.x ) {
- gClipScaled.width += gClipScaled.x;
- gClipScaled.x = 0;
+ final Rectangle2D dClipScaled, dImageSizeScaled; // double precision for scaling
+ // retrieve scaled image-size and clip-bounds
+ {
+ g2d.setClip(dImageSizeOrig);
+ g2d.scale(scaleMatX, scaleMatY);
+ dImageSizeScaled = (Rectangle2D) g2d.getClip();
+ 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();
+ }
}
- if( 0 > gClipScaled.y ) {
- gClipScaled.height += gClipScaled.y;
- gClipScaled.y = 0;
+ final Rectangle iClipScaled = getRoundedRect(dClipScaled);
+ final Rectangle iImageSizeScaled = getRoundedRect(dImageSizeScaled);
+ scaledYOffset = iClipScaled.y;
+ renderer.setImageSize(iImageSizeScaled.width, iImageSizeScaled.height);
+ renderer.clipImageSize(iClipScaled.width, iClipScaled.height);
+ final int clipH = Math.min(iImageSizeScaled.height, iClipScaled.height);
+ if( flipVertical ) {
+ renderer.setTileOffset(iClipScaled.x, iImageSizeScaled.height - ( iClipScaled.y + clipH ));
+ } else {
+ renderer.setTileOffset(iClipScaled.x, iClipScaled.y);
}
if( verbose ) {
- System.err.println("AWT print.0: "+gClipOrig+" -> "+gClipScaled);
- }
- renderer.setImageSize(gClipScaled.width, gClipScaled.height);
- renderer.setTileOffset(gClipScaled.x, gClipScaled.y);
- if( null == gClipOrig ) {
- // reset
- g2d.setClip(null);
+ 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: "+renderer);
}
}
+ private int scaledYOffset;
/** See {@ #setupGraphics2DAndClipBounds(Graphics2D)}. */
public void resetGraphics2D() {
@@ -208,28 +275,55 @@ public class AWTTilePainter {
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {}
};
+ static int _counter = 0;
final GLEventListener postTileGLEL = new GLEventListener() {
- int tTopRowHeight = 0;
@Override
public void init(GLAutoDrawable drawable) {
- tTopRowHeight = 0;
}
@Override
public void dispose(GLAutoDrawable drawable) {}
@Override
public void display(GLAutoDrawable drawable) {
+ final DimensionImmutable cis = renderer.getClippedImageSize();
+ final int tWidth = renderer.getParam(TileRendererBase.TR_CURRENT_TILE_WIDTH);
+ final int tHeight = renderer.getParam(TileRendererBase.TR_CURRENT_TILE_HEIGHT);
+ final int pX = renderer.getParam(TileRendererBase.TR_CURRENT_TILE_X_POS);
+ final int pY = renderer.getParam(TileRendererBase.TR_CURRENT_TILE_Y_POS);
+ final int pYOff = renderer.getParam(TileRenderer.TR_TILE_Y_OFFSET);
+ final int pYf;
+ if( flipVertical ) {
+ pYf = cis.getHeight() - ( pY - pYOff + tHeight ) + scaledYOffset;
+ } else {
+ pYf = pY;
+ }
+
// Copy temporary data into raster of BufferedImage for faster
// blitting Note that we could avoid this copy in the cases
// where !offscreenDrawable.isGLOriented(),
// but that's the software rendering path which is very slow anyway.
- final int tWidth = renderer.getParam(TileRendererBase.TR_CURRENT_TILE_WIDTH);
- final int tHeight = renderer.getParam(TileRendererBase.TR_CURRENT_TILE_HEIGHT);
final BufferedImage dstImage;
+ if( DEBUG_TILES ) {
+ final String fname = String.format("file_%03d_0_tile_[%02d][%02d]_sz_%03dx%03d_pos0_%03d_%03d_yOff_%03d_pos1_%03d_%03d.png",
+ _counter,
+ renderer.getParam(TileRenderer.TR_CURRENT_COLUMN), renderer.getParam(TileRenderer.TR_CURRENT_ROW),
+ tWidth, tHeight,
+ pX, pY, pYOff, pX, pYf).replace(' ', '_');
+ System.err.println("XXX file "+fname);
+ final File fout = new File(fname);
+ try {
+ ImageIO.write(tBuffer.image, "png", fout);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
if( flipVertical ) {
final BufferedImage srcImage = tBuffer.image;
dstImage = vFlipImage;
final int[] src = ((DataBufferInt) srcImage.getRaster().getDataBuffer()).getData();
final int[] dst = ((DataBufferInt) dstImage.getRaster().getDataBuffer()).getData();
+ if( DEBUG_TILES ) {
+ Arrays.fill(dst, 0x55);
+ }
final int incr = tBuffer.width;
int srcPos = 0;
int destPos = (tHeight - 1) * tBuffer.width;
@@ -239,28 +333,31 @@ public class AWTTilePainter {
} else {
dstImage = tBuffer.image;
}
- // Draw resulting image in one shot
- final int tRows = renderer.getParam(TileRenderer.TR_ROWS);
- final int tRow = renderer.getParam(TileRenderer.TR_CURRENT_ROW);
- final int pX = renderer.getParam(TileRendererBase.TR_CURRENT_TILE_X_POS);
- final int pYf;
- if( flipVertical ) {
- if( tRow == tRows - 1 ) {
- tTopRowHeight = tHeight;
- pYf = 0;
- } else if( tRow == tRows - 2 ){
- pYf = tTopRowHeight;
- } else {
- pYf = ( tRows - 2 - tRow ) * tHeight + tTopRowHeight;
+ if( DEBUG_TILES ) {
+ final String fname = String.format("file_%03d_1_tile_[%02d][%02d]_sz_%03dx%03d_pos0_%03d_%03d_yOff_%03d_pos1_%03d_%03d.png",
+ _counter,
+ renderer.getParam(TileRenderer.TR_CURRENT_COLUMN), renderer.getParam(TileRenderer.TR_CURRENT_ROW),
+ tWidth, tHeight,
+ pX, pY, pYOff, pX, pYf).replace(' ', '_');
+ System.err.println("XXX file "+fname);
+ final File fout = new File(fname);
+ try {
+ ImageIO.write(dstImage, "png", fout);
+ } catch (IOException e) {
+ e.printStackTrace();
}
- } else {
- pYf = renderer.getParam(TileRendererBase.TR_CURRENT_TILE_Y_POS);
- }
+ _counter++;
+ }
+ // Draw resulting image in one shot
final Shape oClip = g2d.getClip();
- g2d.clipRect(pX, pYf, tWidth, tHeight);
- g2d.drawImage(dstImage, pX, pYf, dstImage.getWidth(), dstImage.getHeight(), null); // Null ImageObserver since image data is ready.
+ // g2d.clipRect(pX, pYf, tWidth, tHeight);
+ final BufferedImage outImage = dstImage.getSubimage(0, 0, tWidth, tHeight); // instead of clipping
+ final boolean drawDone = g2d.drawImage(outImage, pX, pYf, null); // Null ImageObserver since image data is ready.
+ // final boolean drawDone = g2d.drawImage(dstImage, pX, pYf, dstImage.getWidth(), dstImage.getHeight(), null); // Null ImageObserver since image data is ready.
if( verbose ) {
- System.err.println("XXX tile-post.X clip "+oClip+" -> "+g2d.getClip());
+ System.err.println("XXX tile-post.X clippedImageSize "+cis);
+ System.err.println("XXX tile-post.X pYf "+cis.getHeight()+" - ( "+pY+" - "+pYOff+" + "+tHeight+" ) "+scaledYOffset+" = "+ pYf);
+ System.err.println("XXX tile-post.X clip "+oClip+" + "+pX+" / [pY "+pY+", pYOff "+pYOff+", pYf "+pYf+"] "+tWidth+"x"+tHeight+" -> "+g2d.getClip());
g2d.setColor(Color.BLACK);
g2d.drawRect(pX, pYf, tWidth, tHeight);
if( null != oClip ) {
@@ -269,9 +366,11 @@ public class AWTTilePainter {
g2d.drawRect(r.x, r.y, r.width, r.height);
}
System.err.println("XXX tile-post.X "+renderer);
- System.err.println("XXX tile-post.X dst-img "+dstImage.getWidth()+"x"+dstImage.getHeight()+", y-flip "+flipVertical+" -> "+pX+"/"+pYf);
+ System.err.println("XXX tile-post.X dst-img "+dstImage.getWidth()+"x"+dstImage.getHeight());
+ System.err.println("XXX tile-post.X out-img "+outImage.getWidth()+"x"+dstImage.getHeight());
+ System.err.println("XXX tile-post.X y-flip "+flipVertical+" -> "+pX+"/"+pYf+", drawDone "+drawDone);
}
- g2d.setClip(oClip);
+ // g2d.setClip(oClip);
}
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {}
diff --git a/src/jogl/classes/javax/media/opengl/awt/AWTPrintLifecycle.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTPrintLifecycle.java
index 1a4c5bac0..a54f6bac6 100644
--- a/src/jogl/classes/javax/media/opengl/awt/AWTPrintLifecycle.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTPrintLifecycle.java
@@ -25,41 +25,47 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
-package javax.media.opengl.awt;
+package com.jogamp.nativewindow.awt;
-import javax.media.opengl.GLAutoDrawable;
import java.awt.Component;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
+import java.awt.print.PrinterJob;
import jogamp.nativewindow.awt.AWTMisc;
/**
- * Interface describing print lifecycle to support AWT printing
- * on AWT {@link GLAutoDrawable}s.
+ * Interface describing print lifecycle to support AWT printing,
+ * e.g. on AWT {@link javax.media.opengl.GLAutoDrawable GLAutoDrawable}s.
* <a name="impl"><h5>Implementations</h5></a>
* <p>
- * Implementing {@link GLAutoDrawable} classes based on AWT
+ * Implementing {@link javax.media.opengl.GLAutoDrawable GLAutoDrawable} classes based on AWT
* supporting {@link Component#print(Graphics)} shall implement this interface.
* </p>
* <a name="usage"><h5>Usage</h5></a>
* <p>
* Users attempting to print an AWT {@link Container} containing {@link AWTPrintLifecycle} elements
* shall consider decorating the {@link Container#printAll(Graphics)} call with<br>
- * {@link #setupPrint(Graphics2D, double, double) setupPrint(..)} and {@link #releasePrint()}
+ * {@link #setupPrint(double, double, int) setupPrint(..)} and {@link #releasePrint()}
* on all {@link AWTPrintLifecycle} elements in the {@link Container}.<br>
- * To minimize this burden, a user can use {@link Context#setupPrint(Container, Graphics2D, double, double) Context.setupPrint(..)}:
+ * To minimize this burden, a user can use {@link Context#setupPrint(Container, double, double, int) Context.setupPrint(..)}:
* <pre>
* Graphics2D g2d;
- * Frame frame;
+ * Container cont;
* double scaleGLMatXY = 72.0/glDPI;
+ * int numSamples = 0; // leave multisampling as-is
+ * PrinterJob job;
* ...
- final AWTPrintLifecycle.Context ctx = AWTPrintLifecycle.Context.setupPrint(frame, g2d, scaleGLMatXY, scaleGLMatXY);
+ final AWTPrintLifecycle.Context ctx = AWTPrintLifecycle.Context.setupPrint(cont, scaleGLMatXY, scaleGLMatXY, numSamples);
try {
AWTEDTExecutor.singleton.invoke(true, new Runnable() {
public void run() {
- frame.printAll(g2d);
+ try {
+ job.print();
+ } catch (PrinterException ex) {
+ ex.printStackTrace();
+ }
} });
} finally {
ctx.releasePrint();
@@ -74,18 +80,18 @@ public interface AWTPrintLifecycle {
/**
- * Shall be called before {@link Component#print(Graphics)}.
+ * Shall be called before {@link PrinterJob#print()}.
* <p>
* See <a href="#usage">Usage</a>.
* </p>
- * @param g2d the {@link Graphics2D} instance, which will be used for printing.
* @param scaleMatX {@link Graphics2D} {@link Graphics2D#scale(double, double) scaling factor}, i.e. rendering 1/scaleMatX * width pixels
* @param scaleMatY {@link Graphics2D} {@link Graphics2D#scale(double, double) scaling factor}, i.e. rendering 1/scaleMatY * height pixels
+ * @param numSamples multisampling value: < 0 turns off, == 0 leaves as-is, > 0 enables using given num samples
*/
- void setupPrint(Graphics2D g2d, double scaleMatX, double scaleMatY);
+ void setupPrint(double scaleMatX, double scaleMatY, int numSamples);
/**
- * Shall be called after very last {@link Component#print(Graphics)}.
+ * Shall be called after {@link PrinterJob#print()}.
* <p>
* See <a href="#usage">Usage</a>.
* </p>
@@ -93,7 +99,7 @@ public interface AWTPrintLifecycle {
void releasePrint();
/**
- * Convenient {@link AWTPrintLifecycle} context simplifying calling {@link AWTPrintLifecycle#setupPrint(Graphics2D, double, double) setupPrint(..)}
+ * Convenient {@link AWTPrintLifecycle} context simplifying calling {@link AWTPrintLifecycle#setupPrint(double, double, int) setupPrint(..)}
* and {@link AWTPrintLifecycle#releasePrint()} on all {@link AWTPrintLifecycle} elements of a {@link Container}.
* <p>
* See <a href="#usage">Usage</a>.
@@ -105,14 +111,14 @@ public interface AWTPrintLifecycle {
* See <a href="#usage">Usage</a>.
* </p>
*
- * @param c container to be traversed through to perform {@link AWTPrintLifecycle#setupPrint(Graphics2D, double, double) setupPrint(..)} on all {@link AWTPrintLifecycle} elements.
- * @param g2d the {@link Graphics2D} instance, which will be used for printing.
+ * @param c container to be traversed through to perform {@link AWTPrintLifecycle#setupPrint(double, double, int) setupPrint(..)} on all {@link AWTPrintLifecycle} elements.
* @param scaleMatX {@link Graphics2D} {@link Graphics2D#scale(double, double) scaling factor}, i.e. rendering 1/scaleMatX * width pixels
* @param scaleMatY {@link Graphics2D} {@link Graphics2D#scale(double, double) scaling factor}, i.e. rendering 1/scaleMatY * height pixels
+ * @param numSamples multisampling value: < 0 turns off, == 0 leaves as-is, > 0 enables using given num samples
* @return the context
*/
- public static Context setupPrint(Container c, Graphics2D g2d, double scaleMatX, double scaleMatY) {
- final Context t = new Context(c, g2d, scaleMatX, scaleMatY);
+ public static Context setupPrint(Container c, double scaleMatX, double scaleMatY, int numSamples) {
+ final Context t = new Context(c, scaleMatX, scaleMatY, numSamples);
t.setupPrint(c);
return t;
}
@@ -127,20 +133,20 @@ public interface AWTPrintLifecycle {
}
/**
- * @return count of performed actions of last {@link #setupPrint(Container, Graphics2D, double, double) setupPrint(..)} or {@link #releasePrint()}.
+ * @return count of performed actions of last {@link #setupPrint(Container, double, double, int) setupPrint(..)} or {@link #releasePrint()}.
*/
public int getCount() { return count; }
private final Container cont;
- private final Graphics2D g2d;
private final double scaleMatX;
private final double scaleMatY;
+ private final int numSamples;
private int count;
private final AWTMisc.ComponentAction setupAction = new AWTMisc.ComponentAction() {
@Override
public void run(Component c) {
- ((AWTPrintLifecycle)c).setupPrint(g2d, scaleMatX, scaleMatY);
+ ((AWTPrintLifecycle)c).setupPrint(scaleMatX, scaleMatY, numSamples);
} };
private final AWTMisc.ComponentAction releaseAction = new AWTMisc.ComponentAction() {
@Override
@@ -148,11 +154,11 @@ public interface AWTPrintLifecycle {
((AWTPrintLifecycle)c).releasePrint();
} };
- private Context(Container c, Graphics2D g2d, double scaleMatX, double scaleMatY) {
+ private Context(Container c, double scaleMatX, double scaleMatY, int numSamples) {
this.cont = c;
- this.g2d = g2d;
this.scaleMatX = scaleMatX;
this.scaleMatY = scaleMatY;
+ this.numSamples = numSamples;
this.count = 0;
}
private void setupPrint(Container c) {
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index cdf47cbb3..a2d4eb7f0 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -37,7 +37,6 @@ import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.KeyboardFocusManager;
-import java.awt.RenderingHints;
import java.beans.Beans;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@@ -53,8 +52,6 @@ import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLProfile;
-import javax.media.opengl.awt.AWTPrintLifecycle;
import javax.swing.MenuSelectionManager;
import jogamp.nativewindow.awt.AWTMisc;
@@ -67,6 +64,7 @@ import jogamp.opengl.awt.AWTTilePainter;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.awt.AWTEDTExecutor;
+import com.jogamp.nativewindow.awt.AWTPrintLifecycle;
import com.jogamp.nativewindow.awt.AWTWindowClosingProtocol;
import com.jogamp.nativewindow.awt.JAWTWindow;
import com.jogamp.newt.Display;
@@ -455,13 +453,20 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
}
private volatile boolean printActive = false;
- private boolean printUseAA = false;
+ private int printNumSamples = 0;
private GLAnimatorControl printAnimator = null;
private GLAutoDrawable printGLAD = null;
private AWTTilePainter printAWTTiles = null;
+ private final GLAutoDrawable getGLAD() {
+ if( null != newtChild && newtChild instanceof GLAutoDrawable ) {
+ return (GLAutoDrawable)newtChild;
+ }
+ return null;
+ }
+
@Override
- public void setupPrint(Graphics2D g2d, double scaleMatX, double scaleMatY) {
+ public void setupPrint(double scaleMatX, double scaleMatY, int numSamples) {
if( !validateComponent(true) ) {
if(DEBUG) {
System.err.println(getThreadName()+": Info: NewtCanvasAWT setupPrint - skipped GL render, drawable not valid yet");
@@ -474,15 +479,17 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
}
return; // not yet available ..
}
- printActive = true;
- final RenderingHints rHints = g2d.getRenderingHints();
- {
- final Object _useAA = rHints.get(RenderingHints.KEY_ANTIALIASING);
- printUseAA = null != _useAA && ( _useAA == RenderingHints.VALUE_ANTIALIAS_DEFAULT || _useAA == RenderingHints.VALUE_ANTIALIAS_ON );
+ final GLAutoDrawable glad = getGLAD();
+ if( null == glad ) {
+ if( DEBUG ) {
+ System.err.println("AWT print.setup exit, newtChild not a GLAutoDrawable: "+newtChild);
+ }
+ return;
}
+ printActive = true;
+ printNumSamples = AWTTilePainter.getNumSamples(numSamples, glad.getChosenGLCapabilities());
if( DEBUG ) {
- System.err.println("AWT print.setup: canvasSize "+getWidth()+"x"+getWidth()+", scaleMat "+scaleMatX+" x "+scaleMatY+", useAA "+printUseAA+", printAnimator "+printAnimator);
- AWTTilePainter.dumpHintsAndScale(g2d);
+ System.err.println("AWT print.setup: canvasSize "+getWidth()+"x"+getWidth()+", scaleMat "+scaleMatX+" x "+scaleMatY+", numSamples "+numSamples+" -> "+printNumSamples+", printAnimator "+printAnimator);
}
final int componentCount = isOpaque() ? 3 : 4;
final TileRenderer printRenderer = new TileRenderer();
@@ -492,39 +499,21 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
private final Runnable setupPrintOnEDT = new Runnable() {
@Override
public void run() {
- final GLAutoDrawable glad;
- if( null != newtChild && newtChild instanceof GLAutoDrawable ) {
- glad = (GLAutoDrawable)newtChild;
- } else {
- if( DEBUG ) {
- System.err.println("AWT print.setup exit, newtChild not a GLAutoDrawable: "+newtChild);
- }
- printAWTTiles = null;
- printActive = false;
- return;
- }
+ final GLAutoDrawable glad = getGLAD();
printAnimator = glad.getAnimator();
if( null != printAnimator ) {
printAnimator.remove(glad);
}
final GLCapabilities caps = (GLCapabilities)glad.getChosenGLCapabilities().cloneMutable();
- final GLProfile glp = caps.getGLProfile();
if( caps.getSampleBuffers() ) {
- // bug / issue w/ swapGLContextAndAllGLEventListener and onscreen MSAA w/ NV/GLX
+ // Bug 830: swapGLContextAndAllGLEventListener and onscreen MSAA w/ NV/GLX
printGLAD = glad;
} else {
caps.setDoubleBuffered(false);
caps.setOnscreen(false);
- if( printUseAA && !caps.getSampleBuffers() ) {
- if ( !glp.isGL2ES3() ) {
- if( DEBUG ) {
- System.err.println("Ignore MSAA due to gl-profile < GL2ES3");
- }
- printUseAA = false;
- } else {
- caps.setSampleBuffers(true);
- caps.setNumSamples(8);
- }
+ if( printNumSamples != caps.getNumSamples() ) {
+ caps.setSampleBuffers(0 < printNumSamples);
+ caps.setNumSamples(printNumSamples);
}
final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
printGLAD = factory.createOffscreenAutoDrawable(null, caps, null, DEFAULT_PRINT_TILE_SIZE, DEFAULT_PRINT_TILE_SIZE, null);
@@ -535,7 +524,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
printAWTTiles.renderer.attachToAutoDrawable(printGLAD);
if( DEBUG ) {
System.err.println("AWT print.setup "+printAWTTiles);
- System.err.println("AWT print.setup AA "+printUseAA+", "+caps);
+ System.err.println("AWT print.setup AA "+printNumSamples+", "+caps);
System.err.println("AWT print.setup "+printGLAD);
}
}
@@ -557,7 +546,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
if( DEBUG ) {
System.err.println("AWT print.release "+printAWTTiles);
}
- final GLAutoDrawable glad = (GLAutoDrawable)newtChild;
+ final GLAutoDrawable glad = getGLAD();
printAWTTiles.dispose();
printAWTTiles= null;
if( printGLAD != glad ) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsAWT.java
index 322d2d1b5..908a89a32 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsAWT.java
@@ -115,15 +115,15 @@ public class TestTiledPrintingGearsAWT extends TiledPrintingAWTBase {
final ActionListener print72DPIAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
- doPrintManual(frame, 72, false);
+ doPrintManual(frame, 72, 0);
} };
final ActionListener print300DPIAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
- doPrintManual(frame, 300, false);
+ doPrintManual(frame, 300, -1);
} };
final ActionListener print600DPIAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
- doPrintManual(frame, 600, false);
+ doPrintManual(frame, 600, -1);
} };
final Button print72DPIButton = new Button("72dpi");
print72DPIButton.addActionListener(print72DPIAction);
@@ -176,15 +176,15 @@ public class TestTiledPrintingGearsAWT extends TiledPrintingAWTBase {
Thread.sleep(200);
if( !printDone ) {
printDone = true;
- doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, false);
+ doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, 0);
waitUntilPrintJobsIdle();
- doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, true);
+ doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, 8);
waitUntilPrintJobsIdle();
// No AA needed for 300 dpi and greater :)
- doPrintAuto(frame, PageFormat.LANDSCAPE, null, 300, false);
+ doPrintAuto(frame, PageFormat.LANDSCAPE, null, 300, -1);
waitUntilPrintJobsIdle();
if( allow600dpi ) {
- doPrintAuto(frame, PageFormat.LANDSCAPE, null, 600, false);
+ doPrintAuto(frame, PageFormat.LANDSCAPE, null, 600, -1);
waitUntilPrintJobsIdle();
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsNewtAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsNewtAWT.java
index f7f856676..c695febbe 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsNewtAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsNewtAWT.java
@@ -120,15 +120,15 @@ public class TestTiledPrintingGearsNewtAWT extends TiledPrintingAWTBase {
final ActionListener print72DPIAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
- doPrintManual(frame, 72, false);
+ doPrintManual(frame, 72, 0);
} };
final ActionListener print300DPIAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
- doPrintManual(frame, 300, false);
+ doPrintManual(frame, 300, -1);
} };
final ActionListener print600DPIAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
- doPrintManual(frame, 600, false);
+ doPrintManual(frame, 600, -1);
} };
final Button print72DPIButton = new Button("72dpi");
print72DPIButton.addActionListener(print72DPIAction);
@@ -181,15 +181,15 @@ public class TestTiledPrintingGearsNewtAWT extends TiledPrintingAWTBase {
Thread.sleep(200);
if( !printDone ) {
printDone = true;
- doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, false);
+ doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, 0);
waitUntilPrintJobsIdle();
- doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, true);
+ doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, 8);
waitUntilPrintJobsIdle();
// No AA needed for 300 dpi and greater :)
- doPrintAuto(frame, PageFormat.LANDSCAPE, null, 300, false);
+ doPrintAuto(frame, PageFormat.LANDSCAPE, null, 300, -1);
waitUntilPrintJobsIdle();
if( allow600dpi ) {
- doPrintAuto(frame, PageFormat.LANDSCAPE, null, 600, false);
+ doPrintAuto(frame, PageFormat.LANDSCAPE, null, 600, -1);
waitUntilPrintJobsIdle();
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsSwingAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsSwingAWT.java
index da577ea1d..9c5d6bf8b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsSwingAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsSwingAWT.java
@@ -45,7 +45,11 @@ import java.lang.reflect.InvocationTargetException;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLJPanel;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JComponent;
import javax.swing.JFrame;
+import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
@@ -93,40 +97,67 @@ public class TestTiledPrintingGearsSwingAWT extends TiledPrintingAWTBase {
public static void releaseClass() {
}
- protected void runTestGL(GLCapabilities caps) throws InterruptedException, InvocationTargetException {
- final Dimension glc_sz = new Dimension(width/2, height);
+ protected void runTestGL(GLCapabilities caps, boolean layered) throws InterruptedException, InvocationTargetException {
+ final int layerStepX = width/6, layerStepY = height/6;
+ final Dimension glc_sz = new Dimension(layered ? width - 2*layerStepX : width/2, layered ? height - 2*layerStepY : height);
final GLJPanel glJPanel1 = new GLJPanel(caps);
Assert.assertNotNull(glJPanel1);
glJPanel1.setMinimumSize(glc_sz);
glJPanel1.setPreferredSize(glc_sz);
- glJPanel1.setSize(glc_sz);
+ if( layered ) {
+ glJPanel1.setBounds(layerStepX/2, layerStepY/2, glc_sz.width, glc_sz.height);
+ } else {
+ glJPanel1.setBounds(0, 0, glc_sz.width, glc_sz.height);
+ }
glJPanel1.addGLEventListener(new Gears());
final GLJPanel glJPanel2 = new GLJPanel(caps);
Assert.assertNotNull(glJPanel2);
glJPanel2.setMinimumSize(glc_sz);
glJPanel2.setPreferredSize(glc_sz);
- glJPanel2.setSize(glc_sz);
+ if( layered ) {
+ glJPanel2.setBounds(3*layerStepY, 2*layerStepY, glc_sz.width, glc_sz.height);
+ } else {
+ glJPanel2.setBounds(0, 0, glc_sz.width, glc_sz.height);
+ }
glJPanel2.addGLEventListener(new RedSquareES2());
+ // glJPanel2.addGLEventListener(new Gears());
- final JPanel demoPanel = new JPanel();
- demoPanel.add(glJPanel1);
- demoPanel.add(glJPanel2);
+ final JComponent demoPanel;
+ if( layered ) {
+ glJPanel1.setOpaque(true);
+ glJPanel2.setOpaque(false);
+ final Dimension lsz = new Dimension(width, height);
+ demoPanel = new JLayeredPane();
+ demoPanel.setMinimumSize(lsz);
+ demoPanel.setPreferredSize(lsz);
+ demoPanel.setBounds(0, 0, lsz.width, lsz.height);
+ demoPanel.setBorder(BorderFactory.createTitledBorder("Layered Pane"));
+ demoPanel.add(glJPanel1, JLayeredPane.DEFAULT_LAYER);
+ demoPanel.add(glJPanel2, Integer.valueOf(1));
+ final JButton tb = new JButton("On Top");
+ tb.setBounds(4*layerStepY, 3*layerStepY, 100, 50);
+ demoPanel.add(tb, Integer.valueOf(2));
+ } else {
+ demoPanel = new JPanel();
+ demoPanel.add(glJPanel1);
+ demoPanel.add(glJPanel2);
+ }
final JFrame frame = new JFrame("Swing Print");
Assert.assertNotNull(frame);
final ActionListener print72DPIAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
- doPrintManual(frame, 72, false);
+ doPrintManual(frame, 72, 0);
} };
final ActionListener print300DPIAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
- doPrintManual(frame, 300, false);
+ doPrintManual(frame, 300, -1);
} };
final ActionListener print600DPIAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
- doPrintManual(frame, 600, false);
+ doPrintManual(frame, 600, -1);
} };
final Button print72DPIButton = new Button("72dpi");
print72DPIButton.addActionListener(print72DPIAction);
@@ -182,20 +213,19 @@ public class TestTiledPrintingGearsSwingAWT extends TiledPrintingAWTBase {
Thread.sleep(200);
if( !printDone ) {
printDone = true;
- doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, false);
+ doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, 0);
waitUntilPrintJobsIdle();
- doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, true);
+ doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, 8);
waitUntilPrintJobsIdle();
// No AA needed for 300 dpi and greater :)
- doPrintAuto(frame, PageFormat.LANDSCAPE, null, 300, false);
+ doPrintAuto(frame, PageFormat.LANDSCAPE, null, 300, -1);
waitUntilPrintJobsIdle();
if( allow600dpi ) {
- doPrintAuto(frame, PageFormat.LANDSCAPE, null, 600, false);
+ doPrintAuto(frame, PageFormat.LANDSCAPE, null, 600, -1);
waitUntilPrintJobsIdle();
}
}
}
- // try { Thread.sleep(4000); } catch (InterruptedException e) { } // time to finish print jobs .. FIXME ??
Assert.assertNotNull(frame);
Assert.assertNotNull(glJPanel1);
@@ -220,15 +250,22 @@ public class TestTiledPrintingGearsSwingAWT extends TiledPrintingAWTBase {
@Test
public void test01_Onscreen_aa0() throws InterruptedException, InvocationTargetException {
GLCapabilities caps = new GLCapabilities(glp);
- runTestGL(caps);
+ runTestGL(caps, false);
+ }
+
+ @Test
+ public void test01_Onscreen_aa0_layered() throws InterruptedException, InvocationTargetException {
+ GLCapabilities caps = new GLCapabilities(glp);
+ caps.setAlphaBits(8);
+ runTestGL(caps, true);
}
@Test
public void test02_Onscreen_aa8() throws InterruptedException, InvocationTargetException {
GLCapabilities caps = new GLCapabilities(glp);
caps.setSampleBuffers(true);
- caps.setNumSamples(8); // FIXME
- runTestGL(caps);
+ caps.setNumSamples(8);
+ runTestGL(caps, false);
}
static long duration = 500; // ms
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TiledPrintingAWTBase.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TiledPrintingAWTBase.java
index ec216a95e..c23d51c51 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TiledPrintingAWTBase.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TiledPrintingAWTBase.java
@@ -28,11 +28,10 @@
package com.jogamp.opengl.test.junit.jogl.tile;
-import java.awt.Frame;
+import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
-import java.awt.RenderingHints;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
@@ -41,7 +40,6 @@ import java.awt.print.PrinterJob;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
-import javax.media.opengl.awt.AWTPrintLifecycle;
import javax.print.StreamPrintService;
import javax.print.StreamPrintServiceFactory;
import javax.print.attribute.HashPrintRequestAttributeSet;
@@ -53,6 +51,7 @@ import org.junit.Assert;
import com.jogamp.common.util.awt.AWTEDTExecutor;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.nativewindow.awt.AWTPrintLifecycle;
import com.jogamp.opengl.test.junit.util.UITestCase;
/**
@@ -97,11 +96,7 @@ public abstract class TiledPrintingAWTBase extends UITestCase implements Printab
public static final double A0_HEIGHT_INCH = A0_WIDTH_MM / MM_PER_INCH; */
/** Helper to pass desired Frame to print! **/
- private Frame frame;
- /** Helper to pass desired DPI value ! **/
- private int glDPI = 72;
- /** Helper to pass desired AA hint ! **/
- private boolean printAA = false;
+ private Container printContainer;
private RecursiveLock lockPrinting = LockFactory.createRecursiveLock();
@@ -155,9 +150,9 @@ public abstract class TiledPrintingAWTBase extends UITestCase implements Printab
/**
* See: 'Scaling of Frame and GL content' in Class description!
*/
- final Insets frameInsets = frame.getInsets();
- final int frameWidth = frame.getWidth();
- final int frameHeight= frame.getHeight();
+ final Insets frameInsets = printContainer.getInsets();
+ final int frameWidth = printContainer.getWidth();
+ final int frameHeight= printContainer.getHeight();
final double scaleComp72;
{
final int frameBorderW = frameInsets.left + frameInsets.right;
@@ -166,32 +161,21 @@ public abstract class TiledPrintingAWTBase extends UITestCase implements Printab
final double sy = pf.getImageableHeight() / ( frameHeight + frameBorderH );
scaleComp72 = Math.min(sx, sy);
}
- final double scaleGLMatXY = 72.0 / glDPI;
System.err.println("PRINT thread "+Thread.currentThread().getName());
- System.err.println("PRINT DPI: "+glDPI+", AA "+printAA+", scaleGL "+scaleGLMatXY+", scaleComp72 "+scaleComp72+
+ System.err.println("PRINT DPI: scaleComp72 "+scaleComp72+
", frame: border "+frameInsets+", size "+frameWidth+"x"+frameHeight);
- final Graphics2D printG2D = (Graphics2D)g;
- final Graphics2D g2d = printG2D;
-
+ final Graphics2D g2d = (Graphics2D)g;
+ System.err.println("PRINT at.pre: "+g2d.getTransform());
g2d.translate(pf.getImageableX(), pf.getImageableY());
g2d.scale(scaleComp72, scaleComp72);
-
- if( printAA ) {
- g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- }
- final AWTPrintLifecycle.Context ctx = AWTPrintLifecycle.Context.setupPrint(frame, g2d, scaleGLMatXY, scaleGLMatXY);
- try {
- System.err.println("PRINT AWTPrintLifecycle.setup.count "+ctx.getCount());
- AWTEDTExecutor.singleton.invoke(true, new Runnable() {
- public void run() {
- frame.printAll(g2d);
- }
- });
- } finally {
- ctx.releasePrint();
- System.err.println("PRINT AWTPrintLifecycle.release.count "+ctx.getCount());
- }
+ System.err.println("PRINT at.post: "+g2d.getTransform());
+
+ AWTEDTExecutor.singleton.invoke(true, new Runnable() {
+ public void run() {
+ printContainer.printAll(g2d);
+ }
+ });
/* tell the caller that this page is part of the printed document */
return PAGE_EXISTS;
@@ -207,7 +191,15 @@ public abstract class TiledPrintingAWTBase extends UITestCase implements Printab
super();
}
- public void doPrintAuto(Frame frame, int pOrientation, Paper paper, int dpi, boolean antialiasing) {
+ /**
+ *
+ * @param cont
+ * @param pOrientation
+ * @param paper
+ * @param dpi
+ * @param numSamples multisampling value: < 0 turns off, == 0 leaves as-is, > 0 enables using given num samples
+ */
+ public void doPrintAuto(Container cont, int pOrientation, Paper paper, int dpi, int numSamples) {
lock.lock();
try {
final PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
@@ -224,12 +216,12 @@ public abstract class TiledPrintingAWTBase extends UITestCase implements Printab
StreamPrintServiceFactory[] factories = PrinterJob.lookupStreamPrintServices(pdfMimeType);
if (factories.length > 0) {
- final String fname = getPrintFilename(dpi, antialiasing, "pdf");
+ final String fname = getPrintFilename(dpi, numSamples, "pdf");
System.err.println("doPrint: dpi "+dpi+", "+fname);
FileOutputStream outstream;
try {
outstream = new FileOutputStream(fname);
- Assert.assertTrue(doPrintAutoImpl(frame, pj, factories[0].getPrintService(outstream), pOrientation, paper, dpi, antialiasing));
+ Assert.assertTrue(doPrintAutoImpl(cont, pj, factories[0].getPrintService(outstream), pOrientation, paper, dpi, numSamples));
} catch (FileNotFoundException e) {
Assert.assertNull("Unexpected exception", e);
}
@@ -239,12 +231,12 @@ public abstract class TiledPrintingAWTBase extends UITestCase implements Printab
factories = PrinterJob.lookupStreamPrintServices(psMimeType);
if (factories.length > 0) {
- final String fname = getPrintFilename(dpi, antialiasing, "ps");
+ final String fname = getPrintFilename(dpi, numSamples, "ps");
System.err.println("doPrint: dpi "+dpi+", "+fname);
FileOutputStream outstream;
try {
outstream = new FileOutputStream(fname);
- Assert.assertTrue(doPrintAutoImpl(frame, pj, factories[0].getPrintService(outstream), pOrientation, paper, dpi, antialiasing));
+ Assert.assertTrue(doPrintAutoImpl(cont, pj, factories[0].getPrintService(outstream), pOrientation, paper, dpi, numSamples));
} catch (FileNotFoundException e) {
Assert.assertNull("Unexpected exception", e);
}
@@ -255,18 +247,14 @@ public abstract class TiledPrintingAWTBase extends UITestCase implements Printab
lock.unlock();
}
}
- private String getPrintFilename(int dpi, boolean antialiasing, String suffix) {
+ private String getPrintFilename(int dpi, int numSamples, String suffix) {
final int maxSimpleTestNameLen = getMaxTestNameLen()+getClass().getSimpleName().length()+1;
final String simpleTestName = getSimpleTestName(".");
- final String sAA = antialiasing ? "aa_" : "raw";
- return String.format("%-"+maxSimpleTestNameLen+"s-n%04d-dpi%03d-%s.%s", simpleTestName, printCount, dpi, sAA, suffix).replace(' ', '_');
+ return String.format("%-"+maxSimpleTestNameLen+"s-n%04d-dpi%03d-aa%d.%s", simpleTestName, printCount, dpi, numSamples, suffix).replace(' ', '_');
}
- private boolean doPrintAutoImpl(Frame frame, PrinterJob job,
+ private boolean doPrintAutoImpl(Container cont, PrinterJob job,
StreamPrintService ps, int pOrientation, Paper paper, int dpi,
- boolean antialiasing) {
- this.frame = frame;
- glDPI = dpi;
- printAA = antialiasing;
+ int numSamples) {
boolean ok = true;
try {
PageFormat pageFormat = job.defaultPage();
@@ -280,7 +268,7 @@ public abstract class TiledPrintingAWTBase extends UITestCase implements Printab
pageFormat.setOrientation(pOrientation); // PageFormat.LANDSCAPE or PageFormat.PORTRAIT
job.setPrintService(ps);
job.setPrintable(this, pageFormat);
- job.print();
+ doPrintImpl(cont, job, dpi, numSamples);
} catch (PrinterException pe) {
pe.printStackTrace();
ok = false;
@@ -288,25 +276,52 @@ public abstract class TiledPrintingAWTBase extends UITestCase implements Printab
return ok;
}
- public void doPrintManual(Frame frame, int dpi, boolean antialiasing) {
+ /**
+ *
+ * @param cont
+ * @param dpi
+ * @param numSamples multisampling value: < 0 turns off, == 0 leaves as-is, > 0 enables using given num samples
+ */
+ public void doPrintManual(Container cont, int dpi, int numSamples) {
lock.lock();
try {
- this.frame = frame;
- glDPI = dpi;
- printAA = antialiasing;
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(this);
boolean ok = job.printDialog();
if (ok) {
+ doPrintImpl(cont, job, dpi, numSamples);
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ *
+ * @param cont
+ * @param job
+ * @param dpi
+ * @param numSamples multisampling value: < 0 turns off, == 0 leaves as-is, > 0 enables using given num samples
+ */
+ private void doPrintImpl(final Container cont, final PrinterJob job, final int dpi, final int numSamples) {
+ printContainer = cont;
+ final double scaleGLMatXY = 72.0 / dpi;
+ System.err.println("PRINT DPI: "+dpi+", AA "+numSamples+", scaleGL "+scaleGLMatXY);
+ final AWTPrintLifecycle.Context ctx = AWTPrintLifecycle.Context.setupPrint(printContainer, scaleGLMatXY, scaleGLMatXY, numSamples);
+ System.err.println("PRINT AWTPrintLifecycle.setup.count "+ctx.getCount());
+ try {
+ AWTEDTExecutor.singleton.invoke(true, new Runnable() {
+ public void run() {
try {
job.print();
} catch (PrinterException ex) {
ex.printStackTrace();
}
- }
- } finally {
- lock.unlock();
- }
+ } });
+ } finally {
+ ctx.releasePrint();
+ System.err.println("PRINT AWTPrintLifecycle.release.count "+ctx.getCount());
+ }
}
/** Wait for idle .. simply acquiring all locks and releasing them. */