blob: 9aceec205996efa31e8e0ec5e58061a7d036159c [file] [log] [blame]
DRC2ff39b82011-07-28 08:38:59 +00001//
2// "$Id: Fl_Quartz_Printer.mm 8467 2011-02-23 14:36:18Z manolo $"
3//
4// Mac OS X-specific printing support (objective-c++) for the Fast Light Tool Kit (FLTK).
5//
6// Copyright 2010 by Bill Spitzak and others.
7//
8// This library is free software; you can redistribute it and/or
9// modify it under the terms of the GNU Library General Public
10// License as published by the Free Software Foundation; either
11// version 2 of the License, or (at your option) any later version.
12//
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16// Library General Public License for more details.
17//
18// You should have received a copy of the GNU Library General Public
19// License along with this library; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21// USA.
22//
23// Please report all bugs and problems to:
24//
25// http://www.fltk.org/str.php
26//
27
28#ifdef __APPLE__
29#include <FL/Fl_Printer.H>
30
31#include <FL/Fl.H>
32#include <FL/fl_ask.H>
33#include <FL/fl_draw.H>
34#import <Cocoa/Cocoa.h>
35
36extern void fl_quartz_restore_line_style_();
37
38Fl_System_Printer::Fl_System_Printer(void)
39{
40 x_offset = 0;
41 y_offset = 0;
42 scale_x = scale_y = 1.;
43 gc = 0;
44 driver(Fl_Display_Device::display_device()->driver());
45}
46
47Fl_System_Printer::~Fl_System_Printer(void) {}
48
49int Fl_System_Printer::start_job (int pagecount, int *frompage, int *topage)
50//printing using a Quartz graphics context
51//returns 0 iff OK
52{
53 OSStatus status = 0;
54 Fl_X::q_release_context();
55#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
56 if( [NSPrintPanel instancesRespondToSelector:@selector(runModalWithPrintInfo:)] &&
57 [NSPrintInfo instancesRespondToSelector:@selector(PMPrintSession)] ) {
58 NSAutoreleasePool *localPool;
59 localPool = [[NSAutoreleasePool alloc] init];
60 NSPrintInfo *info = [NSPrintInfo sharedPrintInfo];
61 NSPageLayout *layout = [NSPageLayout pageLayout];
62 NSInteger retval = [layout runModal];
63 if(retval == NSOKButton) {
64 NSPrintPanel *panel = [NSPrintPanel printPanel];
65 retval = (NSInteger)[panel runModalWithPrintInfo:info];//from 10.5 only
66 }
67 if(retval != NSOKButton) {
68 Fl::first_window()->show();
69 [localPool release];
70 return 1;
71 }
72 printSession = (PMPrintSession)[info PMPrintSession];
73 pageFormat = (PMPageFormat)[info PMPageFormat];
74 printSettings = (PMPrintSettings)[info PMPrintSettings];
75 UInt32 from32, to32;
76 PMGetFirstPage(printSettings, &from32);
77 if (frompage) *frompage = (int)from32;
78 PMGetLastPage(printSettings, &to32);
79 if (topage) *topage = (int)to32;
80 if(topage && *topage > pagecount) *topage = pagecount;
81 status = PMSessionBeginCGDocumentNoDialog(printSession, printSettings, pageFormat);
82 [localPool release];
83 }
84 else {
85#endif
86
87#if !__LP64__
88 Boolean accepted;
89 status = PMCreateSession(&printSession);
90 if (status != noErr) return 1;
91 status = PMCreatePageFormat(&pageFormat);
92 status = PMSessionDefaultPageFormat(printSession, pageFormat);
93 if (status != noErr) return 1;
94 // get pointer to the PMSessionPageSetupDialog Carbon function
95 typedef OSStatus (*dialog_f)(PMPrintSession, PMPageFormat, Boolean *);
96 static dialog_f f = NULL;
97 if (!f) f = (dialog_f)Fl_X::get_carbon_function("PMSessionPageSetupDialog");
98 status = (*f)(printSession, pageFormat, &accepted);
99 if (status != noErr || !accepted) {
100 Fl::first_window()->show();
101 return 1;
102 }
103 status = PMCreatePrintSettings(&printSettings);
104 if (status != noErr || printSettings == kPMNoPrintSettings) return 1;
105 status = PMSessionDefaultPrintSettings (printSession, printSettings);
106 if (status != noErr) return 1;
107 PMSetPageRange(printSettings, 1, (UInt32)kPMPrintAllPages);
108 // get pointer to the PMSessionPrintDialog Carbon function
109 typedef OSStatus (*dialog_f2)(PMPrintSession, PMPrintSettings, PMPageFormat, Boolean *);
110 static dialog_f2 f2 = NULL;
111 if (!f2) f2 = (dialog_f2)Fl_X::get_carbon_function("PMSessionPrintDialog");
112 status = (*f2)(printSession, printSettings, pageFormat, &accepted);
113 if (!accepted) status = kPMCancel;
114 if (status != noErr) {
115 Fl::first_window()->show();
116 return 1;
117 }
118 UInt32 from32, to32;
119 PMGetFirstPage(printSettings, &from32);
120 if (frompage) *frompage = (int)from32;
121 PMGetLastPage(printSettings, &to32);
122 if (topage) *topage = (int)to32;
123 if(topage && *topage > pagecount) *topage = pagecount;
124 CFStringRef mystring[1];
125 mystring[0] = kPMGraphicsContextCoreGraphics;
126 CFArrayRef array = CFArrayCreate(NULL, (const void **)mystring, 1, &kCFTypeArrayCallBacks);
127 status = PMSessionSetDocumentFormatGeneration(printSession, kPMDocumentFormatDefault, array, NULL);
128 CFRelease(array);
129 status = PMSessionBeginDocumentNoDialog(printSession, printSettings, pageFormat);
130#endif //__LP64__
131
132#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
133 }
134#endif
135 if (status != noErr) return 1;
136 y_offset = x_offset = 0;
137 this->set_current();
138 return 0;
139}
140
141void Fl_System_Printer::margins(int *left, int *top, int *right, int *bottom)
142{
143 PMPaper paper;
144 PMGetPageFormatPaper(pageFormat, &paper);
145 PMOrientation orientation;
146 PMGetOrientation(pageFormat, &orientation);
147 PMPaperMargins margins;
148 PMPaperGetMargins(paper, &margins);
149 if(orientation == kPMPortrait) {
150 if (left) *left = (int)(margins.left / scale_x + 0.5);
151 if (top) *top = (int)(margins.top / scale_y + 0.5);
152 if (right) *right = (int)(margins.right / scale_x + 0.5);
153 if (bottom) *bottom = (int)(margins.bottom / scale_y + 0.5);
154 }
155 else {
156 if (left) *left = (int)(margins.top / scale_x + 0.5);
157 if (top) *top = (int)(margins.left / scale_y + 0.5);
158 if (right) *right = (int)(margins.bottom / scale_x + 0.5);
159 if (bottom) *bottom = (int)(margins.right / scale_y + 0.5);
160 }
161}
162
163int Fl_System_Printer::printable_rect(int *w, int *h)
164//returns 0 iff OK
165{
166 OSStatus status;
167 PMRect pmRect;
168 int x, y;
169
170 status = PMGetAdjustedPageRect(pageFormat, &pmRect);
171 if (status != noErr) return 1;
172
173 x = (int)pmRect.left;
174 y = (int)pmRect.top;
175 *w = int((int)(pmRect.right - x) / scale_x + 1);
176 *h = int((int)(pmRect.bottom - y) / scale_y + 1);
177 return 0;
178}
179
180void Fl_System_Printer::origin(int x, int y)
181{
182 x_offset = x;
183 y_offset = y;
184 CGContextRestoreGState(fl_gc);
185 CGContextRestoreGState(fl_gc);
186 CGContextSaveGState(fl_gc);
187 CGContextScaleCTM(fl_gc, scale_x, scale_y);
188 CGContextTranslateCTM(fl_gc, x, y);
189 CGContextRotateCTM(fl_gc, angle);
190 CGContextSaveGState(fl_gc);
191}
192
193void Fl_System_Printer::scale (float s_x, float s_y)
194{
195 if (s_y == 0.) s_y = s_x;
196 scale_x = s_x;
197 scale_y = s_y;
198 CGContextRestoreGState(fl_gc);
199 CGContextRestoreGState(fl_gc);
200 CGContextSaveGState(fl_gc);
201 CGContextScaleCTM(fl_gc, scale_x, scale_y);
202 CGContextRotateCTM(fl_gc, angle);
203 x_offset = y_offset = 0;
204 CGContextSaveGState(fl_gc);
205}
206
207void Fl_System_Printer::rotate (float rot_angle)
208{
209 angle = - rot_angle * M_PI / 180.;
210 CGContextRestoreGState(fl_gc);
211 CGContextRestoreGState(fl_gc);
212 CGContextSaveGState(fl_gc);
213 CGContextScaleCTM(fl_gc, scale_x, scale_y);
214 CGContextTranslateCTM(fl_gc, x_offset, y_offset);
215 CGContextRotateCTM(fl_gc, angle);
216 CGContextSaveGState(fl_gc);
217}
218
219void Fl_System_Printer::translate(int x, int y)
220{
221 CGContextSaveGState(fl_gc);
222 CGContextTranslateCTM(fl_gc, x, y );
223 CGContextSaveGState(fl_gc);
224}
225
226void Fl_System_Printer::untranslate(void)
227{
228 CGContextRestoreGState(fl_gc);
229 CGContextRestoreGState(fl_gc);
230}
231
232int Fl_System_Printer::start_page (void)
233{
234 OSStatus status = PMSessionBeginPageNoDialog(printSession, pageFormat, NULL);
235#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
236 if ( PMSessionGetCGGraphicsContext != NULL ) {
237 status = PMSessionGetCGGraphicsContext(printSession, &fl_gc);
238 }
239 else {
240#endif
241#if ! __LP64__
242 status = PMSessionGetGraphicsContext(printSession,NULL,(void **)&fl_gc);
243#endif
244#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
245 }
246#endif
247 PMRect pmRect;
248 float win_scale_x, win_scale_y;
249
250 PMPaper paper;
251 PMGetPageFormatPaper(pageFormat, &paper);
252 PMPaperMargins margins;
253 PMPaperGetMargins(paper, &margins);
254 PMOrientation orientation;
255 PMGetOrientation(pageFormat, &orientation);
256
257 status = PMGetAdjustedPageRect(pageFormat, &pmRect);
258 double h = pmRect.bottom - pmRect.top;
259 x_offset = 0;
260 y_offset = 0;
261 angle = 0;
262 scale_x = scale_y = 1;
263 win_scale_x = win_scale_y = 1;
264 if(orientation == kPMPortrait)
265 CGContextTranslateCTM(fl_gc, margins.left, margins.bottom + h);
266 else
267 CGContextTranslateCTM(fl_gc, margins.top, margins.right + h);
268 CGContextScaleCTM(fl_gc, win_scale_x, - win_scale_y);
269 fl_quartz_restore_line_style_();
270 CGContextSetShouldAntialias(fl_gc, false);
271 CGContextSaveGState(fl_gc);
272 CGContextSaveGState(fl_gc);
273 fl_line_style(FL_SOLID);
274 fl_window = (void *)1; // TODO: something better
275 fl_clip_region(0);
276 if( status == noErr) gc = fl_gc;
277 return status != noErr;
278}
279
280int Fl_System_Printer::end_page (void)
281{
282 CGContextFlush(fl_gc);
283 CGContextRestoreGState(fl_gc);
284 CGContextRestoreGState(fl_gc);
285 OSStatus status = PMSessionEndPageNoDialog(printSession);
286 gc = NULL;
287 return status != noErr;
288}
289
290void Fl_System_Printer::end_job (void)
291{
292 OSStatus status;
293
294 status = PMSessionError(printSession);
295 if (status != noErr) {
296 fl_alert ("PM Session error %d", (int)status);
297 }
298 PMSessionEndDocumentNoDialog(printSession);
299 Fl_Display_Device::display_device()->set_current();
300 fl_gc = 0;
301 Fl::first_window()->show();
302}
303
304#endif // __APPLE__
305
306//
307// End of "$Id: Fl_Quartz_Printer.mm 8467 2011-02-23 14:36:18Z manolo $".
308//