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 */
32import java.awt.Button;
33import java.awt.Color;
34import java.awt.Dimension;
35import java.awt.Frame;
36import java.awt.JobAttributes;
37import java.awt.PageAttributes;
38import java.awt.PrintJob;
39import java.awt.Font;
40import java.awt.FontMetrics;
41import java.awt.Graphics;
42import java.awt.JobAttributes.DialogType;
43import java.awt.JobAttributes.SidesType;
44import java.awt.PageAttributes.OrientationRequestedType;
45import java.awt.PageAttributes.OriginType;
46import java.awt.Dialog;
47import java.awt.Panel;
48import java.awt.TextArea;
49import java.awt.event.ActionEvent;
50import java.awt.event.ActionListener;
51
52public class HighResTest {
53    static Frame f = new Frame();
54
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
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
205    public static synchronized void setTimeoutTo(int seconds)    {
206        sleepTime = seconds * 1000;
207    }
208
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
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
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.
251class 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
282class Sysout {
283    private static TestDialog dialog;
284
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
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
299    public static void printInstructions(String[] instructions)    {
300        dialog.printInstructions(instructions);
301    }
302
303
304    public static void println(String messageIn)    {
305        dialog.displayMessage(messageIn);
306    }
307
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  */
323class 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
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
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
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
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