fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
  SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation)  

Fl_Quartz_Printer.mm

Go to the documentation of this file.
00001 //
00002 // "$Id: Fl_Quartz_Printer.mm 8190 2011-01-05 10:21:45Z manolo $"
00003 //
00004 // Mac OS X-specific printing support (objective-c++) for the Fast Light Tool Kit (FLTK).
00005 //
00006 // Copyright 2010 by Bill Spitzak and others.
00007 //
00008 // This library is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU Library General Public
00010 // License as published by the Free Software Foundation; either
00011 // version 2 of the License, or (at your option) any later version.
00012 //
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 // Library General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU Library General Public
00019 // License along with this library; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021 // USA.
00022 //
00023 // Please report all bugs and problems to:
00024 //
00025 //     http://www.fltk.org/str.php
00026 //
00027 
00028 #ifdef __APPLE__
00029 #include <FL/Fl_Printer.H>
00030 
00031 #include <FL/Fl.H>
00032 #include <FL/fl_ask.H>
00033 #include <FL/fl_draw.H>
00034 #import <Cocoa/Cocoa.h>
00035 
00036 extern void fl_quartz_restore_line_style_();
00037 
00038 Fl_System_Printer::Fl_System_Printer(void)
00039 {
00040   x_offset = 0;
00041   y_offset = 0;
00042   scale_x = scale_y = 1.;
00043   class_name(class_id);
00044   gc = 0;
00045   driver(fl_graphics_driver);
00046 }
00047 
00048 Fl_System_Printer::~Fl_System_Printer(void) {}
00049 
00050 int Fl_System_Printer::start_job (int pagecount, int *frompage, int *topage)
00051 //printing using a Quartz graphics context
00052 //returns 0 iff OK
00053 {
00054   OSStatus status = 0;
00055   Fl_X::q_release_context();
00056 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
00057   if( [NSPrintPanel instancesRespondToSelector:@selector(runModalWithPrintInfo:)] &&
00058      [NSPrintInfo instancesRespondToSelector:@selector(PMPrintSession)] ) {
00059     NSAutoreleasePool *localPool;
00060     localPool = [[NSAutoreleasePool alloc] init]; 
00061     NSPrintInfo *info = [NSPrintInfo sharedPrintInfo];
00062     NSPageLayout *layout = [NSPageLayout pageLayout];
00063     NSInteger retval = [layout runModal];
00064     if(retval == NSOKButton) {
00065       NSPrintPanel *panel = [NSPrintPanel printPanel];
00066       retval = (NSInteger)[panel runModalWithPrintInfo:info];//from 10.5 only
00067     }
00068     if(retval != NSOKButton) {
00069       Fl::first_window()->show();
00070       [localPool release];
00071       return 1;
00072     }
00073     printSession = (PMPrintSession)[info PMPrintSession];
00074     pageFormat = (PMPageFormat)[info PMPageFormat];
00075     printSettings = (PMPrintSettings)[info PMPrintSettings];
00076     UInt32 from32, to32;
00077     PMGetFirstPage(printSettings, &from32); 
00078     if (frompage) *frompage = (int)from32;
00079     PMGetLastPage(printSettings, &to32); 
00080     if (topage) *topage = (int)to32;
00081     if(topage && *topage > pagecount) *topage = pagecount;
00082     status = PMSessionBeginCGDocumentNoDialog(printSession, printSettings, pageFormat);
00083     [localPool release];
00084   }
00085   else {
00086 #endif
00087     
00088 #if !__LP64__
00089     Boolean accepted;
00090     status = PMCreateSession(&printSession);
00091     if (status != noErr) return 1;
00092     status = PMCreatePageFormat(&pageFormat);
00093     status = PMSessionDefaultPageFormat(printSession, pageFormat);
00094     if (status != noErr) return 1;
00095     // get pointer to the PMSessionPageSetupDialog Carbon fucntion
00096     typedef OSStatus (*dialog_f)(PMPrintSession, PMPageFormat, Boolean *);
00097     static dialog_f f = NULL;
00098     if (!f) f = (dialog_f)Fl_X::get_carbon_function("PMSessionPageSetupDialog");
00099     status = (*f)(printSession, pageFormat, &accepted);
00100     if (status != noErr || !accepted) {
00101       Fl::first_window()->show();
00102       return 1;
00103     }
00104     status = PMCreatePrintSettings(&printSettings);
00105     if (status != noErr || printSettings == kPMNoPrintSettings) return 1;
00106     status = PMSessionDefaultPrintSettings (printSession, printSettings);
00107     if (status != noErr) return 1;
00108     PMSetPageRange(printSettings, 1, (UInt32)kPMPrintAllPages);
00109     // get pointer to the PMSessionPrintDialog Carbon fucntion
00110     typedef OSStatus (*dialog_f2)(PMPrintSession, PMPrintSettings, PMPageFormat, Boolean *);
00111     static dialog_f2 f2 = NULL;
00112     if (!f2) f2 = (dialog_f2)Fl_X::get_carbon_function("PMSessionPrintDialog");
00113     status = (*f2)(printSession, printSettings, pageFormat, &accepted);
00114     if (!accepted) status = kPMCancel;
00115     if (status != noErr) {
00116       Fl::first_window()->show();
00117       return 1;
00118     }
00119     UInt32 from32, to32;
00120     PMGetFirstPage(printSettings, &from32); 
00121     if (frompage) *frompage = (int)from32;
00122     PMGetLastPage(printSettings, &to32); 
00123     if (topage) *topage = (int)to32;
00124     if(topage && *topage > pagecount) *topage = pagecount;
00125     CFStringRef mystring[1];
00126     mystring[0] = kPMGraphicsContextCoreGraphics;
00127     CFArrayRef array = CFArrayCreate(NULL, (const void **)mystring, 1, &kCFTypeArrayCallBacks);
00128     status = PMSessionSetDocumentFormatGeneration(printSession, kPMDocumentFormatDefault, array, NULL);
00129     CFRelease(array);
00130     status = PMSessionBeginDocumentNoDialog(printSession, printSettings, pageFormat);
00131 #endif //__LP64__
00132     
00133 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
00134   }
00135 #endif
00136   if (status != noErr) return 1;
00137   y_offset = x_offset = 0;
00138   this->set_current();
00139   return 0;
00140 }
00141 
00142 void Fl_System_Printer::margins(int *left, int *top, int *right, int *bottom)
00143 {
00144   PMPaper paper;
00145   PMGetPageFormatPaper(pageFormat, &paper);
00146   PMOrientation orientation;
00147   PMGetOrientation(pageFormat, &orientation);
00148   PMPaperMargins margins;
00149   PMPaperGetMargins(paper, &margins);
00150   if(orientation == kPMPortrait) {
00151     if (left) *left = (int)(margins.left / scale_x + 0.5);
00152     if (top) *top = (int)(margins.top / scale_y + 0.5);
00153     if (right) *right = (int)(margins.right / scale_x + 0.5);
00154     if (bottom) *bottom = (int)(margins.bottom / scale_y + 0.5);
00155     }
00156   else {
00157     if (left) *left = (int)(margins.top / scale_x + 0.5);
00158     if (top) *top = (int)(margins.left / scale_y + 0.5);
00159     if (right) *right = (int)(margins.bottom / scale_x + 0.5);
00160     if (bottom) *bottom = (int)(margins.right / scale_y + 0.5);
00161   }
00162 }
00163 
00164 int Fl_System_Printer::printable_rect(int *w, int *h)
00165 //returns 0 iff OK
00166 {
00167   OSStatus status;
00168   PMRect pmRect;
00169   int x, y;
00170   
00171   status = PMGetAdjustedPageRect(pageFormat, &pmRect);
00172   if (status != noErr) return 1;
00173   
00174   x = (int)pmRect.left;
00175   y = (int)pmRect.top;
00176   *w = int((int)(pmRect.right - x) / scale_x + 1);
00177   *h = int((int)(pmRect.bottom - y) / scale_y + 1);
00178   return 0;
00179 }
00180 
00181 void Fl_System_Printer::origin(int x, int y)
00182 {
00183   x_offset = x;
00184   y_offset = y;
00185   CGContextRestoreGState(fl_gc);
00186   CGContextRestoreGState(fl_gc);
00187   CGContextSaveGState(fl_gc);
00188   CGContextScaleCTM(fl_gc, scale_x, scale_y);
00189   CGContextTranslateCTM(fl_gc, x, y);
00190   CGContextRotateCTM(fl_gc, angle);
00191   CGContextSaveGState(fl_gc);
00192 }
00193 
00194 void Fl_System_Printer::scale (float s_x, float s_y)
00195 {
00196   scale_x = s_x;
00197   scale_y = s_y;
00198   CGContextRestoreGState(fl_gc);
00199   CGContextRestoreGState(fl_gc);
00200   CGContextSaveGState(fl_gc);
00201   CGContextScaleCTM(fl_gc, scale_x, scale_y);
00202   CGContextRotateCTM(fl_gc, angle);
00203   x_offset = y_offset = 0;
00204   CGContextSaveGState(fl_gc);
00205 }
00206 
00207 void Fl_System_Printer::rotate (float rot_angle)
00208 {
00209   angle = - rot_angle * M_PI / 180.;
00210   CGContextRestoreGState(fl_gc);
00211   CGContextRestoreGState(fl_gc);
00212   CGContextSaveGState(fl_gc);
00213   CGContextScaleCTM(fl_gc, scale_x, scale_y);
00214   CGContextTranslateCTM(fl_gc, x_offset, y_offset);
00215   CGContextRotateCTM(fl_gc, angle);
00216   CGContextSaveGState(fl_gc);
00217 }
00218 
00219 void Fl_System_Printer::translate(int x, int y)
00220 {
00221   CGContextSaveGState(fl_gc);
00222   CGContextTranslateCTM(fl_gc, x, y );
00223   CGContextSaveGState(fl_gc);
00224 }
00225 
00226 void Fl_System_Printer::untranslate(void)
00227 {
00228   CGContextRestoreGState(fl_gc);
00229   CGContextRestoreGState(fl_gc);
00230 }
00231 
00232 int Fl_System_Printer::start_page (void)
00233 {       
00234   OSStatus status = PMSessionBeginPageNoDialog(printSession, pageFormat, NULL);
00235 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
00236   if ( PMSessionGetCGGraphicsContext != NULL ) {
00237     status = PMSessionGetCGGraphicsContext(printSession, &fl_gc);
00238   }
00239   else {
00240 #endif
00241 #if ! __LP64__
00242     status = PMSessionGetGraphicsContext(printSession,NULL,(void **)&fl_gc);
00243 #endif
00244 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
00245   }
00246 #endif
00247   PMRect pmRect;
00248   float win_scale_x, win_scale_y;
00249 
00250   PMPaper paper;
00251   PMGetPageFormatPaper(pageFormat, &paper);
00252   PMPaperMargins margins;
00253   PMPaperGetMargins(paper, &margins);
00254   PMOrientation orientation;
00255   PMGetOrientation(pageFormat, &orientation);
00256   
00257   status = PMGetAdjustedPageRect(pageFormat, &pmRect);
00258   double h = pmRect.bottom - pmRect.top;
00259   x_offset = 0;
00260   y_offset = 0; 
00261   angle = 0;
00262   scale_x = scale_y = 1;
00263   win_scale_x = win_scale_y = 1;
00264   image_list_ = NULL;
00265   if(orientation == kPMPortrait)
00266     CGContextTranslateCTM(fl_gc, margins.left, margins.bottom + h);
00267   else
00268     CGContextTranslateCTM(fl_gc, margins.top, margins.right + h);
00269   CGContextScaleCTM(fl_gc, win_scale_x, - win_scale_y);
00270   fl_quartz_restore_line_style_();
00271   CGContextSetShouldAntialias(fl_gc, false);
00272   CGContextSaveGState(fl_gc);
00273   CGContextSaveGState(fl_gc);
00274   fl_line_style(FL_SOLID);
00275   fl_window = (void *)1; // TODO: something better
00276   fl_clip_region(0);
00277   if( status == noErr) gc = fl_gc;
00278   return status != noErr;
00279 }
00280 
00281 int Fl_System_Printer::end_page (void)
00282 {       
00283   CGContextFlush(fl_gc);
00284   CGContextRestoreGState(fl_gc);
00285   CGContextRestoreGState(fl_gc);
00286   OSStatus status = PMSessionEndPageNoDialog(printSession);
00287   delete_image_list();
00288   gc = NULL;
00289   return status != noErr;
00290 }
00291 
00292 void Fl_System_Printer::end_job (void)
00293 {
00294   OSStatus status;
00295   
00296   status = PMSessionError(printSession);
00297   if (status != noErr) {
00298     fl_alert ("PM Session error %d", (int)status);
00299   }
00300   PMSessionEndDocumentNoDialog(printSession);
00301   Fl_Display_Device::display_device()->set_current();
00302   fl_gc = 0;
00303   Fl::first_window()->show();
00304 }
00305 
00306 #endif // __APPLE__
00307 
00308 //
00309 // End of "$Id: Fl_Quartz_Printer.mm 8190 2011-01-05 10:21:45Z manolo $".
00310 //