diff options
author | Sven Gothel <[email protected]> | 2013-09-17 03:01:11 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-09-17 03:01:11 +0200 |
commit | 4e1d3170667d6692c484b8366d578ab830408175 (patch) | |
tree | bc3a7b52bd89da3bc45c56752bc36fdfad712629 | |
parent | 8afc1091532b0f18f30325aa3a504e7a7e975ce9 (diff) |
Print Tests: Split 'Printable' to own class, add OffscreenPrintable using NIO BufferedImage, adding OffscreenPrintable tests to all unit tests.
8 files changed, 537 insertions, 208 deletions
diff --git a/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java b/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java index b16273b35..7850762ef 100644 --- a/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java +++ b/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java @@ -65,7 +65,7 @@ import com.jogamp.opengl.util.awt.AWTGLPixelBuffer.AWTGLPixelBufferProvider; * </p> */ public class AWTTilePainter { - private static final boolean DEBUG_TILES = Debug.debug("TileRenderer"); + private static final boolean DEBUG_TILES = Debug.debug("TileRenderer.PNG"); public final TileRenderer renderer; public final int componentCount; diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/OffscreenPrintable.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/OffscreenPrintable.java new file mode 100644 index 000000000..1517e0bd1 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/OffscreenPrintable.java @@ -0,0 +1,177 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community 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) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.test.junit.jogl.tile; + +import java.awt.Container; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.awt.print.PageFormat; +import java.awt.print.Paper; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import com.jogamp.common.util.awt.AWTEDTExecutor; +import com.jogamp.nativewindow.awt.DirectDataBufferInt; + +/** + * {@link Printable} implementation using NIO {@link DirectDataBufferInt} {@link BufferedImage} + * for offscreen rendered printing. + * + * @see OnscreenPrintable + * @see PrintableBase + */ +public class OffscreenPrintable extends PrintableBase implements Printable { + + public final String pngFilename; + + /** + * + * @param job + * @param printContainer + * @param printDPI + * @param numSamples multisampling value: < 0 turns off, == 0 leaves as-is, > 0 enables using given num samples + * @param pngFilename TODO + */ + public OffscreenPrintable(PrinterJob job, Container printContainer, int printDPI, int numSamples, String pngFilename) { + super(job, printContainer, printDPI, numSamples); + this.pngFilename = pngFilename; + } + + @Override + public int print(Graphics g, PageFormat pf, int page) throws PrinterException { + if (page > 0) { // We have only one page, and 'page' is zero-based + return NO_SUCH_PAGE; + } + + lockPrinting.lock(); + try { + final Paper paper = pf.getPaper(); + final double paperWWidthInch = paper.getWidth() / 72.0; + final double paperWHeightInch = paper.getHeight() / 72.0; + final double paperIWidthInch = paper.getImageableWidth() / 72.0; + final double paperIHeightInch = paper.getImageableHeight() / 72.0; + final double paperWWidthMM = paperWWidthInch * MM_PER_INCH; + final double paperWHeightMM = paperWHeightInch * MM_PER_INCH; + final double paperIWidthMM = paperIWidthInch * MM_PER_INCH; + final double paperIHeightMM = paperIHeightInch * MM_PER_INCH; + + final double pfWWidthInch = pf.getWidth() / 72.0; + final double pfWHeightInch = pf.getHeight() / 72.0; + final double pfIWidthInch = pf.getImageableWidth() / 72.0; + final double pfIHeightInch = pf.getImageableHeight() / 72.0; + final double pfWWidthMM = pfWWidthInch * MM_PER_INCH; + final double pfWHeightMM = pfWHeightInch * MM_PER_INCH; + final double pfIWidthMM = pfIWidthInch * MM_PER_INCH; + final double pfIHeightMM = pfIHeightInch * MM_PER_INCH; + + System.err.println("PF: Paper whole size "+ + Math.round(paperWWidthMM)+" x "+Math.round(paperWHeightMM)+" mm, "+ + Math.round(paperWWidthInch)+" x "+Math.round(paperWHeightInch)+" inch"); + + System.err.println("PF: Paper image size "+paper.getImageableX()+" / "+paper.getImageableY()+" "+ + Math.round(paperIWidthMM)+" x "+Math.round(paperIHeightMM)+" mm, "+ + Math.round(paperIWidthInch)+" x "+Math.round(paperIHeightInch)+" inch, "+ + Math.round(paper.getImageableWidth())+"x"+Math.round(paper.getImageableHeight())+" 72dpi dots"); + + System.err.println("PF: Page whole size "+ + Math.round(pfWWidthMM)+" x "+Math.round(pfWHeightMM)+" mm, "+ + Math.round(pfWWidthInch)+" x "+Math.round(pfWHeightInch)+" inch"); + + System.err.println("PF: Page image size "+pf.getImageableX()+" / "+pf.getImageableY()+" "+ + Math.round(pfIWidthMM)+" x "+Math.round(pfIHeightMM)+" mm, "+ + Math.round(pfIWidthInch)+" x "+Math.round(pfIHeightInch)+" inch, "+ + Math.round(pf.getImageableWidth())+"x"+Math.round(pf.getImageableHeight())+" 72dpi dots"); + + System.err.println("PF: Page orientation "+pf.getOrientation()); + + /** + * See: 'Scaling of Frame and GL content' in Class description! + */ + final Insets frameInsets = cont.getInsets(); + final int frameWidth = cont.getWidth(); + final int frameHeight= cont.getHeight(); + final int frameWidthT = frameWidth + frameInsets.left + frameInsets.right; + final int frameHeightT = frameHeight + frameInsets.top + frameInsets.bottom; + final double scaleGraphics = dpi / 72.0; + final int frameSWidthT = (int) ( frameWidthT * scaleGraphics ); + final int frameSHeightT = (int) ( frameHeightT * scaleGraphics ); + final double scaleComp72; + { + final double sx = pf.getImageableWidth() / (double)frameSWidthT; + final double sy = pf.getImageableHeight() / (double)frameSHeightT; + scaleComp72 = Math.min(sx, sy); + } + + System.err.println("PRINT.offscrn thread "+Thread.currentThread().getName()); + System.err.println("PRINT.offscrn DPI: scaleGraphics "+scaleGraphics+", scaleComp72 "+scaleComp72); + System.err.println("PRINT.offscrn DPI: frame: border "+frameInsets+", size "+frameWidth+"x"+frameHeight+ + " -> total "+frameWidthT+ "x" + frameHeightT+ + " -> scaled "+frameSWidthT+ "x" + frameSHeightT); + + final BufferedImage image = DirectDataBufferInt.createBufferedImage(frameSWidthT, frameSHeightT, 4, null /* location */); + { + final Graphics2D g2d = (Graphics2D) image.getGraphics(); + g2d.setClip(0, 0, frameSWidthT, frameSHeightT); + g2d.scale(scaleGraphics, scaleGraphics); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + AWTEDTExecutor.singleton.invoke(true, new Runnable() { + public void run() { + cont.printAll(g2d); + } + }); + } + if( null != pngFilename ) { + final File fout = new File(pngFilename); + try { + ImageIO.write(image, "png", fout); + } catch (IOException e) { + e.printStackTrace(); + } + } + + final Graphics2D g2d = (Graphics2D)g; + g2d.translate(pf.getImageableX(), pf.getImageableY()); + g2d.scale(scaleComp72, scaleComp72); + g2d.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null); // Null ImageObserver since image data is ready. + + /* tell the caller that this page is part of the printed document */ + return PAGE_EXISTS; + } finally { + lockPrinting.unlock(); + } + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/OnscreenPrintable.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/OnscreenPrintable.java new file mode 100644 index 000000000..273da5c76 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/OnscreenPrintable.java @@ -0,0 +1,163 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community 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) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.test.junit.jogl.tile; + +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; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; + +import com.jogamp.common.util.awt.AWTEDTExecutor; + +/** + * <h5>Scaling of Frame and GL content</h5> + * <p> + * We fit the frame into the imageable area with for 72 dpi, + * assuming that is the default AWT painting density. + * </p> + * <p> + * The frame borders are considered. + * </p> + * <p> + * The frame's scale factor is used for the graphics print matrix + * of the overall print-job, hence no frame resize is required. + * </p> + * <p> + * The GL scale factor 'scaleGLMatXY', 72dpi/glDPI, is passed to the GL object + * which locally scales the print matrix and renders the scene with 1/scaleGLMatXY pixels. + * </p> + */ +public class OnscreenPrintable extends PrintableBase implements Printable { + + /** + * + * @param job + * @param printContainer + * @param printDPI + * @param numSamples multisampling value: < 0 turns off, == 0 leaves as-is, > 0 enables using given num samples + */ + public OnscreenPrintable(PrinterJob job, Container printContainer, int printDPI, int numSamples) { + super(job, printContainer, printDPI, numSamples); + } + + @Override + public int print(Graphics g, PageFormat pf, int page) throws PrinterException { + if (page > 0) { // We have only one page, and 'page' is zero-based + return NO_SUCH_PAGE; + } + + lockPrinting.lock(); + try { + final Paper paper = pf.getPaper(); + final double paperWWidthInch = paper.getWidth() / 72.0; + final double paperWHeightInch = paper.getHeight() / 72.0; + final double paperIWidthInch = paper.getImageableWidth() / 72.0; + final double paperIHeightInch = paper.getImageableHeight() / 72.0; + final double paperWWidthMM = paperWWidthInch * MM_PER_INCH; + final double paperWHeightMM = paperWHeightInch * MM_PER_INCH; + final double paperIWidthMM = paperIWidthInch * MM_PER_INCH; + final double paperIHeightMM = paperIHeightInch * MM_PER_INCH; + + final double pfWWidthInch = pf.getWidth() / 72.0; + final double pfWHeightInch = pf.getHeight() / 72.0; + final double pfIWidthInch = pf.getImageableWidth() / 72.0; + final double pfIHeightInch = pf.getImageableHeight() / 72.0; + final double pfWWidthMM = pfWWidthInch * MM_PER_INCH; + final double pfWHeightMM = pfWHeightInch * MM_PER_INCH; + final double pfIWidthMM = pfIWidthInch * MM_PER_INCH; + final double pfIHeightMM = pfIHeightInch * MM_PER_INCH; + + System.err.println("PF: Paper whole size "+ + Math.round(paperWWidthMM)+" x "+Math.round(paperWHeightMM)+" mm, "+ + Math.round(paperWWidthInch)+" x "+Math.round(paperWHeightInch)+" inch"); + + System.err.println("PF: Paper image size "+paper.getImageableX()+" / "+paper.getImageableY()+" "+ + Math.round(paperIWidthMM)+" x "+Math.round(paperIHeightMM)+" mm, "+ + Math.round(paperIWidthInch)+" x "+Math.round(paperIHeightInch)+" inch, "+ + Math.round(paper.getImageableWidth())+"x"+Math.round(paper.getImageableHeight())+" 72dpi dots"); + + System.err.println("PF: Page whole size "+ + Math.round(pfWWidthMM)+" x "+Math.round(pfWHeightMM)+" mm, "+ + Math.round(pfWWidthInch)+" x "+Math.round(pfWHeightInch)+" inch"); + + System.err.println("PF: Page image size "+pf.getImageableX()+" / "+pf.getImageableY()+" "+ + Math.round(pfIWidthMM)+" x "+Math.round(pfIHeightMM)+" mm, "+ + Math.round(pfIWidthInch)+" x "+Math.round(pfIHeightInch)+" inch, "+ + Math.round(pf.getImageableWidth())+"x"+Math.round(pf.getImageableHeight())+" 72dpi dots"); + + System.err.println("PF: Page orientation "+pf.getOrientation()); + + /** + * See: 'Scaling of Frame and GL content' in Class description! + */ + final Insets frameInsets = cont.getInsets(); + final int frameWidth = cont.getWidth(); + final int frameHeight= cont.getHeight(); + final int frameWidthT = frameWidth + frameInsets.left + frameInsets.right; + final int frameHeightT = frameHeight + frameInsets.top + frameInsets.bottom; + final double scaleGraphics = dpi / 72.0; + final int frameSWidthT = (int) ( frameWidthT * scaleGraphics ); + final int frameSHeightT = (int) ( frameHeightT * scaleGraphics ); + final double scaleComp72; + { + final double sx = pf.getImageableWidth() / (double)frameWidthT; + final double sy = pf.getImageableHeight() / (double)frameHeightT; + scaleComp72 = Math.min(sx, sy); + } + System.err.println("PRINT.onscrn thread "+Thread.currentThread().getName()); + System.err.println("PRINT.onscrn DPI: scaleGraphics "+scaleGraphics+", scaleComp72 "+scaleComp72); + System.err.println("PRINT.onscrn DPI: frame: border "+frameInsets+", size "+frameWidth+"x"+frameHeight+ + " -> total "+frameWidthT+ "x" + frameHeightT+ + " -> scaled "+frameSWidthT+ "x" + frameSHeightT); + + final Graphics2D g2d = (Graphics2D)g; + System.err.println("PRINT at.pre: "+g2d.getTransform()); + g2d.translate(pf.getImageableX(), pf.getImageableY()); + g2d.scale(scaleComp72, scaleComp72); // WARNING: Produces rounding artifacts due to diff scale-factor of AWT/GL comps !!! + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + + AWTEDTExecutor.singleton.invoke(true, new Runnable() { + public void run() { + cont.printAll(g2d); + } + }); + + /* tell the caller that this page is part of the printed document */ + return PAGE_EXISTS; + } finally { + lockPrinting.unlock(); + } + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/PrintableBase.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/PrintableBase.java new file mode 100644 index 000000000..830ded960 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/PrintableBase.java @@ -0,0 +1,82 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community 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) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.test.junit.jogl.tile; + +import java.awt.Container; +import java.awt.print.Printable; +import java.awt.print.PrinterJob; + +import com.jogamp.common.util.locks.LockFactory; +import com.jogamp.common.util.locks.RecursiveLock; + +/** + * Base {@link Printable} implementation class. + * + * <h5>Virtual printer driver</h5> + * <p> + * Note, on OSX you might need to setup a dummy printer, i.e. <i>print to file</i>.<br> + * As root: + * <pre> + cupsctl FileDevice=Yes + killall -HUP cupsd + mkdir /data/lp + chown USER /data/lp + chmod ugo+rwx /data/lp + lpadmin -p lprint -E -v file:/data/lp/out.ps -P /Library/Printers/PPDs/Contents/Resources/HP\ LaserJet\ 4\ Plus.gz + * </pre> + */ +public abstract class PrintableBase implements Printable { + + public static final double MM_PER_INCH = 25.4; + + public final PrinterJob job; + public final Container cont; + public final int dpi; + public final int numSamples; + protected final RecursiveLock lockPrinting = LockFactory.createRecursiveLock(); + + /** + * + * @param job + * @param printContainer + * @param printDPI + * @param numSamples multisampling value: < 0 turns off, == 0 leaves as-is, > 0 enables using given num samples + */ + public PrintableBase(PrinterJob job, Container printContainer, int printDPI, int numSamples) { + this.job = job; + this.cont = printContainer; + this.dpi = printDPI; + this.numSamples = numSamples; + } + + /** Wait for idle .. simply acquiring all locks and releasing them. */ + public void waitUntilIdle() { + lockPrinting.lock(); + lockPrinting.unlock(); + } +}
\ No newline at end of file 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 908a89a32..c7c04950a 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 @@ -175,21 +175,32 @@ public class TestTiledPrintingGearsAWT extends TiledPrintingAWTBase { while(!quitAdapter.shouldQuit() && animator.isAnimating() && ( 0 == duration || animator.getTotalFPSDuration()<duration )) { Thread.sleep(200); if( !printDone ) { - printDone = true; - doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, 0); - waitUntilPrintJobsIdle(); - doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, 8); - waitUntilPrintJobsIdle(); - // No AA needed for 300 dpi and greater :) - doPrintAuto(frame, PageFormat.LANDSCAPE, null, 300, -1); - waitUntilPrintJobsIdle(); + printDone = true; + { + final PrintableBase p = doPrintAuto(frame, PageFormat.LANDSCAPE, null, false, 72, 0); + waitUntilPrintJobsIdle(p); + } + { + final PrintableBase p = doPrintAuto(frame, PageFormat.LANDSCAPE, null, false, 72, 8); + waitUntilPrintJobsIdle(p); + } + { + // No AA needed for 300 dpi and greater :) + final PrintableBase p = doPrintAuto(frame, PageFormat.LANDSCAPE, null, false, 300, -1); + waitUntilPrintJobsIdle(p); + } + { + // No AA needed for 300 dpi and greater :) + final PrintableBase p = doPrintAuto(frame, PageFormat.LANDSCAPE, null, true, 300, -1); + waitUntilPrintJobsIdle(p); + } if( allow600dpi ) { - doPrintAuto(frame, PageFormat.LANDSCAPE, null, 600, -1); - waitUntilPrintJobsIdle(); + // No AA needed for 300 dpi and greater :) + final PrintableBase p = doPrintAuto(frame, PageFormat.LANDSCAPE, null, false, 600, -1); + waitUntilPrintJobsIdle(p); } } } - // try { Thread.sleep(4000); } catch (InterruptedException e) { } // time to finish print jobs .. FIXME ?? Assert.assertNotNull(frame); Assert.assertNotNull(glCanvas1); @@ -212,16 +223,16 @@ public class TestTiledPrintingGearsAWT extends TiledPrintingAWTBase { } @Test - public void test01_Onscreen_aa0() throws InterruptedException, InvocationTargetException { + public void test01_aa0() throws InterruptedException, InvocationTargetException { GLCapabilities caps = new GLCapabilities(glp); runTestGL(caps); } @Test - public void test02_Onscreen_aa8() throws InterruptedException, InvocationTargetException { + public void test02_aa8() throws InterruptedException, InvocationTargetException { GLCapabilities caps = new GLCapabilities(glp); caps.setSampleBuffers(true); - caps.setNumSamples(8); // FIXME + caps.setNumSamples(8); runTestGL(caps); } 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 c695febbe..b0d6c5117 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 @@ -181,20 +181,31 @@ public class TestTiledPrintingGearsNewtAWT extends TiledPrintingAWTBase { Thread.sleep(200); if( !printDone ) { printDone = true; - doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, 0); - waitUntilPrintJobsIdle(); - doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, 8); - waitUntilPrintJobsIdle(); - // No AA needed for 300 dpi and greater :) - doPrintAuto(frame, PageFormat.LANDSCAPE, null, 300, -1); - waitUntilPrintJobsIdle(); + { + final PrintableBase p = doPrintAuto(frame, PageFormat.LANDSCAPE, null, false, 72, 0); + waitUntilPrintJobsIdle(p); + } + { + final PrintableBase p = doPrintAuto(frame, PageFormat.LANDSCAPE, null, false, 72, 8); + waitUntilPrintJobsIdle(p); + } + { + // No AA needed for 300 dpi and greater :) + final PrintableBase p = doPrintAuto(frame, PageFormat.LANDSCAPE, null, false, 300, -1); + waitUntilPrintJobsIdle(p); + } + { + // No AA needed for 300 dpi and greater :) + final PrintableBase p = doPrintAuto(frame, PageFormat.LANDSCAPE, null, true, 300, -1); + waitUntilPrintJobsIdle(p); + } if( allow600dpi ) { - doPrintAuto(frame, PageFormat.LANDSCAPE, null, 600, -1); - waitUntilPrintJobsIdle(); + // No AA needed for 300 dpi and greater :) + final PrintableBase p = doPrintAuto(frame, PageFormat.LANDSCAPE, null, false, 600, -1); + waitUntilPrintJobsIdle(p); } } } - // try { Thread.sleep(4000); } catch (InterruptedException e) { } // time to finish print jobs .. FIXME ?? Assert.assertNotNull(frame); Assert.assertNotNull(canvas1); @@ -219,16 +230,16 @@ public class TestTiledPrintingGearsNewtAWT extends TiledPrintingAWTBase { } @Test - public void test01_Onscreen_aa0() throws InterruptedException, InvocationTargetException { + public void test01_aa0() throws InterruptedException, InvocationTargetException { GLCapabilities caps = new GLCapabilities(glp); runTestGL(caps); } @Test - public void test02_Onscreen_aa8() throws InterruptedException, InvocationTargetException { + public void test02_aa8() throws InterruptedException, InvocationTargetException { GLCapabilities caps = new GLCapabilities(glp); caps.setSampleBuffers(true); - caps.setNumSamples(8); // FIXME + caps.setNumSamples(8); runTestGL(caps); } 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 9c5d6bf8b..72f4871b8 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 @@ -213,16 +213,28 @@ public class TestTiledPrintingGearsSwingAWT extends TiledPrintingAWTBase { Thread.sleep(200); if( !printDone ) { printDone = true; - doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, 0); - waitUntilPrintJobsIdle(); - doPrintAuto(frame, PageFormat.LANDSCAPE, null, 72, 8); - waitUntilPrintJobsIdle(); - // No AA needed for 300 dpi and greater :) - doPrintAuto(frame, PageFormat.LANDSCAPE, null, 300, -1); - waitUntilPrintJobsIdle(); + { + final PrintableBase p = doPrintAuto(frame, PageFormat.LANDSCAPE, null, false, 72, 0); + waitUntilPrintJobsIdle(p); + } + { + final PrintableBase p = doPrintAuto(frame, PageFormat.LANDSCAPE, null, false, 72, 8); + waitUntilPrintJobsIdle(p); + } + { + // No AA needed for 300 dpi and greater :) + final PrintableBase p = doPrintAuto(frame, PageFormat.LANDSCAPE, null, false, 300, -1); + waitUntilPrintJobsIdle(p); + } + { + // No AA needed for 300 dpi and greater :) + final PrintableBase p = doPrintAuto(frame, PageFormat.LANDSCAPE, null, true, 300, -1); + waitUntilPrintJobsIdle(p); + } if( allow600dpi ) { - doPrintAuto(frame, PageFormat.LANDSCAPE, null, 600, -1); - waitUntilPrintJobsIdle(); + // No AA needed for 300 dpi and greater :) + final PrintableBase p = doPrintAuto(frame, PageFormat.LANDSCAPE, null, false, 600, -1); + waitUntilPrintJobsIdle(p); } } } @@ -248,20 +260,20 @@ public class TestTiledPrintingGearsSwingAWT extends TiledPrintingAWTBase { } @Test - public void test01_Onscreen_aa0() throws InterruptedException, InvocationTargetException { + public void test01_aa0() throws InterruptedException, InvocationTargetException { GLCapabilities caps = new GLCapabilities(glp); runTestGL(caps, false); } @Test - public void test01_Onscreen_aa0_layered() throws InterruptedException, InvocationTargetException { + public void test01_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 { + public void test02_aa8() throws InterruptedException, InvocationTargetException { GLCapabilities caps = new GLCapabilities(glp); caps.setSampleBuffers(true); caps.setNumSamples(8); 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 10d8b186d..199a667a1 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 @@ -29,9 +29,6 @@ package com.jogamp.opengl.test.junit.jogl.tile; import java.awt.Container; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Insets; import java.awt.print.PageFormat; import java.awt.print.Paper; import java.awt.print.Printable; @@ -55,135 +52,12 @@ import com.jogamp.nativewindow.awt.AWTPrintLifecycle; import com.jogamp.opengl.test.junit.util.UITestCase; /** - * Base unit test class implementing {@link Printable}. - * - * <h5>Scaling of Frame and GL content</h5> - * <p> - * We fit the frame into the imageable area with for 72 dpi, - * assuming that is the default AWT painting density. - * </p> - * <p> - * The frame borders are considered. - * </p> - * <p> - * The frame's scale factor is used for the graphics print matrix - * of the overall print-job, hence no frame resize is required. - * </p> - * <p> - * The GL scale factor 'scaleGLMatXY', 72dpi/glDPI, is passed to the GL object - * which locally scales the print matrix and renders the scene with 1/scaleGLMatXY pixels. - * </p> - * <h5>Virtual printer driver</h5> - * <p> - * Note, on OSX you might need to setup a dummy printer, i.e. <i>print to file</i>.<br> - * As root: - * <pre> - cupsctl FileDevice=Yes - killall -HUP cupsd - mkdir /data/lp - chown USER /data/lp - chmod ugo+rwx /data/lp - lpadmin -p lprint -E -v file:/data/lp/out.ps -P /Library/Printers/PPDs/Contents/Resources/HP\ LaserJet\ 4\ Plus.gz - * </pre> + * Base unit test class implementing + * issuing {@link PrinterJob#print()} on a {@link Printable} implementation, + * i.e. {@link OnscreenPrintable} or {@link OffscreenPrintable}. */ -public abstract class TiledPrintingAWTBase extends UITestCase implements Printable { - - public static final double MM_PER_INCH = 25.4; - /** - public static final double A0_WIDTH_MM = 841.0; - public static final double A0_HEIGHT_MM = 1189.0; - public static final double A0_WIDTH_INCH = A0_WIDTH_MM / MM_PER_INCH; - public static final double A0_HEIGHT_INCH = A0_WIDTH_MM / MM_PER_INCH; */ - - /** Helper to pass desired Frame to print! **/ - private Container printContainer; +public abstract class TiledPrintingAWTBase extends UITestCase { - private RecursiveLock lockPrinting = LockFactory.createRecursiveLock(); - - @Override - public int print(Graphics g, PageFormat pf, int page) throws PrinterException { - if (page > 0) { // We have only one page, and 'page' is zero-based - return NO_SUCH_PAGE; - } - - lockPrinting.lock(); - try { - final Paper paper = pf.getPaper(); - final double paperWWidthInch = paper.getWidth() / 72.0; - final double paperWHeightInch = paper.getHeight() / 72.0; - final double paperIWidthInch = paper.getImageableWidth() / 72.0; - final double paperIHeightInch = paper.getImageableHeight() / 72.0; - final double paperWWidthMM = paperWWidthInch * MM_PER_INCH; - final double paperWHeightMM = paperWHeightInch * MM_PER_INCH; - final double paperIWidthMM = paperIWidthInch * MM_PER_INCH; - final double paperIHeightMM = paperIHeightInch * MM_PER_INCH; - - final double pfWWidthInch = pf.getWidth() / 72.0; - final double pfWHeightInch = pf.getHeight() / 72.0; - final double pfIWidthInch = pf.getImageableWidth() / 72.0; - final double pfIHeightInch = pf.getImageableHeight() / 72.0; - final double pfWWidthMM = pfWWidthInch * MM_PER_INCH; - final double pfWHeightMM = pfWHeightInch * MM_PER_INCH; - final double pfIWidthMM = pfIWidthInch * MM_PER_INCH; - final double pfIHeightMM = pfIHeightInch * MM_PER_INCH; - - System.err.println("PF: Paper whole size "+ - Math.round(paperWWidthMM)+" x "+Math.round(paperWHeightMM)+" mm, "+ - Math.round(paperWWidthInch)+" x "+Math.round(paperWHeightInch)+" inch"); - - System.err.println("PF: Paper image size "+paper.getImageableX()+" / "+paper.getImageableY()+" "+ - Math.round(paperIWidthMM)+" x "+Math.round(paperIHeightMM)+" mm, "+ - Math.round(paperIWidthInch)+" x "+Math.round(paperIHeightInch)+" inch, "+ - Math.round(paper.getImageableWidth())+"x"+Math.round(paper.getImageableHeight())+" 72dpi dots"); - - System.err.println("PF: Page whole size "+ - Math.round(pfWWidthMM)+" x "+Math.round(pfWHeightMM)+" mm, "+ - Math.round(pfWWidthInch)+" x "+Math.round(pfWHeightInch)+" inch"); - - System.err.println("PF: Page image size "+pf.getImageableX()+" / "+pf.getImageableY()+" "+ - Math.round(pfIWidthMM)+" x "+Math.round(pfIHeightMM)+" mm, "+ - Math.round(pfIWidthInch)+" x "+Math.round(pfIHeightInch)+" inch, "+ - Math.round(pf.getImageableWidth())+"x"+Math.round(pf.getImageableHeight())+" 72dpi dots"); - - System.err.println("PF: Page orientation "+pf.getOrientation()); - - /** - * See: 'Scaling of Frame and GL content' in Class description! - */ - final Insets frameInsets = printContainer.getInsets(); - final int frameWidth = printContainer.getWidth(); - final int frameHeight= printContainer.getHeight(); - final double scaleComp72; - { - final double frameBorderW = frameInsets.left + frameInsets.right; - final double frameBorderH = frameInsets.top + frameInsets.bottom; - final double sx = pf.getImageableWidth() / ( frameWidth + frameBorderW ); - final double sy = pf.getImageableHeight() / ( frameHeight + frameBorderH ); - scaleComp72 = Math.min(sx, sy); - } - - System.err.println("PRINT thread "+Thread.currentThread().getName()); - System.err.println("PRINT DPI: scaleComp72 "+scaleComp72+ - ", frame: border "+frameInsets+", size "+frameWidth+"x"+frameHeight); - final Graphics2D g2d = (Graphics2D)g; - System.err.println("PRINT at.pre: "+g2d.getTransform()); - g2d.translate(pf.getImageableX(), pf.getImageableY()); - g2d.scale(scaleComp72, scaleComp72); - 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; - } finally { - lockPrinting.unlock(); - } - } - private RecursiveLock lock = LockFactory.createRecursiveLock(); private int printCount = 0; @@ -196,10 +70,11 @@ public abstract class TiledPrintingAWTBase extends UITestCase implements Printab * @param cont * @param pOrientation * @param paper + * @param offscrn TODO * @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) { + public PrintableBase doPrintAuto(Container cont, int pOrientation, Paper paper, boolean offscrn, int dpi, int numSamples) { lock.lock(); try { final PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); @@ -216,46 +91,47 @@ public abstract class TiledPrintingAWTBase extends UITestCase implements Printab StreamPrintServiceFactory[] factories = PrinterJob.lookupStreamPrintServices(pdfMimeType); if (factories.length > 0) { - final String fname = getPrintFilename(dpi, numSamples, "pdf"); + final String fname = getPrintFilename(offscrn, dpi, numSamples, "pdf"); System.err.println("doPrint: dpi "+dpi+", "+fname); FileOutputStream outstream; try { outstream = new FileOutputStream(fname); - Assert.assertTrue(doPrintAutoImpl(cont, pj, factories[0].getPrintService(outstream), pOrientation, paper, dpi, numSamples)); + return doPrintAutoImpl(cont, pj, factories[0].getPrintService(outstream), pOrientation, paper, offscrn, dpi, numSamples); } catch (FileNotFoundException e) { Assert.assertNull("Unexpected exception", e); } - return; + return null; } System.err.println("No PDF"); factories = PrinterJob.lookupStreamPrintServices(psMimeType); if (factories.length > 0) { - final String fname = getPrintFilename(dpi, numSamples, "ps"); + final String fname = getPrintFilename(offscrn, dpi, numSamples, "ps"); System.err.println("doPrint: dpi "+dpi+", "+fname); FileOutputStream outstream; try { outstream = new FileOutputStream(fname); - Assert.assertTrue(doPrintAutoImpl(cont, pj, factories[0].getPrintService(outstream), pOrientation, paper, dpi, numSamples)); + return doPrintAutoImpl(cont, pj, factories[0].getPrintService(outstream), pOrientation, paper, offscrn, dpi, numSamples); } catch (FileNotFoundException e) { Assert.assertNull("Unexpected exception", e); } - return; + return null; } System.err.println("No PS"); + return null; } finally { lock.unlock(); } } - private String getPrintFilename(int dpi, int numSamples, String suffix) { + private String getPrintFilename(boolean offscrn, int dpi, int numSamples, String suffix) { final int maxSimpleTestNameLen = getMaxTestNameLen()+getClass().getSimpleName().length()+1; final String simpleTestName = getSimpleTestName("."); - return String.format("%-"+maxSimpleTestNameLen+"s-n%04d-dpi%03d-aa%d.%s", simpleTestName, printCount, dpi, numSamples, suffix).replace(' ', '_'); + final String onoffscrn = offscrn ? "offscrn" : "on_scrn"; + return String.format("%-"+maxSimpleTestNameLen+"s-n%04d-%s-dpi%03d-aa%d.%s", simpleTestName, printCount, onoffscrn, dpi, numSamples, suffix).replace(' ', '_'); } - private boolean doPrintAutoImpl(Container cont, PrinterJob job, - StreamPrintService ps, int pOrientation, Paper paper, int dpi, - int numSamples) { - boolean ok = true; + private PrintableBase doPrintAutoImpl(Container cont, PrinterJob job, + StreamPrintService ps, int pOrientation, Paper paper, + boolean offscrn, int dpi, int numSamples) { try { PageFormat pageFormat = job.defaultPage(); if( null != paper ) { @@ -267,13 +143,15 @@ public abstract class TiledPrintingAWTBase extends UITestCase implements Printab } pageFormat.setOrientation(pOrientation); // PageFormat.LANDSCAPE or PageFormat.PORTRAIT job.setPrintService(ps); - job.setPrintable(this, pageFormat); - doPrintImpl(cont, job, dpi, numSamples); + final PrintableBase printable = offscrn ? new OffscreenPrintable(job, cont, dpi, numSamples, getPrintFilename(offscrn, dpi, numSamples, "png")) : + new OnscreenPrintable(job, cont, dpi, numSamples); + printable.job.setPrintable(printable, pageFormat); + doPrintImpl(printable); + return printable; } catch (PrinterException pe) { pe.printStackTrace(); - ok = false; + return null; } - return ok; } /** @@ -282,38 +160,32 @@ public abstract class TiledPrintingAWTBase extends UITestCase implements Printab * @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) { + public PrintableBase doPrintManual(Container cont, int dpi, int numSamples) { lock.lock(); try { - PrinterJob job = PrinterJob.getPrinterJob(); - job.setPrintable(this); - boolean ok = job.printDialog(); + final OnscreenPrintable printable = new OnscreenPrintable(PrinterJob.getPrinterJob(), cont, dpi, numSamples); + printable.job.setPrintable(printable); + boolean ok = printable.job.printDialog(); if (ok) { - doPrintImpl(cont, job, dpi, numSamples); + doPrintImpl(printable); } + return printable; } 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); + private void doPrintImpl(final PrintableBase printable) { + final double scaleGLMatXY = 72.0 / printable.dpi; + System.err.println("PRINTable: "+printable.getClass().getSimpleName()); + System.err.println("PRINT DPI: "+printable.dpi+", AA "+printable.numSamples+", scaleGL "+scaleGLMatXY); + final AWTPrintLifecycle.Context ctx = AWTPrintLifecycle.Context.setupPrint(printable.cont, scaleGLMatXY, scaleGLMatXY, printable.numSamples); System.err.println("PRINT AWTPrintLifecycle.setup.count "+ctx.getCount()); try { AWTEDTExecutor.singleton.invoke(true, new Runnable() { public void run() { try { - job.print(); + printable.job.print(); } catch (PrinterException ex) { ex.printStackTrace(); } @@ -325,11 +197,12 @@ public abstract class TiledPrintingAWTBase extends UITestCase implements Printab } /** Wait for idle .. simply acquiring all locks and releasing them. */ - public void waitUntilPrintJobsIdle() { + public void waitUntilPrintJobsIdle(PrintableBase p) { lock.lock(); try { - lockPrinting.lock(); - lockPrinting.unlock(); + if( null != p ) { + p.waitUntilIdle(); + } } finally { lock.unlock(); } |