diff options
author | Sven Gothel <[email protected]> | 2013-09-15 23:27:16 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-09-15 23:27:16 +0200 |
commit | c2ce31e11eefcf1b900c0e9b41264f5d5566dc46 (patch) | |
tree | 09cc72c0b515bb18062e2bdf14f651981759f6bc /src/test/com | |
parent | 5a946df8fd812570826f267d4123b59d79c97cf7 (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/test/com')
4 files changed, 138 insertions, 86 deletions
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. */ |