From 9b5cee85c299e72735bebbfea5c23d3c71bc704e Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 7 Sep 2013 19:59:15 +0200 Subject: TiledPrintingAWTBase: Fix scaling - Fit frame to page, add MSAA RenderingHints test; setupPrint(Graphics2D): Query RenderingHints to use MSAA rendering - AWTPrintLifecycle.setupPrint(Graphics2D): Query RenderingHints to use MSAA rendering - Impl. in GLCanvas - TODO GLJPanel (would need a new offscreen buffer) - TiledPrintingAWTBase: - Fix scaling - Fit frame to page - add MSAA RenderingHints test - GLCanvas: Remove dumpStack() DEBUG output --- .../junit/jogl/demos/gl2/awt/TestGearsAWT.java | 12 +- .../junit/jogl/tile/TestTiledPrintingGearsAWT.java | 42 ++- .../jogl/tile/TestTiledPrintingGearsSwingAWT.java | 29 +- .../test/junit/jogl/tile/TiledPrintingAWTBase.java | 415 ++++++++++++--------- 4 files changed, 293 insertions(+), 205 deletions(-) (limited to 'src/test/com/jogamp/opengl') diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWT.java index d23130d36..24a6d578c 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWT.java @@ -60,6 +60,7 @@ public class TestGearsAWT extends UITestCase { static GLProfile glp; static int width, height; static boolean waitForKey = false; + static int msaaCount = 0; @BeforeClass public static void initClass() { @@ -132,6 +133,10 @@ public class TestGearsAWT extends UITestCase { @Test public void test01() throws InterruptedException, InvocationTargetException { GLCapabilities caps = new GLCapabilities(glp); + if( msaaCount > 0 ) { + caps.setSampleBuffers(true); + caps.setNumSamples(msaaCount); + } runTestGL(caps); } @@ -144,9 +149,14 @@ public class TestGearsAWT extends UITestCase { try { duration = Integer.parseInt(args[i]); } catch (Exception ex) { ex.printStackTrace(); } + } else if(args[i].equals("-msaa")) { + i++; + try { + msaaCount = Integer.parseInt(args[i]); + } catch (Exception ex) { ex.printStackTrace(); } } else if(args[i].equals("-wait")) { waitForKey = true; - } + } } if(waitForKey) { BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); 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 511880a0d..86c06247f 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 @@ -103,20 +103,27 @@ public class TestTiledPrintingGearsAWT extends TiledPrintingAWTBase { final ActionListener print72DPIAction = new ActionListener() { public void actionPerformed(ActionEvent e) { - doPrintManual(frame, glCanvas, TestTiledPrintingGearsAWT.this, offscreenPrinting, 72); + doPrintManual(frame, glCanvas, TestTiledPrintingGearsAWT.this, offscreenPrinting, 72, false); + } }; + final ActionListener print150DPIAction = new ActionListener() { + public void actionPerformed(ActionEvent e) { + doPrintManual(frame, glCanvas, TestTiledPrintingGearsAWT.this, offscreenPrinting, 150, false); } }; final ActionListener print300DPIAction = new ActionListener() { public void actionPerformed(ActionEvent e) { - doPrintManual(frame, glCanvas, TestTiledPrintingGearsAWT.this, offscreenPrinting, 300); + doPrintManual(frame, glCanvas, TestTiledPrintingGearsAWT.this, offscreenPrinting, 300, false); } }; final Button print72DPIButton = new Button("72dpi"); print72DPIButton.addActionListener(print72DPIAction); + final Button print150DPIButton = new Button("150dpi"); + print150DPIButton.addActionListener(print150DPIAction); final Button print300DPIButton = new Button("300dpi"); print300DPIButton.addActionListener(print300DPIAction); frame.setLayout(new BorderLayout()); Panel printPanel = new Panel(); printPanel.add(print72DPIButton); + printPanel.add(print150DPIButton); printPanel.add(print300DPIButton); Panel southPanel = new Panel(); southPanel.add(new Label("South")); @@ -149,18 +156,24 @@ public class TestTiledPrintingGearsAWT extends TiledPrintingAWTBase { animator.start(); boolean dpi72Done = false; - boolean dpi300Done = false; + boolean dpi150Done = false; while(!quitAdapter.shouldQuit() && animator.isAnimating() && ( 0 == duration || animator.getTotalFPSDuration() 0) { // We have only one page, and 'page' is zero-based - return NO_SUCH_PAGE; - } - - 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 * mmPerInch; - final double paperWHeightMM = paperWHeightInch * mmPerInch; - final double paperIWidthMM = paperIWidthInch * mmPerInch; - final double paperIHeightMM = paperIHeightInch * mmPerInch; - - 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 * mmPerInch; - final double pfWHeightMM = pfWHeightInch * mmPerInch; - final double pfIWidthMM = pfIWidthInch * mmPerInch; - final double pfIHeightMM = pfIHeightInch * mmPerInch; - - 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"); - 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"); - System.err.println("PF: Page orientation "+pf.getOrientation()); - - /** - * User (0,0) is typically outside the imageable area, so we must - * translate by the X and Y values in the PageFormat to avoid clipping - */ - - final int scaleComp; - { - final int xScaleComp = (int) Math.round(printDPI/72.0); - final int yScaleComp = (int) Math.round(printDPI/72.0); - scaleComp = Math.min(xScaleComp, yScaleComp); - } - final double scale; - { - final double xScale = 72.0/printDPI; - final double yScale = 72.0/printDPI; - scale = Math.min(xScale, yScale); - } + 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; - System.err.println("PRINT offscreen: "+printOffscreen+", thread "+Thread.currentThread().getName()); - System.err.println("PRINT DPI: "+printDPI+", scaleComp "+scaleComp); - awtPrintObject.setupPrint(); - - final int frameWidth = frame.getWidth(); - final int frameHeight= frame.getHeight(); - - final double moveX, moveY; - - if( scaleComp != 1 ) { - final int frameWidthS = frameWidth*(scaleComp-1); - final int frameHeightS = frameHeight*(scaleComp-1); - - double xMargin = (pf.getImageableWidth() - frameWidthS*scale)/2; - double yMargin = (pf.getImageableHeight() - frameHeightS*scale)/2; - moveX = pf.getImageableX() + xMargin; - moveY = pf.getImageableY() + yMargin; - System.err.println("PRINT DPI: "+printDPI+", scale "+scale+", margin "+xMargin+"/"+yMargin+", move "+moveX+"/"+moveY+ - ", frame: "+frameWidth+"x"+frameHeight+" -> "+frameWidthS+"x"+frameHeightS); - - AWTEDTExecutor.singleton.invoke(true, new Runnable() { - public void run() { - frame.setSize(frameWidthS, frameHeightS); - frame.invalidate(); - frame.validate(); - } - }); - } else { - moveX = pf.getImageableX(); - moveY = pf.getImageableY(); - System.err.println("PRINT DPI: "+printDPI+", scale "+scale+", move "+moveX+"/"+moveY+ - ", frame: "+frameWidth+"x"+frameHeight); - } - - final Graphics2D printG2D = (Graphics2D)g; - - final Graphics2D offscreenG2D; - final BufferedImage offscreenImage; - if( printOffscreen ) { - final int w = frame.getWidth(); - final int h = frame.getHeight(); - offscreenImage = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR); - offscreenG2D = (Graphics2D) offscreenImage.getGraphics(); - offscreenG2D.setClip(0, 0, w, h); + 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()); + + /** + * We fit the frame into the imageable area with the desired DPI. + *

+ * We assume AWT painting happens w/ 72 dpi! + *

+ *

+ * The frame borders are considered. + *

+ */ + final Insets frameInsets = frame.getInsets(); + final int frameWidth = frame.getWidth(); + final int frameHeight= frame.getHeight(); + final int frameWidthS; + final int frameHeightS; + final double scaleComp; + { + final int frameBorderW = frameInsets.left + frameInsets.right; + final int frameBorderH = frameInsets.top + frameInsets.bottom; + final double sx = pf.getImageableWidth() / ( frameWidth + frameBorderW ); + final double sy = pf.getImageableHeight() / ( frameHeight + frameBorderH ); + scaleComp = Math.min(sx, sy) * ( printDPI/72.0 ); + if( 0f < scaleComp ) { + frameWidthS = (int) ( frameWidth*scaleComp ); // cut off FIXME + frameHeightS = (int) ( frameHeight*scaleComp ); // cut off FIXME } else { - offscreenG2D = null; - offscreenImage = null; - } - - final Graphics2D g2d = null != offscreenG2D ? offscreenG2D : printG2D; - - if( g2d != offscreenG2D ) { - g2d.translate(moveX, moveY); - g2d.scale(scale , scale ); + frameWidthS = frameWidth; + frameHeightS = frameHeight; } + } + // Since we fit the frame size into the imageable size respecting the DPI, + // we simply can scale the print graphics matrix to the DPI + // w/o the need to fiddle w/ the margins (matrix translation). + final double scaleGraphics = 72.0 / printDPI; + + System.err.println("PRINT offscreen: "+printOffscreen+", thread "+Thread.currentThread().getName()); + System.err.println("PRINT DPI: "+printDPI+", AA "+printAA+", scaleGraphics "+scaleGraphics+", scaleComp "+scaleComp+ + ", frame: border "+frameInsets+", size "+frameWidth+"x"+frameHeight+" -> "+frameWidthS+"x"+frameHeightS); + + final Graphics2D printG2D = (Graphics2D)g; + final Graphics2D offscreenG2D; + final BufferedImage offscreenImage; + final Graphics2D g2d; + if( printOffscreen ) { + offscreenImage = new BufferedImage(frameWidthS, frameHeightS, BufferedImage.TYPE_4BYTE_ABGR); + offscreenG2D = (Graphics2D) offscreenImage.getGraphics(); + offscreenG2D.setClip(0, 0, frameWidthS, frameHeightS); + g2d = offscreenG2D; + } else { + offscreenG2D = null; + offscreenImage = null; + g2d = printG2D; + g2d.translate(pf.getImageableX(), pf.getImageableY()); + g2d.scale(scaleGraphics, scaleGraphics); + } + if( printAA ) { + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + } + awtPrintObject.setupPrint(g2d); + try { + AWTEDTExecutor.singleton.invoke(true, new Runnable() { + public void run() { + frame.setSize(frameWidthS, frameHeightS); + frame.invalidate(); + frame.validate(); + } + }); + AWTEDTExecutor.singleton.invoke(true, new Runnable() { public void run() { frame.printAll(g2d); } } ); - if( scaleComp != 1 ) { - System.err.println("PRINT DPI: reset frame size "+frameWidth+"x"+frameHeight); - AWTEDTExecutor.singleton.invoke(true, new Runnable() { - public void run() { - frame.setSize(frameWidth, frameHeight); - frame.invalidate(); - frame.validate(); - } - }); - } + System.err.println("PRINT DPI: reset frame size "+frameWidth+"x"+frameHeight); + AWTEDTExecutor.singleton.invoke(true, new Runnable() { + public void run() { + frame.setSize(frameWidth, frameHeight); + frame.invalidate(); + frame.validate(); + } + }); + } finally { awtPrintObject.releasePrint(); - - if( g2d == offscreenG2D ) { - printG2D.translate(moveX, moveY); - printG2D.scale(scale , scale ); - printG2D.drawImage(offscreenImage, 0, 0, offscreenImage.getWidth(), offscreenImage.getHeight(), null); // Null ImageObserver since image data is ready. - } - - /* tell the caller that this page is part of the printed document */ - return PAGE_EXISTS; } + + if( printOffscreen ) { + printG2D.translate(pf.getImageableX(), pf.getImageableY()); + printG2D.scale(scaleGraphics, scaleGraphics); + printG2D.drawImage(offscreenImage, 0, 0, offscreenImage.getWidth(), offscreenImage.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(); + } + } + private RecursiveLock lock = LockFactory.createRecursiveLock(); private int printCount = 0; public TiledPrintingAWTBase() { super(); } - protected void doPrintAuto(Frame frame, AWTPrintLifecycle awtPrintObject, - Printable printable, int pOrientation, Paper paper, boolean offscreen, int dpi) { - final PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); - aset.add(MediaSizeName.ISO_A1); // 594 × 841 mm - aset.add(MediaSizeName.ISO_A2); // 420 × 594 mm - aset.add(MediaSizeName.ISO_A3); // 297 × 420 mm - aset.add(MediaSizeName.ISO_A4); // 210 × 297 mm - - printCount++; - - final String psMimeType = "application/postscript"; - final String pdfMimeType = "application/pdf"; - final PrinterJob pj = PrinterJob.getPrinterJob(); - - StreamPrintServiceFactory[] factories = PrinterJob.lookupStreamPrintServices(pdfMimeType); - if (factories.length > 0) { - final String fname = getPrintFilename(dpi, "pdf"); - System.err.println("doPrint: dpi "+dpi+", "+fname); - FileOutputStream outstream; - try { - outstream = new FileOutputStream(fname); - Assert.assertTrue(doPrintAutoImpl(frame, awtPrintObject, printable, pj, factories[0].getPrintService(outstream), pOrientation, paper, offscreen, dpi)); - } catch (FileNotFoundException e) { - Assert.assertNull("Unexpected exception", e); - } - return; - } - System.err.println("No PDF"); + public void doPrintAuto(Frame frame, AWTPrintLifecycle awtPrintObject, + Printable printable, int pOrientation, Paper paper, boolean offscreen, int dpi, boolean antialiasing) { + lock.lock(); + try { + final PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); + aset.add(MediaSizeName.ISO_A1); // 594 × 841 mm + aset.add(MediaSizeName.ISO_A2); // 420 × 594 mm + aset.add(MediaSizeName.ISO_A3); // 297 × 420 mm + aset.add(MediaSizeName.ISO_A4); // 210 × 297 mm + + printCount++; + + final String psMimeType = "application/postscript"; + final String pdfMimeType = "application/pdf"; + final PrinterJob pj = PrinterJob.getPrinterJob(); - factories = PrinterJob.lookupStreamPrintServices(psMimeType); - if (factories.length > 0) { - final String fname = getPrintFilename(dpi, "ps"); - System.err.println("doPrint: dpi "+dpi+", "+fname); - FileOutputStream outstream; - try { - outstream = new FileOutputStream(fname); - Assert.assertTrue(doPrintAutoImpl(frame, awtPrintObject, printable, pj, factories[0].getPrintService(outstream), pOrientation, paper, offscreen, dpi)); - } catch (FileNotFoundException e) { - Assert.assertNull("Unexpected exception", e); - } - return; - } - System.err.println("No PS"); + StreamPrintServiceFactory[] factories = PrinterJob.lookupStreamPrintServices(pdfMimeType); + if (factories.length > 0) { + final String fname = getPrintFilename(dpi, antialiasing, "pdf"); + System.err.println("doPrint: dpi "+dpi+", "+fname); + FileOutputStream outstream; + try { + outstream = new FileOutputStream(fname); + Assert.assertTrue(doPrintAutoImpl(frame, awtPrintObject, printable, pj, factories[0].getPrintService(outstream), pOrientation, paper, offscreen, dpi, antialiasing)); + } catch (FileNotFoundException e) { + Assert.assertNull("Unexpected exception", e); + } + return; + } + System.err.println("No PDF"); + + factories = PrinterJob.lookupStreamPrintServices(psMimeType); + if (factories.length > 0) { + final String fname = getPrintFilename(dpi, antialiasing, "ps"); + System.err.println("doPrint: dpi "+dpi+", "+fname); + FileOutputStream outstream; + try { + outstream = new FileOutputStream(fname); + Assert.assertTrue(doPrintAutoImpl(frame, awtPrintObject, printable, pj, factories[0].getPrintService(outstream), pOrientation, paper, offscreen, dpi, antialiasing)); + } catch (FileNotFoundException e) { + Assert.assertNull("Unexpected exception", e); + } + return; + } + System.err.println("No PS"); + } finally { + lock.unlock(); + } } - - private String getPrintFilename(int dpi, String suffix) { + private String getPrintFilename(int dpi, boolean antialiasing, String suffix) { final int maxSimpleTestNameLen = getMaxTestNameLen()+getClass().getSimpleName().length()+1; final String simpleTestName = getSimpleTestName("."); - return String.format("%-"+maxSimpleTestNameLen+"s-n%04d-dpi%03d.%s", simpleTestName, printCount, dpi, suffix).replace(' ', '_'); + final String sAA = antialiasing ? "aa_" : "raw"; + return String.format("%-"+maxSimpleTestNameLen+"s-n%04d-dpi%03d-%s.%s", simpleTestName, printCount, dpi, sAA, suffix).replace(' ', '_'); } - private boolean doPrintAutoImpl(Frame frame, AWTPrintLifecycle awtPrintObject, Printable printable, PrinterJob job, StreamPrintService ps, int pOrientation, - Paper paper, boolean offscreen, int dpi) { + Paper paper, boolean offscreen, int dpi, boolean antialiasing) { this.awtPrintObject = awtPrintObject; this.frame = frame; printOffscreen = offscreen; printDPI = dpi; + printAA = antialiasing; boolean ok = true; try { PageFormat pageFormat = job.defaultPage(); @@ -287,21 +314,37 @@ public abstract class TiledPrintingAWTBase extends UITestCase implements Printab return ok; } - protected void doPrintManual(Frame frame, AWTPrintLifecycle awtPrintObject, Printable printable, boolean offscreen, int dpi) { - this.awtPrintObject = awtPrintObject; - this.frame = frame; - printOffscreen = offscreen; - printDPI = dpi; - PrinterJob job = PrinterJob.getPrinterJob(); - job.setPrintable(printable); - boolean ok = job.printDialog(); - if (ok) { - try { - job.print(); - } catch (PrinterException ex) { - ex.printStackTrace(); + public void doPrintManual(Frame frame, AWTPrintLifecycle awtPrintObject, Printable printable, boolean offscreen, int dpi, boolean antialiasing) { + lock.lock(); + try { + this.awtPrintObject = awtPrintObject; + this.frame = frame; + printOffscreen = offscreen; + printDPI = dpi; + printAA = antialiasing; + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(printable); + boolean ok = job.printDialog(); + if (ok) { + try { + job.print(); + } catch (PrinterException ex) { + ex.printStackTrace(); + } } - } + } finally { + lock.unlock(); + } } + /** Wait for idle .. simply acquiring all locks and releasing them. */ + public void waitUntilPrintJobsIdle() { + lock.lock(); + try { + lockPrinting.lock(); + lockPrinting.unlock(); + } finally { + lock.unlock(); + } + } } \ No newline at end of file -- cgit v1.2.3