1/* 2 * Copyright (c) 2007, 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 @test 26 @bug 4386025 27 @summary fonts not in win32 font directory print incorrectly. 28 @author prr: area=PrinterJob 29 @run main/manual CustomFont 30*/ 31import java.io.*; 32import java.awt.*; 33import java.awt.event.*; 34import java.awt.print.*; 35 36 37public class CustomFont implements Printable { 38 39 private Image opaqueimg,transimg; 40 41 private static void init() { 42 43 //*** Create instructions for the user here *** 44 45 String[] instructions = { 46 "On-screen inspection is not possible for this printing-specific", 47 "test therefore its only output is a printed page.", 48 "To be able to run this test it is required to have a default", 49 "printer configured in your user environment.", 50 "", 51 "Visual inspection of the printed page is needed. A passing", 52 "test will print a page on which one line of text will be", 53 "printed: a long string of 'A' characters.", 54 "The A should have of a curly style", 55 "If instead its in the default sansserif font, the test fails", 56 }; 57 58 Sysout.createDialog( ); 59 Sysout.printInstructions( instructions ); 60 61 PrinterJob pjob = PrinterJob.getPrinterJob(); 62 63 Book book = new Book(); 64 65 PageFormat portrait = pjob.defaultPage(); 66 book.append(new CustomFont(),portrait); 67 68 pjob.setPageable(book); 69 70 if (pjob.printDialog()) { 71 try { 72 pjob.print(); 73 } catch (PrinterException e) { 74 System.err.println(e); 75 e.printStackTrace(); 76 } 77 } 78 System.out.println("Done Printing"); 79 80 }//End init() 81 82 83 Font customFont; 84 public CustomFont() { 85 try { 86 FileInputStream fin = new FileInputStream("A.ttf"); 87 Font cf = Font.createFont(Font.TRUETYPE_FONT, fin); 88 customFont = cf.deriveFont(Font.PLAIN, 14); 89 } catch (Exception ioe) { 90 System.err.println(ioe.getMessage()); 91 customFont = new Font("serif", Font.PLAIN, 14); 92 } 93 } 94 95 public int print(Graphics g, PageFormat pgFmt, int pgIndex) { 96 97 Graphics2D g2D = (Graphics2D) g; 98 g2D.translate(pgFmt.getImageableX(), pgFmt.getImageableY()); 99 100 g2D.setColor(Color.black); 101 g2D.setFont(customFont); 102 String str = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; 103 g.drawString(str, 100, 100); 104 105 return Printable.PAGE_EXISTS; 106 } 107 108 /** 109 * The graphics is scaled and the font and the positions 110 * are reduced in respect to the scaling, so that all 111 * printing should be the same. 112 * 113 * @param g2D graphics2D to paint on 114 * @param font font to paint 115 * @param scale scale for the painting 116 * @param x x position 117 * @param y y position 118 */ 119 private void printScale(Graphics2D g2D, Font font, 120 float scale, float x, float y) { 121 122 int RES = 72; 123 124 g2D.scale(scale, scale); 125 126 g2D.setFont (font.deriveFont(10.0f / scale)); 127 g2D.drawString("This text is scaled by a factor of " + scale, 128 x * RES / scale, y * RES / scale); 129 130 g2D.scale(1/scale, 1/scale); 131 132} 133 134 /***************************************************** 135 Standard Test Machinery Section 136 DO NOT modify anything in this section -- it's a 137 standard chunk of code which has all of the 138 synchronisation necessary for the test harness. 139 By keeping it the same in all tests, it is easier 140 to read and understand someone else's test, as 141 well as insuring that all tests behave correctly 142 with the test harness. 143 There is a section following this for test-defined 144 classes 145 ******************************************************/ 146 private static boolean theTestPassed = false; 147 private static boolean testGeneratedInterrupt = false; 148 private static String failureMessage = ""; 149 150 private static Thread mainThread = null; 151 152 private static int sleepTime = 300000; 153 154 public static void main( String args[] ) throws InterruptedException 155 { 156 mainThread = Thread.currentThread(); 157 try 158 { 159 init(); 160 } 161 catch( TestPassedException e ) 162 { 163 //The test passed, so just return from main and harness will 164 // interepret this return as a pass 165 return; 166 } 167 //At this point, neither test passed nor test failed has been 168 // called -- either would have thrown an exception and ended the 169 // test, so we know we have multiple threads. 170 171 //Test involves other threads, so sleep and wait for them to 172 // called pass() or fail() 173 try 174 { 175 Thread.sleep( sleepTime ); 176 //Timed out, so fail the test 177 throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); 178 } 179 catch (InterruptedException e) 180 { 181 if( ! testGeneratedInterrupt ) throw e; 182 183 //reset flag in case hit this code more than once for some reason (just safety) 184 testGeneratedInterrupt = false; 185 if ( theTestPassed == false ) 186 { 187 throw new RuntimeException( failureMessage ); 188 } 189 } 190 191 }//main 192 193 public static synchronized void setTimeoutTo( int seconds ) 194 { 195 sleepTime = seconds * 1000; 196 } 197 198 public static synchronized void pass() 199 { 200 Sysout.println( "The test passed." ); 201 Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); 202 //first check if this is executing in main thread 203 if ( mainThread == Thread.currentThread() ) 204 { 205 //Still in the main thread, so set the flag just for kicks, 206 // and throw a test passed exception which will be caught 207 // and end the test. 208 theTestPassed = true; 209 throw new TestPassedException(); 210 } 211 //pass was called from a different thread, so set the flag and interrupt 212 // the main thead. 213 theTestPassed = true; 214 testGeneratedInterrupt = true; 215 mainThread.interrupt(); 216 }//pass() 217 218 public static synchronized void fail() 219 { 220 //test writer didn't specify why test failed, s fail( "it just plain failed! :-)" ); 221 } 222 223 public static synchronized void fail( String whyFailed ) 224 { 225 Sysout.println( "The test failed: " + whyFailed ); 226 Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); 227 //check if this called from main thread 228 if ( mainThread == Thread.currentThread() ) 229 { 230 //If main thread, fail now 'cause not sleeping 231 throw new RuntimeException( whyFailed ); 232 } 233 theTestPassed = false; 234 testGeneratedInterrupt = true; 235 failureMessage = whyFailed; 236 mainThread.interrupt(); 237 }//fail() 238 239}// class CustomFont 240 241//This exception is used to exit from any level of call nesting 242// when it's determined that the test has passed, and immediately 243// end the test. 244class TestPassedException extends RuntimeException 245 { 246 } 247 248 249//************** End classes defined for the test ******************* 250 251 252 253 254/**************************************************** 255 Standard Test Machinery 256 DO NOT modify anything below -- it's a standard 257 chunk of code whose purpose is to make user 258 interaction uniform, and thereby make it simpler 259 to read and understand someone else's test. 260 ****************************************************/ 261 262/** 263 This is part of the standard test machinery. 264 It creates a dialog (with the instructions), and is the interface 265 for sending text messages to the user. 266 To print the instructions, send an array of strings to Sysout.createDialog 267 WithInstructions method. Put one line of instructions per array entry. 268 To display a message for the tester to see, simply call Sysout.println 269 with the string to be displayed. 270 This mimics System.out.println but works within the test harness as well 271 as standalone. 272 */ 273 274class Sysout 275 { 276 private static TestDialog dialog; 277 278 public static void createDialogWithInstructions( String[] instructions ) 279 { 280 dialog = new TestDialog( new Frame(), "Instructions" ); 281 dialog.printInstructions( instructions ); 282 dialog.show(); 283 println( "Any messages for the tester will display here." ); 284 } 285 286 public static void createDialog( ) 287 { 288 dialog = new TestDialog( new Frame(), "Instructions" ); 289 String[] defInstr = { "Instructions will appear here. ", "" } ; 290 dialog.printInstructions( defInstr ); 291 dialog.show(); 292 println( "Any messages for the tester will display here." ); 293 } 294 295 296 public static void printInstructions( String[] instructions ) 297 { 298 dialog.printInstructions( instructions ); 299 } 300 301 302 public static void println( String messageIn ) 303 { 304 dialog.displayMessage( messageIn ); 305 } 306 307 }// Sysout class 308 309/** 310 This is part of the standard test machinery. It provides a place for the 311 test instructions to be displayed, and a place for interactive messages 312 to the user to be displayed. 313 To have the test instructions displayed, see Sysout. 314 To have a message to the user be displayed, see Sysout. 315 Do not call anything in this dialog directly. 316 */ 317class TestDialog extends Dialog implements ActionListener { 318 319 TextArea instructionsText; 320 TextArea messageText; 321 int maxStringLength = 80; 322 Panel buttonP = new Panel(); 323 Button passB = new Button( "pass" ); 324 Button failB = new Button( "fail" ); 325 326 //DO NOT call this directly, go through Sysout 327 public TestDialog( Frame frame, String name ) 328 { 329 super( frame, name ); 330 int scrollBoth = TextArea.SCROLLBARS_BOTH; 331 instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); 332 add( "North", instructionsText ); 333 334 messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); 335 add("Center", messageText); 336 337 passB = new Button( "pass" ); 338 passB.setActionCommand( "pass" ); 339 passB.addActionListener( this ); 340 buttonP.add( "East", passB ); 341 342 failB = new Button( "fail" ); 343 failB.setActionCommand( "fail" ); 344 failB.addActionListener( this ); 345 buttonP.add( "West", failB ); 346 347 add( "South", buttonP ); 348 pack(); 349 350 show(); 351 }// TestDialog() 352 353 //DO NOT call this directly, go through Sysout 354 public void printInstructions( String[] instructions ) 355 { 356 //Clear out any current instructions 357 instructionsText.setText( "" ); 358 359 //Go down array of instruction strings 360 361 String printStr, remainingStr; 362 for( int i=0; i < instructions.length; i++ ) 363 { 364 //chop up each into pieces maxSringLength long 365 remainingStr = instructions[ i ]; 366 while( remainingStr.length() > 0 ) 367 { 368 //if longer than max then chop off first max chars to print 369 if( remainingStr.length() >= maxStringLength ) 370 { 371 //Try to chop on a word boundary 372 int posOfSpace = remainingStr. 373 lastIndexOf( ' ', maxStringLength - 1 ); 374 375 if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; 376 377 printStr = remainingStr.substring( 0, posOfSpace + 1 ); 378 remainingStr = remainingStr.substring( posOfSpace + 1 ); 379 } 380 //else just print 381 else 382 { 383 printStr = remainingStr; 384 remainingStr = ""; 385 } 386 387 instructionsText.append( printStr + "\n" ); 388 389 }// while 390 391 }// for 392 393 }//printInstructions() 394 395 //DO NOT call this directly, go through Sysout 396 public void displayMessage( String messageIn ) 397 { 398 messageText.append( messageIn + "\n" ); 399 } 400 401 //catch presses of the passed and failed buttons. 402 //simply call the standard pass() or fail() static methods of 403 //CustomFont 404 public void actionPerformed( ActionEvent e ) 405 { 406 if( e.getActionCommand() == "pass" ) 407 { 408 CustomFont.pass(); 409 } 410 else 411 { 412 CustomFont.fail(); 413 } 414 } 415 416 }// TestDialog class 417