1 /*
   2  * Copyright (c) 2015, 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 import java.awt.Button;
  26 import java.awt.Color;
  27 import java.awt.Dimension;
  28 import java.awt.Frame;
  29 import java.awt.JobAttributes;
  30 import java.awt.PageAttributes;
  31 import java.awt.PrintJob;
  32 import java.awt.Font;
  33 import java.awt.FontMetrics;
  34 import java.awt.Graphics;
  35 import java.awt.JobAttributes.DialogType;
  36 import java.awt.JobAttributes.SidesType;
  37 import java.awt.PageAttributes.OrientationRequestedType;
  38 import java.awt.PageAttributes.OriginType;
  39 import java.awt.Dialog;
  40 import java.awt.Panel;
  41 import java.awt.TextArea;
  42 import java.awt.event.ActionEvent;
  43 import java.awt.event.ActionListener;
  44 
  45 /*
  46   @test
  47   @bug 4227128 8066139
  48   @summary  Test printing at resolutions > 72dpi
  49   @author dpm: area=awt.print
  50   @run main/manual HighResTest
  51  */
  52 public 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-P";
  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.
 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 
 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   */
 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
 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