JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
OnscreenPrintable.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 */
28package com.jogamp.opengl.test.junit.jogl.tile;
29
30import java.awt.Container;
31import java.awt.Graphics;
32import java.awt.Graphics2D;
33import java.awt.Insets;
34import java.awt.RenderingHints;
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;
40
41import com.jogamp.common.util.awt.AWTEDTExecutor;
42import com.jogamp.opengl.util.TileRenderer;
43
44/**
45 * <h5>Scaling of Frame and GL content</h5>
46 * <p>
47 * We fit the frame into the imageable area with for 72 dpi,
48 * assuming that is the default AWT painting density.
49 * </p>
50 * <p>
51 * The frame borders are considered.
52 * </p>
53 * <p>
54 * The frame's scale factor is used for the graphics print matrix
55 * of the overall print-job, hence no frame resize is required.
56 * </p>
57 * <p>
58 * The GL scale factor 'scaleGLMatXY', 72dpi/glDPI, is passed to the GL object
59 * which locally scales the print matrix and renders the scene with 1/scaleGLMatXY pixels.
60 * </p>
61 */
62public class OnscreenPrintable extends PrintableBase implements Printable {
63
64 /**
65 *
66 * @param job
67 * @param printContainer
68 * @param printDPI
69 * @param numSamples multisampling value: < 0 turns off, == 0 leaves as-is, > 0 enables using given num samples
70 * @param tileWidth custom tile width for {@link TileRenderer#setTileSize(int, int, int) tile renderer}, pass -1 for default.
71 * @param tileHeight custom tile height for {@link TileRenderer#setTileSize(int, int, int) tile renderer}, pass -1 for default.
72 */
73 public OnscreenPrintable(final PrinterJob job, final Container printContainer, final int printDPI, final int numSamples, final int tileWidth, final int tileHeight) {
74 super(job, printContainer, printDPI, numSamples, tileWidth, tileHeight);
75 }
76
77
78 @Override
79 public int print(final Graphics g, final PageFormat pf, final int page) throws PrinterException {
80 if (page > 0) { // We have only one page, and 'page' is zero-based
81 return NO_SUCH_PAGE;
82 }
83
84 lockPrinting.lock();
85 try {
86 final Paper paper = pf.getPaper();
87 final double paperWWidthInch = paper.getWidth() / 72.0;
88 final double paperWHeightInch = paper.getHeight() / 72.0;
89 final double paperIWidthInch = paper.getImageableWidth() / 72.0;
90 final double paperIHeightInch = paper.getImageableHeight() / 72.0;
91 final double paperWWidthMM = paperWWidthInch * MM_PER_INCH;
92 final double paperWHeightMM = paperWHeightInch * MM_PER_INCH;
93 final double paperIWidthMM = paperIWidthInch * MM_PER_INCH;
94 final double paperIHeightMM = paperIHeightInch * MM_PER_INCH;
95
96 final double pfWWidthInch = pf.getWidth() / 72.0;
97 final double pfWHeightInch = pf.getHeight() / 72.0;
98 final double pfIWidthInch = pf.getImageableWidth() / 72.0;
99 final double pfIHeightInch = pf.getImageableHeight() / 72.0;
100 final double pfWWidthMM = pfWWidthInch * MM_PER_INCH;
101 final double pfWHeightMM = pfWHeightInch * MM_PER_INCH;
102 final double pfIWidthMM = pfIWidthInch * MM_PER_INCH;
103 final double pfIHeightMM = pfIHeightInch * MM_PER_INCH;
104
105 System.err.println("PF: Paper whole size "+
106 Math.round(paperWWidthMM)+" x "+Math.round(paperWHeightMM)+" mm, "+
107 Math.round(paperWWidthInch)+" x "+Math.round(paperWHeightInch)+" inch");
108
109 System.err.println("PF: Paper image size "+paper.getImageableX()+" / "+paper.getImageableY()+" "+
110 Math.round(paperIWidthMM)+" x "+Math.round(paperIHeightMM)+" mm, "+
111 Math.round(paperIWidthInch)+" x "+Math.round(paperIHeightInch)+" inch, "+
112 Math.round(paper.getImageableWidth())+"x"+Math.round(paper.getImageableHeight())+" 72dpi dots");
113
114 System.err.println("PF: Page whole size "+
115 Math.round(pfWWidthMM)+" x "+Math.round(pfWHeightMM)+" mm, "+
116 Math.round(pfWWidthInch)+" x "+Math.round(pfWHeightInch)+" inch");
117
118 System.err.println("PF: Page image size "+pf.getImageableX()+" / "+pf.getImageableY()+" "+
119 Math.round(pfIWidthMM)+" x "+Math.round(pfIHeightMM)+" mm, "+
120 Math.round(pfIWidthInch)+" x "+Math.round(pfIHeightInch)+" inch, "+
121 Math.round(pf.getImageableWidth())+"x"+Math.round(pf.getImageableHeight())+" 72dpi dots");
122
123 System.err.println("PF: Page orientation "+pf.getOrientation());
124
125 /**
126 * See: 'Scaling of Frame and GL content' in Class description!
127 * Note: Frame size contains the frame border (i.e. insets)!
128 */
129 final Insets frameInsets = cont.getInsets();
130 final int frameWidth = cont.getWidth();
131 final int frameHeight= cont.getHeight();
132 final double scaleGraphics = dpi / 72.0;
133 final int frameSWidth = (int) ( frameWidth * scaleGraphics );
134 final int frameSHeight = (int) ( frameHeight * scaleGraphics );
135 final double scaleComp72;
136 {
137 final double sx = pf.getImageableWidth() / frameWidth;
138 final double sy = pf.getImageableHeight() / frameHeight;
139 scaleComp72 = Math.min(sx, sy);
140 }
141 System.err.println("PRINT.onscrn thread "+Thread.currentThread().getName());
142 System.err.println("PRINT.onscrn DPI: scaleGraphics "+scaleGraphics+", scaleComp72 "+scaleComp72);
143 System.err.println("PRINT.onscrn DPI: frame: border "+frameInsets+", size "+frameWidth+"x"+frameHeight+
144 " -> scaled "+frameSWidth+ "x" + frameSHeight);
145
146 final Graphics2D g2d = (Graphics2D)g;
147 System.err.println("PRINT at.pre: "+g2d.getTransform());
148 g2d.translate(pf.getImageableX(), pf.getImageableY());
149 g2d.scale(scaleComp72, scaleComp72); // WARNING: Produces rounding artifacts due to diff scale-factor of AWT/GL comps !!!
150 // g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
151 g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
152
153 AWTEDTExecutor.singleton.invoke(true, new Runnable() {
154 public void run() {
155 cont.printAll(g2d);
156 }
157 });
158
159 /* tell the caller that this page is part of the printed document */
160 return PAGE_EXISTS;
161 } finally {
162 lockPrinting.unlock();
163 }
164 }
165}
int print(final Graphics g, final PageFormat pf, final int page)
OnscreenPrintable(final PrinterJob job, final Container printContainer, final int printDPI, final int numSamples, final int tileWidth, final int tileHeight)