1 /*
2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 /*
26   @test
27   @bug 4227128 8066139
28   @summary  Test printing at resolutions > 72dpi
29   @author dpm: area=awt.print
30   @run main/manual HighResTest
31  */
32 import java.awt.Button;
33 import java.awt.Color;
34 import java.awt.Dimension;
35 import java.awt.Frame;
36 import java.awt.JobAttributes;
37 import java.awt.PageAttributes;
38 import java.awt.PrintJob;
39 import java.awt.Font;
40 import java.awt.FontMetrics;
41 import java.awt.Graphics;
42 import java.awt.JobAttributes.DialogType;
43 import java.awt.JobAttributes.SidesType;
44 import java.awt.PageAttributes.OrientationRequestedType;
45 import java.awt.PageAttributes.OriginType;
46 import java.awt.Dialog;
47 import java.awt.Panel;
48 import java.awt.TextArea;
49 import java.awt.event.ActionEvent;
50 import java.awt.event.ActionListener;
51 
52 public class HighResTest {
53     static Frame f = new Frame();
54 
init()55     private static void init() {
56         String[] instructions = {
57             "To be able to run this test it is required to have a default",
58          "printer configured in your user environment.",
59          "If no default printer exists, then test passes.",
60          " ",
61          "There will be 2 print dialogs.  The first dialog should show",
62          "portrait as the selected orientation.  The 2nd dialog should show",
63          "landscape as the selected orientation.",
64          " ",
65          "Visual inspection of the printed pages is needed. A passing",
66          "test will print 2 pages in portrait and 2 pages in landscape.",
67          "The pages have on the center of the page the text \"Center\"",
68          "2 rectangles will appear above and below it, the one below is",
69          "filled."
70         };
71         Sysout.createDialog();
72         Sysout.printInstructions(instructions);
73 
74         PrintJob job = null;
75         Dimension dim = null;
76         JobAttributes jobAttributes = new JobAttributes();
77         PageAttributes pageAttributes = new PageAttributes();
78         String center = "Center";
79         Font font = new Font("SansSerif", Font.PLAIN, 200);
80         FontMetrics metrics = null;
81         int width = 0;
82         Graphics g = null;
83 
84         jobAttributes.setDialog(DialogType.NATIVE);
85         pageAttributes.setOrigin(OriginType.PRINTABLE);
86         pageAttributes.setPrinterResolution(new int[]{1200, 1200, 3});
87         pageAttributes.setOrientationRequested(
88                 OrientationRequestedType.PORTRAIT);
89         jobAttributes.setSides(SidesType.TWO_SIDED_LONG_EDGE);
90 
91         job = f.getToolkit().getPrintJob(f, "Portrait Test", jobAttributes,
92                                           pageAttributes);
93         if (job != null) {
94             dim = job.getPageDimension();
95             for (int i = 0; i < 2; i++) {
96                 g = job.getGraphics();
97 
98                 g.drawLine(0, 0, dim.width, 0);
99                 g.drawLine(dim.width, 0, dim.width, dim.height);
100                 g.drawLine(dim.width, dim.height, 0, dim.height);
101                 g.drawLine(0, dim.height, 0, 0);
102 
103                 g.drawRect(dim.width / 2 - 200, dim.height / 3 - 300, 400, 600);
104                 g.fillRect(dim.width / 2 - 200, 2 * dim.height / 3 - 300, 400, 600);
105 
106                 g.setFont(font);
107                 metrics = g.getFontMetrics();
108                 width = metrics.stringWidth(center);
109                 g.setColor(Color.black);
110                 g.drawString(center, (dim.width / 2) - (width / 2), dim.height / 2);
111 
112                 g.dispose();
113             }
114             job.end();
115             job = null;
116         }
117 
118         pageAttributes.setOrientationRequested(
119                 OrientationRequestedType.LANDSCAPE);
120 
121         job = f.getToolkit().getPrintJob(f, "Landscape Test", jobAttributes,
122                                              pageAttributes);
123         if (job != null) {
124             dim = job.getPageDimension();
125             for (int i = 0; i < 2; i++) {
126                 g = job.getGraphics();
127                 g.drawLine(0, 0, dim.width, 0);
128                 g.drawLine(dim.width, 0, dim.width, dim.height);
129                 g.drawLine(dim.width, dim.height, 0, dim.height);
130                 g.drawLine(0, dim.height, 0, 0);
131 
132                 g.drawRect(dim.width / 2 - 200, dim.height / 3 - 300, 400, 600);
133                 g.fillRect(dim.width / 2 - 200, 2 * dim.height / 3 - 300, 400, 600);
134 
135                 g.setFont(font);
136                 metrics = g.getFontMetrics();
137                 width = metrics.stringWidth(center);
138                 g.setColor(Color.black);
139                 g.drawString(center, (dim.width / 2) - (width / 2), dim.height / 2);
140 
141                 g.dispose();
142             }
143             job.end();
144             job = null;
145         }
146         System.out.println("done");
147     }
148 
149 
150 
151     /**
152      * ***************************************************
153      * Standard Test Machinery Section      DO NOT modify anything in this section -- it's a
154       standard chunk of code which has all of the
155       synchronisation necessary for the test harness.
156       By keeping it the same in all tests, it is easier
157       to read and understand someone else's test, as
158       well as insuring that all tests behave correctly
159       with the test harness.
160      There is a section following this for test-defined
161       classes
162     *****************************************************
163      */
164     private static boolean theTestPassed = false;
165     private static boolean testGeneratedInterrupt = false;
166     private static String failureMessage = "";
167 
168     private static Thread mainThread = null;
169 
170     private static int sleepTime = 300000;
171 
main(String args[])172     public static void main(String args[]) throws InterruptedException    {
173         mainThread = Thread.currentThread();
174         try {
175             init();
176         } catch (TestPassedException e) {
177             //The test passed, so just return from main and harness will
178             // interepret this return as a pass
179             return;
180         }
181         //At this point, neither test passed nor test failed has been
182         // called -- either would have thrown an exception and ended the
183         // test, so we know we have multiple threads.
184 
185         //Test involves other threads, so sleep and wait for them to
186         // called pass() or fail()
187         try {
188             Thread.sleep(sleepTime);
189             //Timed out, so fail the test
190             throw new RuntimeException("Timed out after " + sleepTime / 1000 + " seconds");
191         } catch (InterruptedException e) {
192             if (!testGeneratedInterrupt) {
193                 throw e;
194             }
195 
196             //reset flag in case hit this code more than once for some reason (just safety)
197             testGeneratedInterrupt = false;
198             if (theTestPassed == false) {
199                 throw new RuntimeException(failureMessage);
200             }
201         }
202 
203     }//main
204 
setTimeoutTo(int seconds)205     public static synchronized void setTimeoutTo(int seconds)    {
206         sleepTime = seconds * 1000;
207     }
208 
pass()209     public static synchronized void pass()    {
210         Sysout.println("The test passed.");
211         //first check if this is executing in main thread
212         if (mainThread == Thread.currentThread()) {
213             //Still in the main thread, so set the flag just for kicks,
214             // and throw a test passed exception which will be caught
215             // and end the test.
216             theTestPassed = true;
217             throw new TestPassedException();
218         }
219         //pass was called from a different thread, so set the flag and interrupt
220         // the main thead.
221         theTestPassed = true;
222         testGeneratedInterrupt = true;
223         mainThread.interrupt();
224         Sysout.dispose();
225     }//pass()
226 
fail()227     public static synchronized void fail()    {
228         //test writer didn't specify why test failed, so give generic
229         fail("it just plain failed! :-)");
230     }
231 
fail(String whyFailed)232     public static synchronized void fail(String whyFailed)    {
233         Sysout.println("The test failed: " + whyFailed);
234         //check if this called from main thread
235         if (mainThread == Thread.currentThread()) {
236             //If main thread, fail now 'cause not sleeping
237             throw new RuntimeException(whyFailed);
238         }
239         theTestPassed = false;
240         testGeneratedInterrupt = true;
241         failureMessage = whyFailed;
242         mainThread.interrupt();
243         Sysout.dispose();
244     }//fail()
245 
246  }// class HighResTest
247 
248 //This exception is used to exit from any level of call nesting
249 // when it's determined that the test has passed, and immediately
250 // end the test.
251 class TestPassedException extends RuntimeException
252  {
253  }
254 
255 //*********** End Standard Test Machinery Section **********
256 
257 //************** End classes defined for the test *******************
258 
259 
260 
261 
262 /****************************************************
263  Standard Test Machinery
264  DO NOT modify anything below -- it's a standard
265   chunk of code whose purpose is to make user
266   interaction uniform, and thereby make it simpler
267   to read and understand someone else's test.
268  ****************************************************/
269 
270 /**
271  This is part of the standard test machinery.
272  It creates a dialog (with the instructions), and is the interface
273   for sending text messages to the user.
274  To print the instructions, send an array of strings to Sysout.createDialog
275   WithInstructions method.  Put one line of instructions per array entry.
276  To display a message for the tester to see, simply call Sysout.println
277   with the string to be displayed.
278  This mimics System.out.println but works within the test harness as well
279   as standalone.
280  */
281 
282 class Sysout {
283     private static TestDialog dialog;
284 
createDialogWithInstructions(String[] instructions)285     public static void createDialogWithInstructions(String[] instructions)    {
286         dialog = new TestDialog(new Frame(), "Instructions");
287         dialog.printInstructions(instructions);
288         println("Any messages for the tester will display here.");
289     }
290 
createDialog()291     public static void createDialog() {
292         dialog = new TestDialog(new Frame(), "Instructions");
293         String[] defInstr = {"Instructions will appear here. ", ""};
294         dialog.printInstructions(defInstr);
295         println("Any messages for the tester will display here.");
296     }
297 
298 
printInstructions(String[] instructions)299     public static void printInstructions(String[] instructions)    {
300         dialog.printInstructions(instructions);
301     }
302 
303 
println(String messageIn)304     public static void println(String messageIn)    {
305         dialog.displayMessage(messageIn);
306     }
307 
dispose()308     public static void dispose() {
309         Sysout.println("Shutting down the Java process..");
310         HighResTest.f.dispose();
311         dialog.dispose();
312     }
313  }// Sysout  class
314 
315 /**
316   This is part of the standard test machinery.  It provides a place for the
317    test instructions to be displayed, and a place for interactive messages
318    to the user to be displayed.
319   To have the test instructions displayed, see Sysout.
320   To have a message to the user be displayed, see Sysout.
321   Do not call anything in this dialog directly.
322   */
323 class TestDialog extends Dialog implements ActionListener
324 {
325 
326     TextArea instructionsText;
327     TextArea messageText;
328     int maxStringLength = 80;
329     Panel buttonP = new Panel();
330     Button passB = new Button("pass");
331     Button failB = new Button("fail");
332 
333     //DO NOT call this directly, go through Sysout
TestDialog(Frame frame, String name)334     public TestDialog(Frame frame, String name)    {
335         super(frame, name);
336         int scrollBoth = TextArea.SCROLLBARS_BOTH;
337         instructionsText = new TextArea("", 15, maxStringLength, scrollBoth);
338         add("North", instructionsText);
339 
340         messageText = new TextArea("", 5, maxStringLength, scrollBoth);
341         add("Center", messageText);
342 
343         passB = new Button("pass");
344         passB.setActionCommand("pass");
345         passB.addActionListener(this);
346         buttonP.add("East", passB);
347 
348         failB = new Button("fail");
349         failB.setActionCommand("fail");
350         failB.addActionListener(this);
351         buttonP.add("West", failB);
352 
353         add("South", buttonP);
354         pack();
355 
356         show();
357     }// TestDialog()
358 
359     //DO NOT call this directly, go through Sysout
printInstructions(String[] instructions)360     public void printInstructions(String[] instructions)    {
361         //Clear out any current instructions
362         instructionsText.setText("");
363 
364         //Go down array of instruction strings
365 
366         String printStr, remainingStr;
367         for (int i = 0; i < instructions.length; i++) {
368             //chop up each into pieces maxSringLength long
369             remainingStr = instructions[i];
370             while (remainingStr.length() > 0) {
371                 //if longer than max then chop off first max chars to print
372                 if (remainingStr.length() >= maxStringLength) {
373                     //Try to chop on a word boundary
374                     int posOfSpace = remainingStr.
375                             lastIndexOf(' ', maxStringLength - 1);
376 
377                     if (posOfSpace <= 0) {
378                         posOfSpace = maxStringLength - 1;
379                     }
380 
381                     printStr = remainingStr.substring(0, posOfSpace + 1);
382                     remainingStr = remainingStr.substring(posOfSpace + 1);
383                 } //else just print
384                 else {
385                     printStr = remainingStr;
386                     remainingStr = "";
387                 }
388 
389                 instructionsText.append(printStr + "\n");
390 
391             }// while
392 
393         }// for
394 
395     }//printInstructions()
396 
397     //DO NOT call this directly, go through Sysout
displayMessage(String messageIn)398     public void displayMessage(String messageIn)    {
399         messageText.append(messageIn + "\n");
400     }
401 
402     //catch presses of the passed and failed buttons.
403     //simply call the standard pass() or fail() static methods of
404     //HighResTest
actionPerformed(ActionEvent e)405     public void actionPerformed(ActionEvent e)    {
406         if (e.getActionCommand() == "pass") {
407             HighResTest.pass();
408         } else {
409             HighResTest.fail();
410         }
411     }
412 }// TestDialog  class
413