30 import java.awt.geom.Rectangle2D; 31 import java.awt.image.BufferedImage; 32 import java.awt.print.*; 33 34 import javax.print.*; 35 import javax.print.attribute.PrintRequestAttributeSet; 36 37 import sun.java2d.*; 38 import sun.print.*; 39 40 public class CPrinterJob extends RasterPrinterJob { 41 // NOTE: This uses RasterPrinterJob as a base, but it doesn't use 42 // all of the RasterPrinterJob functions. RasterPrinterJob will 43 // break down printing to pieces that aren't necessary under MacOSX 44 // printing, such as controlling the # of copies and collating. These 45 // are handled by the native printing. RasterPrinterJob is kept for 46 // future compatibility and the state keeping that it handles. 47 48 private static String sShouldNotReachHere = "Should not reach here."; 49 50 private boolean noDefaultPrinter = false; 51 52 private static Font defaultFont; 53 54 // This is the NSPrintInfo for this PrinterJob. Protect multi thread 55 // access to it. It is used by the pageDialog, jobDialog, and printLoop. 56 // This way the state of these items is shared across these calls. 57 // PageFormat data is passed in and set on the fNSPrintInfo on a per call 58 // basis. 59 private long fNSPrintInfo = -1; 60 private Object fNSPrintInfoLock = new Object(); 61 62 static { 63 // AWT has to be initialized for the native code to function correctly. 64 Toolkit.getDefaultToolkit(); 65 } 66 67 /** 68 * Presents a dialog to the user for changing the properties of 69 * the print job. 143 getDefaultPage(newPage); 144 return newPage; 145 } 146 147 protected void setAttributes(PrintRequestAttributeSet attributes) throws PrinterException { 148 super.setAttributes(attributes); 149 150 if (attributes == null) { 151 return; 152 } 153 154 // See if this has an NSPrintInfo in it. 155 NSPrintInfo nsPrintInfo = (NSPrintInfo)attributes.get(NSPrintInfo.class); 156 if (nsPrintInfo != null) { 157 fNSPrintInfo = nsPrintInfo.getValue(); 158 } 159 } 160 161 volatile boolean onEventThread; 162 163 private void completePrintLoop() { 164 Runnable r = new Runnable() { public void run() { 165 synchronized(this) { 166 performingPrinting = false; 167 } 168 }}; 169 170 if (onEventThread) { 171 try { EventQueue.invokeAndWait(r); } catch (Exception e) { e.printStackTrace(); } 172 } else { 173 r.run(); 174 } 175 } 176 177 178 public void print(PrintRequestAttributeSet attributes) throws PrinterException { 179 // NOTE: Some of this code is copied from RasterPrinterJob. 180 181 182 // this code uses javax.print APIs 183 // this will make it print directly to the printer 184 // this will not work if the user clicks on the "Preview" button 185 // However if the printer is a StreamPrintService, its the right path. 186 PrintService psvc = getPrintService(); 187 if (psvc instanceof StreamPrintService) { 206 if (totalPages != Pageable.UNKNOWN_NUMBER_OF_PAGES) { 207 lastPage = mDocument.getNumberOfPages() - 1; 208 } 209 } 210 211 try { 212 synchronized (this) { 213 performingPrinting = true; 214 userCancelled = false; 215 } 216 217 if (EventQueue.isDispatchThread()) { 218 // This is an AWT EventQueue, and this print rendering loop needs to block it. 219 220 onEventThread = true; 221 222 try { 223 // Fire off the print rendering loop on the AppKit thread, and don't have 224 // it wait and block this thread. 225 if (printLoop(false, firstPage, lastPage)) { 226 // Fire off the EventConditional that will what until the condition is met, 227 // but will still process AWTEvent's as they occur. 228 new EventDispatchAccess() { 229 public boolean evaluate() { 230 return performingPrinting; 231 } 232 }.pumpEventsAndWait(); 233 } 234 } catch (Exception e) { 235 e.printStackTrace(); 236 } 237 } else { 238 // Fire off the print rendering loop on the AppKit, and block this thread 239 // until it is done. 240 // But don't actually block... we need to come back here! 241 onEventThread = false; 242 243 try { 244 printLoop(true, firstPage, lastPage); 245 } catch (Exception e) { 246 e.printStackTrace(); 247 } 248 } 249 } finally { 250 synchronized (this) { 251 // NOTE: Native code shouldn't allow exceptions out while 252 // printing. They should cancel the print loop. 253 performingPrinting = false; 254 notify(); 255 } 256 } 257 258 // Normalize the collated, # copies, numPages, first/last pages. Need to 259 // make note of pageRangesAttr. 260 261 // Set up NSPrintInfo with the java settings (PageFormat & Paper). 262 263 // Create an NSView for printing. Have knowsPageRange return YES, and give the correct 264 // range, or MAX? if unknown. Have rectForPage do a peekGraphics check before returning 265 // the rectangle. Have drawRect do the real render of the page. Have printJobTitle do 266 // the right thing. 267 268 // Call NSPrintOperation, it will call NSView.drawRect: for each page. 269 270 // NSView.drawRect: will create a CPrinterGraphics with the current CGContextRef, and then 271 // pass this Graphics onto the Printable with the appropriate PageFormat and index. 272 273 // Need to be able to cancel the NSPrintOperation (using code from RasterPrinterJob, be | 30 import java.awt.geom.Rectangle2D; 31 import java.awt.image.BufferedImage; 32 import java.awt.print.*; 33 34 import javax.print.*; 35 import javax.print.attribute.PrintRequestAttributeSet; 36 37 import sun.java2d.*; 38 import sun.print.*; 39 40 public class CPrinterJob extends RasterPrinterJob { 41 // NOTE: This uses RasterPrinterJob as a base, but it doesn't use 42 // all of the RasterPrinterJob functions. RasterPrinterJob will 43 // break down printing to pieces that aren't necessary under MacOSX 44 // printing, such as controlling the # of copies and collating. These 45 // are handled by the native printing. RasterPrinterJob is kept for 46 // future compatibility and the state keeping that it handles. 47 48 private static String sShouldNotReachHere = "Should not reach here."; 49 50 private final SecondaryLoop printingLoop = Toolkit.getDefaultToolkit() 51 .getSystemEventQueue() 52 .createSecondaryLoop(); 53 54 private boolean noDefaultPrinter = false; 55 56 private static Font defaultFont; 57 58 // This is the NSPrintInfo for this PrinterJob. Protect multi thread 59 // access to it. It is used by the pageDialog, jobDialog, and printLoop. 60 // This way the state of these items is shared across these calls. 61 // PageFormat data is passed in and set on the fNSPrintInfo on a per call 62 // basis. 63 private long fNSPrintInfo = -1; 64 private Object fNSPrintInfoLock = new Object(); 65 66 static { 67 // AWT has to be initialized for the native code to function correctly. 68 Toolkit.getDefaultToolkit(); 69 } 70 71 /** 72 * Presents a dialog to the user for changing the properties of 73 * the print job. 147 getDefaultPage(newPage); 148 return newPage; 149 } 150 151 protected void setAttributes(PrintRequestAttributeSet attributes) throws PrinterException { 152 super.setAttributes(attributes); 153 154 if (attributes == null) { 155 return; 156 } 157 158 // See if this has an NSPrintInfo in it. 159 NSPrintInfo nsPrintInfo = (NSPrintInfo)attributes.get(NSPrintInfo.class); 160 if (nsPrintInfo != null) { 161 fNSPrintInfo = nsPrintInfo.getValue(); 162 } 163 } 164 165 volatile boolean onEventThread; 166 167 @Override 168 public void cancel() { 169 super.cancel(); 170 printingLoop.exit(); 171 } 172 173 @Override 174 protected void cancelDoc() throws PrinterAbortException { 175 super.cancelDoc(); 176 printingLoop.exit(); 177 } 178 179 private void completePrintLoop() { 180 Runnable r = new Runnable() { public void run() { 181 synchronized(this) { 182 performingPrinting = false; 183 } 184 printingLoop.exit(); 185 }}; 186 187 if (onEventThread) { 188 try { EventQueue.invokeAndWait(r); } catch (Exception e) { e.printStackTrace(); } 189 } else { 190 r.run(); 191 } 192 } 193 194 195 public void print(PrintRequestAttributeSet attributes) throws PrinterException { 196 // NOTE: Some of this code is copied from RasterPrinterJob. 197 198 199 // this code uses javax.print APIs 200 // this will make it print directly to the printer 201 // this will not work if the user clicks on the "Preview" button 202 // However if the printer is a StreamPrintService, its the right path. 203 PrintService psvc = getPrintService(); 204 if (psvc instanceof StreamPrintService) { 223 if (totalPages != Pageable.UNKNOWN_NUMBER_OF_PAGES) { 224 lastPage = mDocument.getNumberOfPages() - 1; 225 } 226 } 227 228 try { 229 synchronized (this) { 230 performingPrinting = true; 231 userCancelled = false; 232 } 233 234 if (EventQueue.isDispatchThread()) { 235 // This is an AWT EventQueue, and this print rendering loop needs to block it. 236 237 onEventThread = true; 238 239 try { 240 // Fire off the print rendering loop on the AppKit thread, and don't have 241 // it wait and block this thread. 242 if (printLoop(false, firstPage, lastPage)) { 243 // Start a secondary loop on EDT until printing operation is finished or cancelled 244 printingLoop.enter(); 245 } 246 } catch (Exception e) { 247 e.printStackTrace(); 248 } 249 } else { 250 // Fire off the print rendering loop on the AppKit, and block this thread 251 // until it is done. 252 // But don't actually block... we need to come back here! 253 onEventThread = false; 254 255 try { 256 printLoop(true, firstPage, lastPage); 257 } catch (Exception e) { 258 e.printStackTrace(); 259 } 260 } 261 } finally { 262 synchronized (this) { 263 // NOTE: Native code shouldn't allow exceptions out while 264 // printing. They should cancel the print loop. 265 performingPrinting = false; 266 printingLoop.exit(); 267 notify(); 268 } 269 } 270 271 // Normalize the collated, # copies, numPages, first/last pages. Need to 272 // make note of pageRangesAttr. 273 274 // Set up NSPrintInfo with the java settings (PageFormat & Paper). 275 276 // Create an NSView for printing. Have knowsPageRange return YES, and give the correct 277 // range, or MAX? if unknown. Have rectForPage do a peekGraphics check before returning 278 // the rectangle. Have drawRect do the real render of the page. Have printJobTitle do 279 // the right thing. 280 281 // Call NSPrintOperation, it will call NSView.drawRect: for each page. 282 283 // NSView.drawRect: will create a CPrinterGraphics with the current CGContextRef, and then 284 // pass this Graphics onto the Printable with the appropriate PageFormat and index. 285 286 // Need to be able to cancel the NSPrintOperation (using code from RasterPrinterJob, be |