JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
TiledPrintingAWTBase.java
Go to the documentation of this file.
1/**
2 * Copyright 2013 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.opengl.test.junit.jogl.tile;
30
31import java.awt.Component;
32import java.awt.Container;
33import java.awt.Rectangle;
34import java.awt.Window;
35import java.awt.print.PageFormat;
36import java.awt.print.Paper;
37import java.awt.print.Printable;
38import java.awt.print.PrinterException;
39import java.awt.print.PrinterJob;
40import java.io.FileNotFoundException;
41import java.io.FileOutputStream;
42import java.util.Locale;
43
44import com.jogamp.opengl.GLAutoDrawable;
45import javax.print.StreamPrintService;
46import javax.print.StreamPrintServiceFactory;
47import javax.print.attribute.HashPrintRequestAttributeSet;
48import javax.print.attribute.PrintRequestAttributeSet;
49import javax.print.attribute.standard.MediaSizeName;
50
51import jogamp.nativewindow.awt.AWTMisc;
52
53import org.junit.Assert;
54
55import com.jogamp.common.os.Platform;
56import com.jogamp.common.util.awt.AWTEDTExecutor;
57import com.jogamp.common.util.locks.LockFactory;
58import com.jogamp.common.util.locks.RecursiveLock;
59import com.jogamp.nativewindow.awt.AWTPrintLifecycle;
60import com.jogamp.opengl.test.junit.util.UITestCase;
61import com.jogamp.opengl.util.TileRenderer;
62
63/**
64 * Base unit test class implementing
65 * issuing {@link PrinterJob#print()} on a {@link Printable} implementation,
66 * i.e. {@link OnscreenPrintable} or {@link OffscreenPrintable}.
67 */
68public abstract class TiledPrintingAWTBase extends UITestCase {
69
70 private final RecursiveLock lock = LockFactory.createRecursiveLock();
71 private int printCount = 0;
72
74 super();
75 }
76
77 /**
78 *
79 * @param cont
80 * @param pOrientation
81 * @param paper
82 * @param offscrnImageType if < 0 onscreen, otherwise integer BufferedImage type
83 * @param dpi
84 * @param numSamples multisampling value: < 0 turns off, == 0 leaves as-is, > 0 enables using given num samples
85 * @param tileWidth custom tile width for {@link TileRenderer#setTileSize(int, int, int) tile renderer}, pass -1 for default.
86 * @param tileHeight custom tile height for {@link TileRenderer#setTileSize(int, int, int) tile renderer}, pass -1 for default.
87 * @param resizeWithinPrintTest TODO
88 */
89 public PrintableBase doPrintAuto(final Container cont, final int pOrientation, final Paper paper,
90 final int offscrnImageType, final int dpi, final int numSamples, final int tileWidth, final int tileHeight, final boolean resizeWithinPrintTest) {
91 lock.lock();
92 try {
93 final PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
94 aset.add(MediaSizeName.ISO_A1); // 594 × 841 mm
95 aset.add(MediaSizeName.ISO_A2); // 420 × 594 mm
96 aset.add(MediaSizeName.ISO_A3); // 297 × 420 mm
97 aset.add(MediaSizeName.ISO_A4); // 210 × 297 mm
98
99 printCount++;
100
101 final String psMimeType = "application/postscript";
102 final String pdfMimeType = "application/pdf";
103 final PrinterJob pj = PrinterJob.getPrinterJob();
104
105 StreamPrintServiceFactory[] factories = PrinterJob.lookupStreamPrintServices(pdfMimeType);
106 if (factories.length > 0) {
107 final String fname = getPrintFilename(offscrnImageType, dpi, numSamples, tileWidth, tileHeight, "pdf", resizeWithinPrintTest);
108 System.err.println("doPrint: dpi "+dpi+", "+fname);
109 FileOutputStream outstream;
110 try {
111 outstream = new FileOutputStream(fname);
112 return doPrintAutoImpl(cont, pj, factories[0].getPrintService(outstream), pOrientation, paper,
113 offscrnImageType, dpi, numSamples, tileWidth, tileHeight, resizeWithinPrintTest);
114 } catch (final FileNotFoundException e) {
115 Assert.assertNull("Unexpected exception", e);
116 }
117 }
118 System.err.println("No PDF");
119
120 factories = PrinterJob.lookupStreamPrintServices(psMimeType);
121 if (factories.length > 0) {
122 final String fname = getPrintFilename(offscrnImageType, dpi, numSamples, tileWidth, tileHeight, "ps", resizeWithinPrintTest);
123 System.err.println("doPrint: dpi "+dpi+", "+fname);
124 FileOutputStream outstream;
125 try {
126 outstream = new FileOutputStream(fname);
127 return doPrintAutoImpl(cont, pj, factories[0].getPrintService(outstream), pOrientation, paper, offscrnImageType, dpi, numSamples, tileWidth, tileHeight, resizeWithinPrintTest);
128 } catch (final FileNotFoundException e) {
129 Assert.assertNull("Unexpected exception", e);
130 }
131 }
132 System.err.println("No PS");
133 return null;
134 } finally {
135 lock.unlock();
136 }
137 }
138 private String getPrintFilename(final int offscrnImageType, final int dpi, final int numSamples, final int tileWidth, final int tileHeight, final String suffix, final boolean resizeWithinPrintTest) {
139 final int maxSimpleTestNameLen = getMaxTestNameLen()+getClass().getSimpleName().length()+1;
140 final String simpleTestName = getSimpleTestName(".");
141 final String onoffscrn = 0 > offscrnImageType ? "on_screen" : "offscrn_"+offscrnImageType;
142 final String aa = 0 <= numSamples ? "aa"+numSamples : "aaN";
143 return String.format((Locale)null, "%-"+maxSimpleTestNameLen+"s-n%04d-%s-dpi%03d-%s-tSz%04dx%04d-resize%d.%s",
144 simpleTestName, printCount, onoffscrn, dpi, aa, tileWidth, tileHeight, resizeWithinPrintTest?1:0, suffix).replace(' ', '_');
145 }
146 private PrintableBase doPrintAutoImpl(final Container cont, final PrinterJob job,
147 final StreamPrintService ps, final int pOrientation, final Paper paper,
148 final int offscrnImageType, final int dpi, final int numSamples, final int tileWidth, final int tileHeight, final boolean resizeWithinPrintTest) {
149 try {
150 final PageFormat pageFormat = job.defaultPage();
151 if( null != paper ) {
152 /**
153 Paper paper = new Paper();
154 paper.setSize(500,500); // Large Address Dimension
155 paper.setImageableArea(20, 20, 450, 420); */
156 pageFormat.setPaper(paper);
157 }
158 pageFormat.setOrientation(pOrientation); // PageFormat.LANDSCAPE or PageFormat.PORTRAIT
159 job.setPrintService(ps);
160 final PrintableBase printable;
161 if( 0 < offscrnImageType ) {
162 printable = new OffscreenPrintable(job, cont, dpi, numSamples, tileWidth, tileHeight, offscrnImageType, getPrintFilename(offscrnImageType, dpi, numSamples, tileWidth, tileHeight, "png", resizeWithinPrintTest));
163 } else {
164 printable = new OnscreenPrintable(job, cont, dpi, numSamples, tileWidth, tileHeight);
165 }
166 printable.job.setPrintable(printable, pageFormat);
167 doPrintImpl(printable, resizeWithinPrintTest);
168 return printable;
169 } catch (final PrinterException pe) {
170 pe.printStackTrace();
171 return null;
172 }
173 }
174
175 /**
176 * @param cont
177 * @param dpi
178 * @param numSamples multisampling value: < 0 turns off, == 0 leaves as-is, > 0 enables using given num samples
179 * @param tileWidth custom tile width for {@link TileRenderer#setTileSize(int, int, int) tile renderer}, pass -1 for default.
180 * @param tileHeight custom tile height for {@link TileRenderer#setTileSize(int, int, int) tile renderer}, pass -1 for default.
181 */
182 public PrintableBase doPrintManual(final Container cont, final int dpi, final int numSamples, final int tileWidth, final int tileHeight) {
183 lock.lock();
184 try {
185 final OnscreenPrintable printable = new OnscreenPrintable(PrinterJob.getPrinterJob(), cont, dpi, numSamples, tileWidth, tileHeight);
186 printable.job.setPrintable(printable);
187 final boolean ok = printable.job.printDialog();
188 if (ok) {
189 doPrintImpl(printable, false);
190 }
191 return printable;
192 } finally {
193 lock.unlock();
194 }
195 }
196
197 private final AWTMisc.ComponentAction resizePlusAction = new AWTMisc.ComponentAction() {
198 @Override
199 public void run(final Component c) {
200 final Rectangle r = c.getBounds();
201 r.width += 64;
202 r.height += 64;
203 c.setBounds(r);
204 } };
205 private final AWTMisc.ComponentAction resizeMinusAction = new AWTMisc.ComponentAction() {
206 @Override
207 public void run(final Component c) {
208 final Rectangle r = c.getBounds();
209 r.width -= 64;
210 r.height -= 64;
211 c.setBounds(r);
212 } };
213
214 private void doPrintImpl(final PrintableBase printable, final boolean resizeWithinPrintTest) {
215 final double scaleGLMatXY = 72.0 / printable.dpi;
216 System.err.println("PRINTable: "+printable.getClass().getSimpleName());
217 System.err.println("PRINT DPI: "+printable.dpi+", AA "+printable.numSamples+", scaleGL "+scaleGLMatXY);
218 final AWTPrintLifecycle.Context ctx =
219 AWTPrintLifecycle.Context.setupPrint(printable.cont, scaleGLMatXY, scaleGLMatXY,
220 printable.numSamples, printable.tileWidth, printable.tileHeight);
221 System.err.println("PRINT AWTPrintLifecycle.setup.count "+ctx.getCount());
222 final int w = printable.cont.getWidth();
223 final int h = printable.cont.getHeight();
224 final long t0 = Platform.currentTimeMillis();
225 try {
226 AWTEDTExecutor.singleton.invoke(true, new Runnable() {
227 public void run() {
228 try {
229 if( resizeWithinPrintTest ) {
230 System.err.println("PRINT resizeWithinPrint size+ "+(w+64)+"x"+(h+64));
231 AWTMisc.performAction(printable.cont, GLAutoDrawable.class, resizePlusAction);
232 printable.cont.validate();
233 if( printable.cont instanceof Window ) {
234 ((Window)printable.cont).pack();
235 }
236 }
237 printable.job.print();
238 } catch (final PrinterException ex) {
239 ex.printStackTrace();
240 }
241 } });
242 } finally {
243 ctx.releasePrint();
244 final long td = Platform.currentTimeMillis() - t0;
245 System.err.println("PRINT Duration "+td+" ms");
246 if( resizeWithinPrintTest ) {
247 AWTEDTExecutor.singleton.invoke(true, new Runnable() {
248 public void run() {
249 System.err.println("PRINT resizeWithinPrint repaint");
250 printable.cont.repaint();
251 System.err.println("PRINT resizeWithinPrint size- "+w+"x"+h);
252 AWTMisc.performAction(printable.cont, GLAutoDrawable.class, resizeMinusAction);
253 printable.cont.validate();
254 if( printable.cont instanceof Window ) {
255 ((Window)printable.cont).pack();
256 }
257 } });
258 }
259 System.err.println("PRINT AWTPrintLifecycle.release.count "+ctx.getCount());
260 }
261 }
262
263 /** Wait for idle .. simply acquiring all locks and releasing them. */
265 lock.lock();
266 try {
267 if( null != p ) {
268 p.waitUntilIdle();
269 }
270 } finally {
271 lock.unlock();
272 }
273 }
274}
Base unit test class implementing issuing PrinterJob#print() on a Printable implementation,...
PrintableBase doPrintManual(final Container cont, final int dpi, final int numSamples, final int tileWidth, final int tileHeight)
PrintableBase doPrintAuto(final Container cont, final int pOrientation, final Paper paper, final int offscrnImageType, final int dpi, final int numSamples, final int tileWidth, final int tileHeight, final boolean resizeWithinPrintTest)
void waitUntilPrintJobsIdle(final PrintableBase p)
Wait for idle .
A higher-level abstraction than GLDrawable which supplies an event based mechanism (GLEventListener) ...