summaryrefslogtreecommitdiff
path: root/src/Fl_Quartz_Printer.mm
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2016-03-18 18:20:11 +0000
committerManolo Gouy <Manolo>2016-03-18 18:20:11 +0000
commitfa9a33eaeeddb85a6afedc2d02d0d67f290b0822 (patch)
treeb881473f229f5edccf5fef79c335de8b4faf33d4 /src/Fl_Quartz_Printer.mm
parent3e0e68bb59058eb86af143ed2946197aa7cfca1c (diff)
Beginning of Albrecht's plan for Fl_Window and Fl_Window_Driver classes.
Still unclear whether the implementation of the flush() functions follows the plan. The Fl_Printer class is fully rewritten under the driver model. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11364 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Quartz_Printer.mm')
-rw-r--r--src/Fl_Quartz_Printer.mm159
1 files changed, 142 insertions, 17 deletions
diff --git a/src/Fl_Quartz_Printer.mm b/src/Fl_Quartz_Printer.mm
index 350ab53b7..68e7f44d0 100644
--- a/src/Fl_Quartz_Printer.mm
+++ b/src/Fl_Quartz_Printer.mm
@@ -16,8 +16,9 @@
// http://www.fltk.org/str.php
//
-#ifdef __APPLE__
#include <FL/Fl_Printer.H>
+#include <FL/Fl_Shared_Image.H>
+#include <FL/Fl_Window_Driver.H>
#include "drivers/Quartz/Fl_Quartz_Printer_Graphics_Driver.H"
#include <FL/Fl.H>
@@ -42,7 +43,37 @@ typedef OSStatus
extern void fl_quartz_restore_line_style_(CGContextRef gc);
-Fl_Printer::Helper::Helper(void)
+
+/** Support for printing on the Apple OS X platform */
+class Fl_Cocoa_Printer_Driver : public Fl_Paged_Device {
+ friend class Fl_Paged_Device;
+private:
+ float scale_x;
+ float scale_y;
+ float angle; // rotation angle in radians
+ PMPrintSession printSession;
+ PMPageFormat pageFormat;
+ PMPrintSettings printSettings;
+ Fl_Cocoa_Printer_Driver(void);
+ int start_job(int pagecount, int *frompage = NULL, int *topage = NULL);
+ int start_page (void);
+ int printable_rect(int *w, int *h);
+ void margins(int *left, int *top, int *right, int *bottom);
+ void origin(int *x, int *y);
+ void origin(int x, int y);
+ void scale (float scale_x, float scale_y = 0.);
+ void rotate(float angle);
+ void translate(int x, int y);
+ void untranslate(void);
+ int end_page (void);
+ void end_job (void);
+ void draw_decorated_window(Fl_Window *win, int x_offset, int y_offset);
+ void print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x, int delta_y);
+ ~Fl_Cocoa_Printer_Driver(void);
+};
+
+
+Fl_Cocoa_Printer_Driver::Fl_Cocoa_Printer_Driver(void)
{
x_offset = 0;
y_offset = 0;
@@ -50,11 +81,17 @@ Fl_Printer::Helper::Helper(void)
driver(new Fl_Quartz_Printer_Graphics_Driver);
}
-Fl_Printer::Helper::~Helper(void) {
+Fl_Paged_Device* Fl_Paged_Device::newPrinterDriver(void)
+{
+ return new Fl_Cocoa_Printer_Driver();
+}
+
+Fl_Cocoa_Printer_Driver::~Fl_Cocoa_Printer_Driver(void) {
delete driver();
}
-int Fl_Printer::Helper::start_job (int pagecount, int *frompage, int *topage)
+
+int Fl_Cocoa_Printer_Driver::start_job (int pagecount, int *frompage, int *topage)
//printing using a Quartz graphics context
//returns 0 iff OK
{
@@ -145,7 +182,7 @@ int Fl_Printer::Helper::start_job (int pagecount, int *frompage, int *topage)
return 0;
}
-void Fl_Printer::Helper::margins(int *left, int *top, int *right, int *bottom)
+void Fl_Cocoa_Printer_Driver::margins(int *left, int *top, int *right, int *bottom)
{
PMPaper paper;
PMGetPageFormatPaper(pageFormat, &paper);
@@ -167,7 +204,7 @@ void Fl_Printer::Helper::margins(int *left, int *top, int *right, int *bottom)
}
}
-int Fl_Printer::Helper::printable_rect(int *w, int *h)
+int Fl_Cocoa_Printer_Driver::printable_rect(int *w, int *h)
//returns 0 iff OK
{
OSStatus status;
@@ -184,7 +221,7 @@ int Fl_Printer::Helper::printable_rect(int *w, int *h)
return 0;
}
-void Fl_Printer::Helper::origin(int x, int y)
+void Fl_Cocoa_Printer_Driver::origin(int x, int y)
{
x_offset = x;
y_offset = y;
@@ -198,7 +235,7 @@ void Fl_Printer::Helper::origin(int x, int y)
CGContextSaveGState(gc);
}
-void Fl_Printer::Helper::scale (float s_x, float s_y)
+void Fl_Cocoa_Printer_Driver::scale (float s_x, float s_y)
{
if (s_y == 0.) s_y = s_x;
scale_x = s_x;
@@ -213,7 +250,7 @@ void Fl_Printer::Helper::scale (float s_x, float s_y)
CGContextSaveGState(gc);
}
-void Fl_Printer::Helper::rotate (float rot_angle)
+void Fl_Cocoa_Printer_Driver::rotate (float rot_angle)
{
angle = - rot_angle * M_PI / 180.;
CGContextRef gc = (CGContextRef)driver()->gc();
@@ -226,7 +263,7 @@ void Fl_Printer::Helper::rotate (float rot_angle)
CGContextSaveGState(gc);
}
-void Fl_Printer::Helper::translate(int x, int y)
+void Fl_Cocoa_Printer_Driver::translate(int x, int y)
{
CGContextRef gc = (CGContextRef)driver()->gc();
CGContextSaveGState(gc);
@@ -234,14 +271,14 @@ void Fl_Printer::Helper::translate(int x, int y)
CGContextSaveGState(gc);
}
-void Fl_Printer::Helper::untranslate(void)
+void Fl_Cocoa_Printer_Driver::untranslate(void)
{
CGContextRef gc = (CGContextRef)driver()->gc();
CGContextRestoreGState(gc);
CGContextRestoreGState(gc);
}
-int Fl_Printer::Helper::start_page (void)
+int Fl_Cocoa_Printer_Driver::start_page (void)
{
OSStatus status = PMSessionBeginPageNoDialog(printSession, pageFormat, NULL);
CGContextRef gc;
@@ -259,6 +296,7 @@ int Fl_Printer::Helper::start_page (void)
#endif
}
driver()->gc(gc);
+ set_current();
PMRect pmRect;
float win_scale_x, win_scale_y;
@@ -291,7 +329,7 @@ int Fl_Printer::Helper::start_page (void)
return status != noErr;
}
-int Fl_Printer::Helper::end_page (void)
+int Fl_Cocoa_Printer_Driver::end_page (void)
{
CGContextRef gc = (CGContextRef)driver()->gc();
CGContextFlush(gc);
@@ -302,7 +340,7 @@ int Fl_Printer::Helper::end_page (void)
return status != noErr;
}
-void Fl_Printer::Helper::end_job (void)
+void Fl_Cocoa_Printer_Driver::end_job (void)
{
OSStatus status;
@@ -325,7 +363,7 @@ void Fl_Printer::Helper::end_job (void)
}
// version that prints at high res if using a retina display
-void Fl_Printer::Helper::print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x, int delta_y)
+void Fl_Cocoa_Printer_Driver::print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x, int delta_y)
{
Fl_Surface_Device *current = Fl_Surface_Device::surface();
Fl_Display_Device::display_device()->set_current();
@@ -339,12 +377,99 @@ void Fl_Printer::Helper::print_window_part(Fl_Window *win, int x, int y, int w,
CFRelease(img);
}
-void Fl_Printer::Helper::origin(int *x, int *y)
+void Fl_Cocoa_Printer_Driver::origin(int *x, int *y)
{
Fl_Paged_Device::origin(x, y);
}
-#endif // __APPLE__
+void Fl_Cocoa_Printer_Driver::draw_decorated_window(Fl_Window *win, int x_offset, int y_offset)
+{
+ if (!win->shown() || win->parent() || !win->border() || !win->visible()) {
+ this->print_widget(win, x_offset, y_offset);
+ return;
+ }
+ int bt = win->decorated_h() - win->h();
+ BOOL to_quartz = (this->driver()->has_feature(Fl_Graphics_Driver::NATIVE));
+ CALayer *layer = nil;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+ if (fl_mac_os_version >= 101000) layer = [[[fl_xid(win) standardWindowButton:NSWindowCloseButton] superview] layer];
+#endif
+
+ if (layer) { // if title bar uses a layer
+ if (to_quartz) { // to Quartz printer
+ CGContextRef gc = (CGContextRef)driver()->gc();
+ CGContextSaveGState(gc);
+ CGContextTranslateCTM(gc, x_offset - 0.5, y_offset + bt - 0.5);
+ CGContextScaleCTM(gc, 1, -1);
+ Fl_X::draw_layer_to_context(layer, gc, win->w(), bt);
+ CGContextRestoreGState(gc);
+ }
+ else {
+ CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB ();
+ CGContextRef gc = CGBitmapContextCreate(NULL, 2*win->w(), 2*bt, 8, 0, cspace, kCGImageAlphaPremultipliedLast);
+ CGColorSpaceRelease(cspace);
+ CGContextScaleCTM(gc, 2, 2);
+ Fl_X::draw_layer_to_context(layer, gc, win->w(), bt);
+ Fl_RGB_Image *image = new Fl_RGB_Image((const uchar*)CGBitmapContextGetData(gc), 2*win->w(), 2*bt, 4,
+ CGBitmapContextGetBytesPerRow(gc)); // 10.2
+ int ori_x, ori_y;
+ origin(&ori_x, &ori_y);
+ scale(0.5);
+ origin(2*ori_x, 2*ori_y);
+ image->draw(2*x_offset, 2*y_offset); // draw title bar as double resolution image
+ scale(1);
+ origin(ori_x, ori_y);
+ delete image;
+ CGContextRelease(gc);
+ }
+ this->print_widget(win, x_offset, y_offset + bt);
+ return;
+ }
+ Fl_Display_Device::display_device()->set_current(); // send win to front and make it current
+ const char *title = win->label();
+ win->label(""); // temporarily set a void window title
+ win->show();
+ Fl::check();
+ // capture the window title bar with no title
+ Fl_Shared_Image *top, *left, *bottom, *right;
+ win->driver()->capture_titlebar_and_borders(top, left, bottom, right);
+ win->label(title); // put back the window title
+ this->set_current(); // back to the Fl_Paged_Device
+ top->draw(x_offset, y_offset); // print the title bar
+ top->release();
+ if (title) { // print the window title
+ const int skip = 65; // approx width of the zone of the 3 window control buttons
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+ if (fl_mac_os_version >= 100400 && to_quartz) { // use Cocoa string drawing with exact title bar font
+ // the exact font is LucidaGrande 13 pts (and HelveticaNeueDeskInterface-Regular with 10.10)
+ NSGraphicsContext *current = [NSGraphicsContext currentContext];
+ [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:driver()->gc() flipped:YES]];//10.4
+ NSDictionary *attr = [NSDictionary dictionaryWithObject:[NSFont titleBarFontOfSize:0]
+ forKey:NSFontAttributeName];
+ NSString *title_s = [fl_xid(win) title];
+ NSSize size = [title_s sizeWithAttributes:attr];
+ int x = x_offset + win->w()/2 - size.width/2;
+ if (x < x_offset+skip) x = x_offset+skip;
+ NSRect r = NSMakeRect(x, y_offset+bt/2+4, win->w() - skip, bt);
+ [[NSGraphicsContext currentContext] setShouldAntialias:YES];
+ [title_s drawWithRect:r options:(NSStringDrawingOptions)0 attributes:attr]; // 10.4
+ [[NSGraphicsContext currentContext] setShouldAntialias:NO];
+ [NSGraphicsContext setCurrentContext:current];
+ }
+ else
+#endif
+ {
+ fl_font(FL_HELVETICA, 14);
+ fl_color(FL_BLACK);
+ int x = x_offset + win->w()/2 - fl_width(title)/2;
+ if (x < x_offset+skip) x = x_offset+skip;
+ fl_push_clip(x_offset, y_offset, win->w(), bt);
+ fl_draw(title, x, y_offset+bt/2+4);
+ fl_pop_clip();
+ }
+ }
+ this->print_widget(win, x_offset, y_offset + bt); // print the window inner part
+}
//
// End of "$Id$".