From 8273b5435460d065ae5ab43ef602e8826bcda8d9 Mon Sep 17 00:00:00 2001 From: Manolo Gouy Date: Sat, 19 Mar 2016 21:15:34 +0000 Subject: Rename print support files to src/drivers/XXX/Fl_XXX_Printer_Driver.xxx git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11381 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/CMakeLists.txt | 4 +- src/Fl_GDI_Printer.cxx | 327 ---------------- src/Fl_Printer.cxx | 2 +- src/Fl_Quartz_Printer.mm | 477 ------------------------ src/Makefile | 5 +- src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm | 477 ++++++++++++++++++++++++ src/drivers/Posix/Fl_Posix_Printer_Driver.cxx | 141 +++++++ src/drivers/PostScript/Fl_PostScript.cxx | 122 +----- src/drivers/WinAPI/Fl_WinAPI_Printer_Driver.cxx | 327 ++++++++++++++++ 9 files changed, 954 insertions(+), 928 deletions(-) delete mode 100644 src/Fl_GDI_Printer.cxx delete mode 100644 src/Fl_Quartz_Printer.mm create mode 100644 src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm create mode 100644 src/drivers/Posix/Fl_Posix_Printer_Driver.cxx create mode 100644 src/drivers/WinAPI/Fl_WinAPI_Printer_Driver.cxx (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cb32ff56b..6813773bf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -169,6 +169,7 @@ if (USE_X11) set(DRIVER_FILES drivers/Posix/Fl_Posix_System_Driver.cxx + drivers/Posix/Fl_Posix_Printer_Driver.cxx drivers/X11/Fl_X11_Screen_Driver.cxx drivers/X11/Fl_X11_Window_Driver.cxx drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx @@ -264,6 +265,7 @@ else () drivers/WinAPI/Fl_WinAPI_System_Driver.cxx drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx + drivers/WinAPI/Fl_WinAPI_Printer_Driver.cxx drivers/GDI/Fl_GDI_Graphics_Driver.cxx drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx drivers/GDI/Fl_GDI_Graphics_Driver_color.cxx @@ -373,7 +375,7 @@ add_definitions(-DFL_LIBRARY) if(APPLE AND (NOT OPTION_APPLE_X11) AND (NOT OPTION_APPLE_SDL)) set(MMFILES Fl_cocoa.mm - Fl_Quartz_Printer.mm + drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm Fl_Native_File_Chooser_MAC.mm Fl_Sys_Menu_Bar.mm ) diff --git a/src/Fl_GDI_Printer.cxx b/src/Fl_GDI_Printer.cxx deleted file mode 100644 index 5491acfdd..000000000 --- a/src/Fl_GDI_Printer.cxx +++ /dev/null @@ -1,327 +0,0 @@ -// -// "$Id$" -// -// Support for WIN32 printing for the Fast Light Tool Kit (FLTK). -// -// Copyright 2010-2016 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// http://www.fltk.org/COPYING.php -// -// Please report all bugs and problems on the following page: -// -// http://www.fltk.org/str.php -// - -#ifdef WIN32 - -#include "drivers/GDI/Fl_GDI_Graphics_Driver.H" - -#include - - -#include -#include -#include - -extern HWND fl_window; - -/** Support for printing on the MSWindows platform */ -class Fl_WinAPI_Printer_Driver : public Fl_Paged_Device { - friend class Fl_Paged_Device; -private: - int abortPrint; - PRINTDLG pd; - HDC hPr; - int prerr; - int left_margin; - int top_margin; - void absolute_printable_rect(int *x, int *y, int *w, int *h); - Fl_WinAPI_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); - ~Fl_WinAPI_Printer_Driver(void); -}; - -Fl_WinAPI_Printer_Driver::Fl_WinAPI_Printer_Driver(void) : Fl_Paged_Device() { - hPr = NULL; - driver(new Fl_GDI_Printer_Graphics_Driver); -} - -Fl_Paged_Device* Fl_Paged_Device::newPrinterDriver(void) -{ - return new Fl_WinAPI_Printer_Driver(); -} - - -Fl_WinAPI_Printer_Driver::~Fl_WinAPI_Printer_Driver(void) { - if (hPr) end_job(); - delete driver(); -} - -static void WIN_SetupPrinterDeviceContext(HDC prHDC) -{ - if ( !prHDC ) return; - - fl_window = 0; - SetGraphicsMode(prHDC, GM_ADVANCED); // to allow for rotations - SetMapMode(prHDC, MM_ANISOTROPIC); - SetTextAlign(prHDC, TA_BASELINE|TA_LEFT); - SetBkMode(prHDC, TRANSPARENT); - // this matches 720 logical units to the number of device units in 10 inches of paper - // thus the logical unit is the point (= 1/72 inch) - SetWindowExtEx(prHDC, 720, 720, NULL); - SetViewportExtEx(prHDC, 10*GetDeviceCaps(prHDC, LOGPIXELSX), 10*GetDeviceCaps(prHDC, LOGPIXELSY), NULL); -} - - -int Fl_WinAPI_Printer_Driver::start_job (int pagecount, int *frompage, int *topage) -// returns 0 iff OK -{ - if (pagecount == 0) pagecount = 10000; - DWORD commdlgerr; - DOCINFO di; - char docName [256]; - int err = 0; - - abortPrint = FALSE; - memset (&pd, 0, sizeof (PRINTDLG)); - pd.lStructSize = sizeof (PRINTDLG); - pd.hwndOwner = GetForegroundWindow(); - pd.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE | PD_NOSELECTION; - pd.nMinPage = 1; - pd.nMaxPage = pagecount; - BOOL b = PrintDlg (&pd); - if (pd.hwndOwner) { // restore the correct state of mouse buttons and keyboard modifier keys (STR #3221) - WNDPROC windproc = (WNDPROC)GetWindowLongPtrW(pd.hwndOwner, GWLP_WNDPROC); - CallWindowProc(windproc, pd.hwndOwner, WM_ACTIVATEAPP, 1, 0); - } - if (b != 0) { - hPr = pd.hDC; - if (hPr != NULL) { - strcpy (docName, "FLTK"); - memset(&di, 0, sizeof(DOCINFO)); - di.cbSize = sizeof (DOCINFO); - di.lpszDocName = (LPCSTR) docName; - prerr = StartDoc (hPr, &di); - if (prerr < 1) { - abortPrint = TRUE; - //fl_alert ("StartDoc error %d", prerr); - err = 1; - } - } else { - commdlgerr = CommDlgExtendedError (); - fl_alert ("Unable to create print context, error %lu", - (unsigned long) commdlgerr); - err = 1; - } - } else { - err = 1; - } - if(!err) { - if((pd.Flags & PD_PAGENUMS) != 0 ) { - if (frompage) *frompage = pd.nFromPage; - if (topage) *topage = pd.nToPage; - } - else { - if (frompage) *frompage = 1; - if (topage) *topage = pagecount; - } - x_offset = 0; - y_offset = 0; - WIN_SetupPrinterDeviceContext (hPr); - driver()->gc(hPr); - this->set_current(); - } - return err; -} - -void Fl_WinAPI_Printer_Driver::end_job (void) -{ - Fl_Display_Device::display_device()->set_current(); - if (hPr != NULL) { - if (! abortPrint) { - prerr = EndDoc (hPr); - if (prerr < 0) { - fl_alert ("EndDoc error %d", prerr); - } - } - DeleteDC (hPr); - if (pd.hDevMode != NULL) { - GlobalFree (pd.hDevMode); - } - if (pd.hDevNames != NULL) { - GlobalFree (pd.hDevNames); - } - } - hPr = NULL; -} - -void Fl_WinAPI_Printer_Driver::absolute_printable_rect(int *x, int *y, int *w, int *h) -{ - POINT physPageSize; - POINT pixelsPerInch; - XFORM transform; - - if (hPr == NULL) return; - HDC gc = (HDC)driver()->gc(); - GetWorldTransform(gc, &transform); - ModifyWorldTransform(gc, NULL, MWT_IDENTITY); - SetWindowOrgEx(gc, 0, 0, NULL); - - physPageSize.x = GetDeviceCaps(hPr, HORZRES); - physPageSize.y = GetDeviceCaps(hPr, VERTRES); - DPtoLP(hPr, &physPageSize, 1); - *w = physPageSize.x + 1; - *h = physPageSize.y + 1; - pixelsPerInch.x = GetDeviceCaps(hPr, LOGPIXELSX); - pixelsPerInch.y = GetDeviceCaps(hPr, LOGPIXELSY); - DPtoLP(hPr, &pixelsPerInch, 1); - left_margin = (pixelsPerInch.x / 4); - *w -= (pixelsPerInch.x / 2); - top_margin = (pixelsPerInch.y / 4); - *h -= (pixelsPerInch.y / 2); - - *x = left_margin; - *y = top_margin; - origin(x_offset, y_offset); - SetWorldTransform(gc, &transform); -} - -void Fl_WinAPI_Printer_Driver::margins(int *left, int *top, int *right, int *bottom) -{ - int x = 0, y = 0, w = 0, h = 0; - absolute_printable_rect(&x, &y, &w, &h); - if (left) *left = x; - if (top) *top = y; - if (right) *right = x; - if (bottom) *bottom = y; -} - -int Fl_WinAPI_Printer_Driver::printable_rect(int *w, int *h) -{ - int x, y; - absolute_printable_rect(&x, &y, w, h); - return 0; -} - -int Fl_WinAPI_Printer_Driver::start_page (void) -{ - int rsult, w, h; - - rsult = 0; - if (hPr != NULL) { - WIN_SetupPrinterDeviceContext (hPr); - prerr = StartPage (hPr); - if (prerr < 0) { - fl_alert ("StartPage error %d", prerr); - rsult = 1; - } - printable_rect(&w, &h); - origin(0, 0); - fl_clip_region(0); - } - return rsult; -} - -void Fl_WinAPI_Printer_Driver::origin (int deltax, int deltay) -{ - SetWindowOrgEx( (HDC)driver()->gc(), - left_margin - deltax, - top_margin - deltay, NULL); - x_offset = deltax; - y_offset = deltay; -} - -void Fl_WinAPI_Printer_Driver::scale (float scalex, float scaley) -{ - if (scaley == 0.) scaley = scalex; - int w, h; - SetWindowExtEx((HDC)driver()->gc(), (int)(720 / scalex + 0.5), (int)(720 / scaley + 0.5), NULL); - printable_rect(&w, &h); - origin(0, 0); -} - -void Fl_WinAPI_Printer_Driver::rotate (float rot_angle) -{ - XFORM mat; - float angle; - angle = (float) - (rot_angle * M_PI / 180.); - mat.eM11 = cos(angle); - mat.eM12 = sin(angle); - mat.eM21 = - mat.eM12; - mat.eM22 = mat.eM11; - mat.eDx = mat.eDy = 0; - SetWorldTransform((HDC)driver()->gc(), &mat); -} - -int Fl_WinAPI_Printer_Driver::end_page (void) -{ - int rsult; - - rsult = 0; - if (hPr != NULL) { - prerr = EndPage (hPr); - if (prerr < 0) { - abortPrint = TRUE; - fl_alert ("EndPage error %d", prerr); - rsult = 1; - } - } - return rsult; -} - -static int translate_stack_depth = 0; -const int translate_stack_max = 5; -static int translate_stack_x[translate_stack_max]; -static int translate_stack_y[translate_stack_max]; - -static void do_translate(int x, int y, HDC gc) -{ - XFORM tr; - tr.eM11 = tr.eM22 = 1; - tr.eM12 = tr.eM21 = 0; - tr.eDx = (FLOAT) x; - tr.eDy = (FLOAT) y; - ModifyWorldTransform(gc, &tr, MWT_LEFTMULTIPLY); -} - -void Fl_WinAPI_Printer_Driver::translate (int x, int y) -{ - do_translate(x, y, (HDC)driver()->gc()); - if (translate_stack_depth < translate_stack_max) { - translate_stack_x[translate_stack_depth] = x; - translate_stack_y[translate_stack_depth] = y; - translate_stack_depth++; - } -} - -void Fl_WinAPI_Printer_Driver::untranslate (void) -{ - if (translate_stack_depth > 0) { - translate_stack_depth--; - do_translate( - translate_stack_x[translate_stack_depth], - translate_stack_y[translate_stack_depth], (HDC)driver()->gc() ); - } -} - -void Fl_WinAPI_Printer_Driver::origin(int *x, int *y) -{ - Fl_Paged_Device::origin(x, y); -} - -#endif // WIN32 - -// -// End of "$Id$". -// diff --git a/src/Fl_Printer.cxx b/src/Fl_Printer.cxx index e82163e3b..1d824c9e3 100644 --- a/src/Fl_Printer.cxx +++ b/src/Fl_Printer.cxx @@ -68,7 +68,7 @@ const char *Fl_Printer::property_cancel = NULL; #else -#include "Fl_GDI_Printer.cxx" +//#include "Fl_GDI_Printer.cxx" // print dialog customization strings /** [this text may be customized at run-time] */ diff --git a/src/Fl_Quartz_Printer.mm b/src/Fl_Quartz_Printer.mm deleted file mode 100644 index d9817b7ea..000000000 --- a/src/Fl_Quartz_Printer.mm +++ /dev/null @@ -1,477 +0,0 @@ -// -// "$Id$" -// -// Mac OS X-specific printing support (objective-c++) for the Fast Light Tool Kit (FLTK). -// -// Copyright 2010-2016 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// http://www.fltk.org/COPYING.php -// -// Please report all bugs and problems to: -// -// http://www.fltk.org/str.php -// - -#include -#include -#include -#include "drivers/Quartz/Fl_Quartz_Printer_Graphics_Driver.H" - -#include -#include -#include -#import - -typedef OSStatus (*PMSessionSetDocumentFormatGeneration_type)( - PMPrintSession printSession, - CFStringRef docFormat, - CFArrayRef graphicsContextTypes, - CFTypeRef options); -typedef OSStatus (*PMSessionBeginDocumentNoDialog_type)( - PMPrintSession printSession, - PMPrintSettings printSettings, - PMPageFormat pageFormat); -typedef OSStatus -(*PMSessionGetGraphicsContext_type)( - PMPrintSession printSession, - CFStringRef graphicsContextType, - void ** graphicsContext); - -extern void fl_quartz_restore_line_style_(CGContextRef gc); - - -/** 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; - scale_x = scale_y = 1.; - driver(new Fl_Quartz_Printer_Graphics_Driver); -} - -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_Cocoa_Printer_Driver::start_job (int pagecount, int *frompage, int *topage) -//printing using a Quartz graphics context -//returns 0 iff OK -{ - OSStatus status = 0; - fl_open_display(); - Fl_X::q_release_context(); -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - if (fl_mac_os_version >= 100500) { - NSPrintInfo *info = [NSPrintInfo sharedPrintInfo]; - NSPrintPanel *panel = [NSPrintPanel printPanel]; - //from 10.5 - [panel setOptions:NSPrintPanelShowsCopies | NSPrintPanelShowsPageRange | NSPrintPanelShowsPageSetupAccessory]; - NSInteger retval = [panel runModalWithPrintInfo:info];//from 10.5 - if(retval != NSOKButton) { - Fl_Window *w = Fl::first_window(); - if (w) w->show(); - return 1; - } - printSession = (PMPrintSession)[info PMPrintSession];//from 10.5 - pageFormat = (PMPageFormat)[info PMPageFormat];//from 10.5 - printSettings = (PMPrintSettings)[info PMPrintSettings];//from 10.5 - UInt32 from32, to32; - PMGetFirstPage(printSettings, &from32); - if (frompage) *frompage = (int)from32; - PMGetLastPage(printSettings, &to32); - if (topage) { - *topage = (int)to32; - if (*topage > pagecount && pagecount > 0) *topage = pagecount; - } - status = PMSessionBeginCGDocumentNoDialog(printSession, printSettings, pageFormat);//from 10.4 - } - else -#endif - { -#if !__LP64__ - Boolean accepted; - status = PMCreateSession(&printSession); - if (status != noErr) return 1; - status = PMCreatePageFormat(&pageFormat); - status = PMSessionDefaultPageFormat(printSession, pageFormat); - if (status != noErr) return 1; - // get pointer to the PMSessionPageSetupDialog Carbon function - typedef OSStatus (*dialog_f)(PMPrintSession, PMPageFormat, Boolean *); - static dialog_f f = NULL; - if (!f) f = (dialog_f)Fl_X::get_carbon_function("PMSessionPageSetupDialog"); - status = (*f)(printSession, pageFormat, &accepted); - if (status != noErr || !accepted) { - Fl::first_window()->show(); - return 1; - } - status = PMCreatePrintSettings(&printSettings); - if (status != noErr || printSettings == kPMNoPrintSettings) return 1; - status = PMSessionDefaultPrintSettings (printSession, printSettings); - if (status != noErr) return 1; - PMSetPageRange(printSettings, 1, (UInt32)kPMPrintAllPages); - // get pointer to the PMSessionPrintDialog Carbon function - typedef OSStatus (*dialog_f2)(PMPrintSession, PMPrintSettings, PMPageFormat, Boolean *); - static dialog_f2 f2 = NULL; - if (!f2) f2 = (dialog_f2)Fl_X::get_carbon_function("PMSessionPrintDialog"); - status = (*f2)(printSession, printSettings, pageFormat, &accepted); - if (!accepted) status = kPMCancel; - if (status != noErr) { - Fl::first_window()->show(); - return 1; - } - UInt32 from32, to32; - PMGetFirstPage(printSettings, &from32); - if (frompage) *frompage = (int)from32; - PMGetLastPage(printSettings, &to32); - if (topage) *topage = (int)to32; - if(topage && *topage > pagecount) *topage = pagecount; - CFStringRef mystring[1]; - mystring[0] = kPMGraphicsContextCoreGraphics; - CFArrayRef array = CFArrayCreate(NULL, (const void **)mystring, 1, &kCFTypeArrayCallBacks); - PMSessionSetDocumentFormatGeneration_type PMSessionSetDocumentFormatGeneration = - (PMSessionSetDocumentFormatGeneration_type)Fl_X::get_carbon_function("PMSessionSetDocumentFormatGeneration"); - status = PMSessionSetDocumentFormatGeneration(printSession, kPMDocumentFormatDefault, array, NULL); - CFRelease(array); - PMSessionBeginDocumentNoDialog_type PMSessionBeginDocumentNoDialog = - (PMSessionBeginDocumentNoDialog_type)Fl_X::get_carbon_function("PMSessionBeginDocumentNoDialog"); - status = PMSessionBeginDocumentNoDialog(printSession, printSettings, pageFormat); -#endif //__LP64__ - } - - if (status != noErr) return 1; - y_offset = x_offset = 0; - this->set_current(); - return 0; -} - -void Fl_Cocoa_Printer_Driver::margins(int *left, int *top, int *right, int *bottom) -{ - PMPaper paper; - PMGetPageFormatPaper(pageFormat, &paper); - PMOrientation orientation; - PMGetOrientation(pageFormat, &orientation); - PMPaperMargins margins; - PMPaperGetMargins(paper, &margins); - if(orientation == kPMPortrait) { - if (left) *left = (int)(margins.left / scale_x + 0.5); - if (top) *top = (int)(margins.top / scale_y + 0.5); - if (right) *right = (int)(margins.right / scale_x + 0.5); - if (bottom) *bottom = (int)(margins.bottom / scale_y + 0.5); - } - else { - if (left) *left = (int)(margins.top / scale_x + 0.5); - if (top) *top = (int)(margins.left / scale_y + 0.5); - if (right) *right = (int)(margins.bottom / scale_x + 0.5); - if (bottom) *bottom = (int)(margins.right / scale_y + 0.5); - } -} - -int Fl_Cocoa_Printer_Driver::printable_rect(int *w, int *h) -//returns 0 iff OK -{ - OSStatus status; - PMRect pmRect; - int x, y; - - status = PMGetAdjustedPageRect(pageFormat, &pmRect); - if (status != noErr) return 1; - - x = (int)pmRect.left; - y = (int)pmRect.top; - *w = int((int)(pmRect.right - x) / scale_x + 1); - *h = int((int)(pmRect.bottom - y) / scale_y + 1); - return 0; -} - -void Fl_Cocoa_Printer_Driver::origin(int x, int y) -{ - x_offset = x; - y_offset = y; - CGContextRef gc = (CGContextRef)driver()->gc(); - CGContextRestoreGState(gc); - CGContextRestoreGState(gc); - CGContextSaveGState(gc); - CGContextScaleCTM(gc, scale_x, scale_y); - CGContextTranslateCTM(gc, x, y); - CGContextRotateCTM(gc, angle); - CGContextSaveGState(gc); -} - -void Fl_Cocoa_Printer_Driver::scale (float s_x, float s_y) -{ - if (s_y == 0.) s_y = s_x; - scale_x = s_x; - scale_y = s_y; - CGContextRef gc = (CGContextRef)driver()->gc(); - CGContextRestoreGState(gc); - CGContextRestoreGState(gc); - CGContextSaveGState(gc); - CGContextScaleCTM(gc, scale_x, scale_y); - CGContextRotateCTM(gc, angle); - x_offset = y_offset = 0; - CGContextSaveGState(gc); -} - -void Fl_Cocoa_Printer_Driver::rotate (float rot_angle) -{ - angle = - rot_angle * M_PI / 180.; - CGContextRef gc = (CGContextRef)driver()->gc(); - CGContextRestoreGState(gc); - CGContextRestoreGState(gc); - CGContextSaveGState(gc); - CGContextScaleCTM(gc, scale_x, scale_y); - CGContextTranslateCTM(gc, x_offset, y_offset); - CGContextRotateCTM(gc, angle); - CGContextSaveGState(gc); -} - -void Fl_Cocoa_Printer_Driver::translate(int x, int y) -{ - CGContextRef gc = (CGContextRef)driver()->gc(); - CGContextSaveGState(gc); - CGContextTranslateCTM(gc, x, y ); - CGContextSaveGState(gc); -} - -void Fl_Cocoa_Printer_Driver::untranslate(void) -{ - CGContextRef gc = (CGContextRef)driver()->gc(); - CGContextRestoreGState(gc); - CGContextRestoreGState(gc); -} - -int Fl_Cocoa_Printer_Driver::start_page (void) -{ - OSStatus status = PMSessionBeginPageNoDialog(printSession, pageFormat, NULL); - CGContextRef gc; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 - if ( &PMSessionGetCGGraphicsContext != NULL ) { - status = PMSessionGetCGGraphicsContext(printSession, &gc); - } - else -#endif - { -#if ! __LP64_ - PMSessionGetGraphicsContext_type PMSessionGetGraphicsContext = - (PMSessionGetGraphicsContext_type)Fl_X::get_carbon_function("PMSessionGetGraphicsContext"); - status = PMSessionGetGraphicsContext(printSession, NULL, (void **)&gc); -#endif - } - driver()->gc(gc); - set_current(); - PMRect pmRect; - float win_scale_x, win_scale_y; - - PMPaper paper; - PMGetPageFormatPaper(pageFormat, &paper); - PMPaperMargins margins; - PMPaperGetMargins(paper, &margins); - PMOrientation orientation; - PMGetOrientation(pageFormat, &orientation); - - status = PMGetAdjustedPageRect(pageFormat, &pmRect); - double h = pmRect.bottom - pmRect.top; - x_offset = 0; - y_offset = 0; - angle = 0; - scale_x = scale_y = 1; - win_scale_x = win_scale_y = 1; - if(orientation == kPMPortrait) - CGContextTranslateCTM(gc, margins.left, margins.bottom + h); - else - CGContextTranslateCTM(gc, margins.top, margins.right + h); - CGContextScaleCTM(gc, win_scale_x, - win_scale_y); - fl_quartz_restore_line_style_(gc); - CGContextSetShouldAntialias(gc, false); - CGContextSaveGState(gc); - CGContextSaveGState(gc); - fl_line_style(FL_SOLID); - fl_window = (Window)1; // TODO: something better - fl_clip_region(0); - return status != noErr; -} - -int Fl_Cocoa_Printer_Driver::end_page (void) -{ - CGContextRef gc = (CGContextRef)driver()->gc(); - CGContextFlush(gc); - CGContextRestoreGState(gc); - CGContextRestoreGState(gc); - OSStatus status = PMSessionEndPageNoDialog(printSession); - gc = NULL; - return status != noErr; -} - -void Fl_Cocoa_Printer_Driver::end_job (void) -{ - OSStatus status; - - status = PMSessionError(printSession); - if (status != noErr) { - fl_alert ("PM Session error %d", (int)status); - } - PMSessionEndDocumentNoDialog(printSession); -#if !__LP64__ - if (fl_mac_os_version < 100500) { - PMRelease(printSettings); - PMRelease(pageFormat); - PMRelease(printSession); - } -#endif - Fl_Display_Device::display_device()->set_current(); - driver()->gc(0); - Fl_Window *w = Fl::first_window(); - if (w) w->show(); -} - -// version that prints at high res if using a retina display -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(); - Fl_Window *save_front = Fl::first_window(); - win->show(); - Fl::check(); - CGImageRef img = Fl_X::CGImage_from_window_rect(win, x, y, w, h); - if (save_front != win) save_front->show(); - current->set_current(); - ((Fl_Quartz_Graphics_Driver*)driver())->draw_CGImage(img,delta_x, delta_y, w, h, 0,0,w,h); - CFRelease(img); -} - -void Fl_Cocoa_Printer_Driver::origin(int *x, int *y) -{ - Fl_Paged_Device::origin(x, y); -} - -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 - NSString *title = [fl_xid(win) title]; - [title retain]; - [fl_xid(win) setTitle:@""]; // 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); - [fl_xid(win) setTitle: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 (win->label()) { // 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]; - NSSize size = [title 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 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(win->label())/2; - if (x < x_offset+skip) x = x_offset+skip; - fl_push_clip(x_offset, y_offset, win->w(), bt); - fl_draw(win->label(), x, y_offset+bt/2+4); - fl_pop_clip(); - } - } - [title release]; - this->print_widget(win, x_offset, y_offset + bt); // print the window inner part -} - -// -// End of "$Id$". -// diff --git a/src/Makefile b/src/Makefile index f616a8f5a..af93cd432 100644 --- a/src/Makefile +++ b/src/Makefile @@ -165,7 +165,7 @@ CPPFILES = \ OBJCPPFILES = \ Fl_cocoa.mm \ - Fl_Quartz_Printer.mm \ + drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm \ Fl_Native_File_Chooser_MAC.mm \ Fl_Sys_Menu_Bar.mm @@ -252,6 +252,7 @@ XLIBCPPFILES = \ drivers/X11/Fl_X11_Window_Driver.cxx \ drivers/X11/Fl_X11_Screen_Driver.cxx \ drivers/Posix/Fl_Posix_System_Driver.cxx + drivers/Posix/Fl_Posix_Printer_Driver.cxx XLIBFONTFILES = \ drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx @@ -273,7 +274,7 @@ GDICPPFILES = \ drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx \ drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx \ drivers/WinAPI/Fl_WinAPI_System_Driver.cxx \ - Fl_GDI_Printer.cxx + drivers/WinAPI/Fl_WinAPI_Printer_Driver.cxx PSCPPFILES = \ drivers/PostScript/Fl_PostScript.cxx \ diff --git a/src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm b/src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm new file mode 100644 index 000000000..525e545c0 --- /dev/null +++ b/src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm @@ -0,0 +1,477 @@ +// +// "$Id$" +// +// Mac OS X-specific printing support (objective-c++) for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010-2016 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// http://www.fltk.org/COPYING.php +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "../Quartz/Fl_Quartz_Printer_Graphics_Driver.H" + +#include +#include +#include +#import + +typedef OSStatus (*PMSessionSetDocumentFormatGeneration_type)( + PMPrintSession printSession, + CFStringRef docFormat, + CFArrayRef graphicsContextTypes, + CFTypeRef options); +typedef OSStatus (*PMSessionBeginDocumentNoDialog_type)( + PMPrintSession printSession, + PMPrintSettings printSettings, + PMPageFormat pageFormat); +typedef OSStatus +(*PMSessionGetGraphicsContext_type)( + PMPrintSession printSession, + CFStringRef graphicsContextType, + void ** graphicsContext); + +extern void fl_quartz_restore_line_style_(CGContextRef gc); + + +/** 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; + scale_x = scale_y = 1.; + driver(new Fl_Quartz_Printer_Graphics_Driver); +} + +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_Cocoa_Printer_Driver::start_job (int pagecount, int *frompage, int *topage) +//printing using a Quartz graphics context +//returns 0 iff OK +{ + OSStatus status = 0; + fl_open_display(); + Fl_X::q_release_context(); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if (fl_mac_os_version >= 100500) { + NSPrintInfo *info = [NSPrintInfo sharedPrintInfo]; + NSPrintPanel *panel = [NSPrintPanel printPanel]; + //from 10.5 + [panel setOptions:NSPrintPanelShowsCopies | NSPrintPanelShowsPageRange | NSPrintPanelShowsPageSetupAccessory]; + NSInteger retval = [panel runModalWithPrintInfo:info];//from 10.5 + if(retval != NSOKButton) { + Fl_Window *w = Fl::first_window(); + if (w) w->show(); + return 1; + } + printSession = (PMPrintSession)[info PMPrintSession];//from 10.5 + pageFormat = (PMPageFormat)[info PMPageFormat];//from 10.5 + printSettings = (PMPrintSettings)[info PMPrintSettings];//from 10.5 + UInt32 from32, to32; + PMGetFirstPage(printSettings, &from32); + if (frompage) *frompage = (int)from32; + PMGetLastPage(printSettings, &to32); + if (topage) { + *topage = (int)to32; + if (*topage > pagecount && pagecount > 0) *topage = pagecount; + } + status = PMSessionBeginCGDocumentNoDialog(printSession, printSettings, pageFormat);//from 10.4 + } + else +#endif + { +#if !__LP64__ + Boolean accepted; + status = PMCreateSession(&printSession); + if (status != noErr) return 1; + status = PMCreatePageFormat(&pageFormat); + status = PMSessionDefaultPageFormat(printSession, pageFormat); + if (status != noErr) return 1; + // get pointer to the PMSessionPageSetupDialog Carbon function + typedef OSStatus (*dialog_f)(PMPrintSession, PMPageFormat, Boolean *); + static dialog_f f = NULL; + if (!f) f = (dialog_f)Fl_X::get_carbon_function("PMSessionPageSetupDialog"); + status = (*f)(printSession, pageFormat, &accepted); + if (status != noErr || !accepted) { + Fl::first_window()->show(); + return 1; + } + status = PMCreatePrintSettings(&printSettings); + if (status != noErr || printSettings == kPMNoPrintSettings) return 1; + status = PMSessionDefaultPrintSettings (printSession, printSettings); + if (status != noErr) return 1; + PMSetPageRange(printSettings, 1, (UInt32)kPMPrintAllPages); + // get pointer to the PMSessionPrintDialog Carbon function + typedef OSStatus (*dialog_f2)(PMPrintSession, PMPrintSettings, PMPageFormat, Boolean *); + static dialog_f2 f2 = NULL; + if (!f2) f2 = (dialog_f2)Fl_X::get_carbon_function("PMSessionPrintDialog"); + status = (*f2)(printSession, printSettings, pageFormat, &accepted); + if (!accepted) status = kPMCancel; + if (status != noErr) { + Fl::first_window()->show(); + return 1; + } + UInt32 from32, to32; + PMGetFirstPage(printSettings, &from32); + if (frompage) *frompage = (int)from32; + PMGetLastPage(printSettings, &to32); + if (topage) *topage = (int)to32; + if(topage && *topage > pagecount) *topage = pagecount; + CFStringRef mystring[1]; + mystring[0] = kPMGraphicsContextCoreGraphics; + CFArrayRef array = CFArrayCreate(NULL, (const void **)mystring, 1, &kCFTypeArrayCallBacks); + PMSessionSetDocumentFormatGeneration_type PMSessionSetDocumentFormatGeneration = + (PMSessionSetDocumentFormatGeneration_type)Fl_X::get_carbon_function("PMSessionSetDocumentFormatGeneration"); + status = PMSessionSetDocumentFormatGeneration(printSession, kPMDocumentFormatDefault, array, NULL); + CFRelease(array); + PMSessionBeginDocumentNoDialog_type PMSessionBeginDocumentNoDialog = + (PMSessionBeginDocumentNoDialog_type)Fl_X::get_carbon_function("PMSessionBeginDocumentNoDialog"); + status = PMSessionBeginDocumentNoDialog(printSession, printSettings, pageFormat); +#endif //__LP64__ + } + + if (status != noErr) return 1; + y_offset = x_offset = 0; + this->set_current(); + return 0; +} + +void Fl_Cocoa_Printer_Driver::margins(int *left, int *top, int *right, int *bottom) +{ + PMPaper paper; + PMGetPageFormatPaper(pageFormat, &paper); + PMOrientation orientation; + PMGetOrientation(pageFormat, &orientation); + PMPaperMargins margins; + PMPaperGetMargins(paper, &margins); + if(orientation == kPMPortrait) { + if (left) *left = (int)(margins.left / scale_x + 0.5); + if (top) *top = (int)(margins.top / scale_y + 0.5); + if (right) *right = (int)(margins.right / scale_x + 0.5); + if (bottom) *bottom = (int)(margins.bottom / scale_y + 0.5); + } + else { + if (left) *left = (int)(margins.top / scale_x + 0.5); + if (top) *top = (int)(margins.left / scale_y + 0.5); + if (right) *right = (int)(margins.bottom / scale_x + 0.5); + if (bottom) *bottom = (int)(margins.right / scale_y + 0.5); + } +} + +int Fl_Cocoa_Printer_Driver::printable_rect(int *w, int *h) +//returns 0 iff OK +{ + OSStatus status; + PMRect pmRect; + int x, y; + + status = PMGetAdjustedPageRect(pageFormat, &pmRect); + if (status != noErr) return 1; + + x = (int)pmRect.left; + y = (int)pmRect.top; + *w = int((int)(pmRect.right - x) / scale_x + 1); + *h = int((int)(pmRect.bottom - y) / scale_y + 1); + return 0; +} + +void Fl_Cocoa_Printer_Driver::origin(int x, int y) +{ + x_offset = x; + y_offset = y; + CGContextRef gc = (CGContextRef)driver()->gc(); + CGContextRestoreGState(gc); + CGContextRestoreGState(gc); + CGContextSaveGState(gc); + CGContextScaleCTM(gc, scale_x, scale_y); + CGContextTranslateCTM(gc, x, y); + CGContextRotateCTM(gc, angle); + CGContextSaveGState(gc); +} + +void Fl_Cocoa_Printer_Driver::scale (float s_x, float s_y) +{ + if (s_y == 0.) s_y = s_x; + scale_x = s_x; + scale_y = s_y; + CGContextRef gc = (CGContextRef)driver()->gc(); + CGContextRestoreGState(gc); + CGContextRestoreGState(gc); + CGContextSaveGState(gc); + CGContextScaleCTM(gc, scale_x, scale_y); + CGContextRotateCTM(gc, angle); + x_offset = y_offset = 0; + CGContextSaveGState(gc); +} + +void Fl_Cocoa_Printer_Driver::rotate (float rot_angle) +{ + angle = - rot_angle * M_PI / 180.; + CGContextRef gc = (CGContextRef)driver()->gc(); + CGContextRestoreGState(gc); + CGContextRestoreGState(gc); + CGContextSaveGState(gc); + CGContextScaleCTM(gc, scale_x, scale_y); + CGContextTranslateCTM(gc, x_offset, y_offset); + CGContextRotateCTM(gc, angle); + CGContextSaveGState(gc); +} + +void Fl_Cocoa_Printer_Driver::translate(int x, int y) +{ + CGContextRef gc = (CGContextRef)driver()->gc(); + CGContextSaveGState(gc); + CGContextTranslateCTM(gc, x, y ); + CGContextSaveGState(gc); +} + +void Fl_Cocoa_Printer_Driver::untranslate(void) +{ + CGContextRef gc = (CGContextRef)driver()->gc(); + CGContextRestoreGState(gc); + CGContextRestoreGState(gc); +} + +int Fl_Cocoa_Printer_Driver::start_page (void) +{ + OSStatus status = PMSessionBeginPageNoDialog(printSession, pageFormat, NULL); + CGContextRef gc; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + if ( &PMSessionGetCGGraphicsContext != NULL ) { + status = PMSessionGetCGGraphicsContext(printSession, &gc); + } + else +#endif + { +#if ! __LP64_ + PMSessionGetGraphicsContext_type PMSessionGetGraphicsContext = + (PMSessionGetGraphicsContext_type)Fl_X::get_carbon_function("PMSessionGetGraphicsContext"); + status = PMSessionGetGraphicsContext(printSession, NULL, (void **)&gc); +#endif + } + driver()->gc(gc); + set_current(); + PMRect pmRect; + float win_scale_x, win_scale_y; + + PMPaper paper; + PMGetPageFormatPaper(pageFormat, &paper); + PMPaperMargins margins; + PMPaperGetMargins(paper, &margins); + PMOrientation orientation; + PMGetOrientation(pageFormat, &orientation); + + status = PMGetAdjustedPageRect(pageFormat, &pmRect); + double h = pmRect.bottom - pmRect.top; + x_offset = 0; + y_offset = 0; + angle = 0; + scale_x = scale_y = 1; + win_scale_x = win_scale_y = 1; + if(orientation == kPMPortrait) + CGContextTranslateCTM(gc, margins.left, margins.bottom + h); + else + CGContextTranslateCTM(gc, margins.top, margins.right + h); + CGContextScaleCTM(gc, win_scale_x, - win_scale_y); + fl_quartz_restore_line_style_(gc); + CGContextSetShouldAntialias(gc, false); + CGContextSaveGState(gc); + CGContextSaveGState(gc); + fl_line_style(FL_SOLID); + fl_window = (Window)1; // TODO: something better + fl_clip_region(0); + return status != noErr; +} + +int Fl_Cocoa_Printer_Driver::end_page (void) +{ + CGContextRef gc = (CGContextRef)driver()->gc(); + CGContextFlush(gc); + CGContextRestoreGState(gc); + CGContextRestoreGState(gc); + OSStatus status = PMSessionEndPageNoDialog(printSession); + gc = NULL; + return status != noErr; +} + +void Fl_Cocoa_Printer_Driver::end_job (void) +{ + OSStatus status; + + status = PMSessionError(printSession); + if (status != noErr) { + fl_alert ("PM Session error %d", (int)status); + } + PMSessionEndDocumentNoDialog(printSession); +#if !__LP64__ + if (fl_mac_os_version < 100500) { + PMRelease(printSettings); + PMRelease(pageFormat); + PMRelease(printSession); + } +#endif + Fl_Display_Device::display_device()->set_current(); + driver()->gc(0); + Fl_Window *w = Fl::first_window(); + if (w) w->show(); +} + +// version that prints at high res if using a retina display +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(); + Fl_Window *save_front = Fl::first_window(); + win->show(); + Fl::check(); + CGImageRef img = Fl_X::CGImage_from_window_rect(win, x, y, w, h); + if (save_front != win) save_front->show(); + current->set_current(); + ((Fl_Quartz_Graphics_Driver*)driver())->draw_CGImage(img,delta_x, delta_y, w, h, 0,0,w,h); + CFRelease(img); +} + +void Fl_Cocoa_Printer_Driver::origin(int *x, int *y) +{ + Fl_Paged_Device::origin(x, y); +} + +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 + NSString *title = [fl_xid(win) title]; + [title retain]; + [fl_xid(win) setTitle:@""]; // 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); + [fl_xid(win) setTitle: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 (win->label()) { // 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]; + NSSize size = [title 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 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(win->label())/2; + if (x < x_offset+skip) x = x_offset+skip; + fl_push_clip(x_offset, y_offset, win->w(), bt); + fl_draw(win->label(), x, y_offset+bt/2+4); + fl_pop_clip(); + } + } + [title release]; + this->print_widget(win, x_offset, y_offset + bt); // print the window inner part +} + +// +// End of "$Id$". +// diff --git a/src/drivers/Posix/Fl_Posix_Printer_Driver.cxx b/src/drivers/Posix/Fl_Posix_Printer_Driver.cxx new file mode 100644 index 000000000..f06bef7f9 --- /dev/null +++ b/src/drivers/Posix/Fl_Posix_Printer_Driver.cxx @@ -0,0 +1,141 @@ +// +// "$Id: Fl_Posix_Printer_Driver.cxx 11364 2016-03-18 18:20:11Z manolo $" +// +// PostScript priting support for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010-2016 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// http://www.fltk.org/COPYING.php +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +#include "../../src/config_lib.h" + +#if defined(FL_CFG_PRN_PS) + +#include +#include +#include + +#include + +/** Support for printing on the Unix/Linux platform */ +class Fl_Posix_Printer_Driver : public Fl_PostScript_File_Device { + virtual int start_job(int pagecount, int *frompage = NULL, int *topage = NULL); +}; + +Fl_Paged_Device* Fl_Paged_Device::newPrinterDriver(void) +{ + return new Fl_Posix_Printer_Driver(); +} + +/** Starts a print job. */ +int Fl_Posix_Printer_Driver::start_job(int pages, int *firstpage, int *lastpage) { + enum Fl_Paged_Device::Page_Format format; + enum Fl_Paged_Device::Page_Layout layout; + + // first test version for print dialog + if (!print_panel) make_print_panel(); + printing_style style = print_load(); + print_selection->deactivate(); + print_all->setonly(); + print_all->do_callback(); + print_from->value("1"); + { char tmp[10]; snprintf(tmp, sizeof(tmp), "%d", pages); print_to->value(tmp); } + print_panel->show(); // this is modal + while (print_panel->shown()) Fl::wait(); + + if (!print_start) // user clicked cancel + return 1; + + // get options + + switch (print_page_size->value()) { + case 0: + format = Fl_Paged_Device::LETTER; + break; + case 2: + format = Fl_Paged_Device::LEGAL; + break; + case 3: + format = Fl_Paged_Device::EXECUTIVE; + break; + case 4: + format = Fl_Paged_Device::A3; + break; + case 5: + format = Fl_Paged_Device::A5; + break; + case 6: + format = Fl_Paged_Device::B5; + break; + case 7: + format = Fl_Paged_Device::ENVELOPE; + break; + case 8: + format = Fl_Paged_Device::DLE; + break; + default: + format = Fl_Paged_Device::A4; + } + + { // page range choice + int from = 1, to = pages; + if (print_pages->value()) { + sscanf(print_from->value(), "%d", &from); + sscanf(print_to->value(), "%d", &to); + } + if (from < 1) from = 1; + if (to > pages) to = pages; + if (to < from) to = from; + if (firstpage) *firstpage = from; + if (lastpage) *lastpage = to; + if (pages > 0) pages = to - from + 1; + } + + if (print_output_mode[0]->value()) layout = Fl_Paged_Device::PORTRAIT; + else if (print_output_mode[1]->value()) layout = Fl_Paged_Device::LANDSCAPE; + else if (print_output_mode[2]->value()) layout = Fl_Paged_Device::PORTRAIT; + else layout = Fl_Paged_Device::LANDSCAPE; + + int print_pipe = print_choice->value(); // 0 = print to file, >0 = printer (pipe) + + const char *media = print_page_size->text(print_page_size->value()); + const char *printer = (const char *)print_choice->menu()[print_choice->value()].user_data(); + if (!print_pipe) printer = ""; + + if (!print_pipe) // fall back to file printing + return Fl_PostScript_File_Device::start_job (pages, format, layout); + + // Print: pipe the output into the lp command... + + char command[1024]; + if (style == SystemV) snprintf(command, sizeof(command), "lp -s -d %s -n %d -t '%s' -o media=%s", + printer, print_collate_button->value() ? 1 : (int)(print_copies->value() + 0.5), "FLTK", media); + else snprintf(command, sizeof(command), "lpr -h -P%s -#%d -T FLTK ", + printer, print_collate_button->value() ? 1 : (int)(print_copies->value() + 0.5)); + + Fl_PostScript_Graphics_Driver *ps = driver(); + ps->output = popen(command, "w"); + if (!ps->output) { + fl_alert("could not run command: %s\n",command); + return 1; + } + ps->close_command(pclose); + this->set_current(); + return ps->start_postscript(pages, format, layout); // start printing +} + +#endif // defined(FL_CFG_PRN_PS) + + +// +// End of "$Id: Fl_Posix_Printer_Driver.cxx 11364 2016-03-18 18:20:11Z manolo $". +// diff --git a/src/drivers/PostScript/Fl_PostScript.cxx b/src/drivers/PostScript/Fl_PostScript.cxx index b3e7d214d..7de93e48c 100644 --- a/src/drivers/PostScript/Fl_PostScript.cxx +++ b/src/drivers/PostScript/Fl_PostScript.cxx @@ -1,7 +1,7 @@ // // "$Id$" // -// PostScript device support for the Fast Light Tool Kit (FLTK). +// Classes Fl_PostScript_File_Device and Fl_PostScript_Graphics_Driver for the Fast Light Tool Kit (FLTK). // // Copyright 2010-2016 by Bill Spitzak and others. // @@ -16,8 +16,7 @@ // http://www.fltk.org/str.php // -#include -#include +#include #include #include #include @@ -171,10 +170,6 @@ int Fl_PostScript_Graphics_Driver::clocale_printf(const char *format, ...) #ifndef FL_DOXYGEN -#if ! (defined(__APPLE__) || defined(WIN32) ) // PORTME: Fl_Surface_Driver - platform PostScript -# include -#endif - // Prolog string static const char * prolog = @@ -1557,119 +1552,6 @@ void Fl_PostScript_File_Device::end_job (void) #endif // FL_DOXYGEN - -#if defined(FL_CFG_PRN_PS) - -/** Support for printing on the Unix/Linux platform */ -class Fl_Posix_Printer_Driver : public Fl_PostScript_File_Device { - virtual int start_job(int pagecount, int *frompage = NULL, int *topage = NULL); -}; - -Fl_Paged_Device* Fl_Paged_Device::newPrinterDriver(void) -{ - return new Fl_Posix_Printer_Driver(); -} - -/** Starts a print job. */ -int Fl_Posix_Printer_Driver::start_job(int pages, int *firstpage, int *lastpage) { - enum Fl_Paged_Device::Page_Format format; - enum Fl_Paged_Device::Page_Layout layout; - - // first test version for print dialog - if (!print_panel) make_print_panel(); - printing_style style = print_load(); - print_selection->deactivate(); - print_all->setonly(); - print_all->do_callback(); - print_from->value("1"); - { char tmp[10]; snprintf(tmp, sizeof(tmp), "%d", pages); print_to->value(tmp); } - print_panel->show(); // this is modal - while (print_panel->shown()) Fl::wait(); - - if (!print_start) // user clicked cancel - return 1; - - // get options - - switch (print_page_size->value()) { - case 0: - format = Fl_Paged_Device::LETTER; - break; - case 2: - format = Fl_Paged_Device::LEGAL; - break; - case 3: - format = Fl_Paged_Device::EXECUTIVE; - break; - case 4: - format = Fl_Paged_Device::A3; - break; - case 5: - format = Fl_Paged_Device::A5; - break; - case 6: - format = Fl_Paged_Device::B5; - break; - case 7: - format = Fl_Paged_Device::ENVELOPE; - break; - case 8: - format = Fl_Paged_Device::DLE; - break; - default: - format = Fl_Paged_Device::A4; - } - - { // page range choice - int from = 1, to = pages; - if (print_pages->value()) { - sscanf(print_from->value(), "%d", &from); - sscanf(print_to->value(), "%d", &to); - } - if (from < 1) from = 1; - if (to > pages) to = pages; - if (to < from) to = from; - if (firstpage) *firstpage = from; - if (lastpage) *lastpage = to; - if (pages > 0) pages = to - from + 1; - } - - if (print_output_mode[0]->value()) layout = Fl_Paged_Device::PORTRAIT; - else if (print_output_mode[1]->value()) layout = Fl_Paged_Device::LANDSCAPE; - else if (print_output_mode[2]->value()) layout = Fl_Paged_Device::PORTRAIT; - else layout = Fl_Paged_Device::LANDSCAPE; - - int print_pipe = print_choice->value(); // 0 = print to file, >0 = printer (pipe) - - const char *media = print_page_size->text(print_page_size->value()); - const char *printer = (const char *)print_choice->menu()[print_choice->value()].user_data(); - if (!print_pipe) printer = ""; - - if (!print_pipe) // fall back to file printing - return Fl_PostScript_File_Device::start_job (pages, format, layout); - - // Print: pipe the output into the lp command... - - char command[1024]; - if (style == SystemV) snprintf(command, sizeof(command), "lp -s -d %s -n %d -t '%s' -o media=%s", - printer, print_collate_button->value() ? 1 : (int)(print_copies->value() + 0.5), "FLTK", media); - else snprintf(command, sizeof(command), "lpr -h -P%s -#%d -T FLTK ", - printer, print_collate_button->value() ? 1 : (int)(print_copies->value() + 0.5)); - - Fl_PostScript_Graphics_Driver *ps = driver(); - ps->output = popen(command, "w"); - if (!ps->output) { - fl_alert("could not run command: %s\n",command); - return 1; - } - ps->close_command(pclose); - this->set_current(); - return ps->start_postscript(pages, format, layout); // start printing -} - -#endif // defined(FL_CFG_PRN_PS) - - // // End of "$Id$". // diff --git a/src/drivers/WinAPI/Fl_WinAPI_Printer_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Printer_Driver.cxx new file mode 100644 index 000000000..0e4d53f8b --- /dev/null +++ b/src/drivers/WinAPI/Fl_WinAPI_Printer_Driver.cxx @@ -0,0 +1,327 @@ +// +// "$Id$" +// +// Support for WIN32 printing for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010-2016 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// http://www.fltk.org/COPYING.php +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifdef WIN32 + +#include "../GDI/Fl_GDI_Graphics_Driver.H" + +#include + + +#include +#include +#include + +extern HWND fl_window; + +/** Support for printing on the MSWindows platform */ +class Fl_WinAPI_Printer_Driver : public Fl_Paged_Device { + friend class Fl_Paged_Device; +private: + int abortPrint; + PRINTDLG pd; + HDC hPr; + int prerr; + int left_margin; + int top_margin; + void absolute_printable_rect(int *x, int *y, int *w, int *h); + Fl_WinAPI_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); + ~Fl_WinAPI_Printer_Driver(void); +}; + +Fl_WinAPI_Printer_Driver::Fl_WinAPI_Printer_Driver(void) : Fl_Paged_Device() { + hPr = NULL; + driver(new Fl_GDI_Printer_Graphics_Driver); +} + +Fl_Paged_Device* Fl_Paged_Device::newPrinterDriver(void) +{ + return new Fl_WinAPI_Printer_Driver(); +} + + +Fl_WinAPI_Printer_Driver::~Fl_WinAPI_Printer_Driver(void) { + if (hPr) end_job(); + delete driver(); +} + +static void WIN_SetupPrinterDeviceContext(HDC prHDC) +{ + if ( !prHDC ) return; + + fl_window = 0; + SetGraphicsMode(prHDC, GM_ADVANCED); // to allow for rotations + SetMapMode(prHDC, MM_ANISOTROPIC); + SetTextAlign(prHDC, TA_BASELINE|TA_LEFT); + SetBkMode(prHDC, TRANSPARENT); + // this matches 720 logical units to the number of device units in 10 inches of paper + // thus the logical unit is the point (= 1/72 inch) + SetWindowExtEx(prHDC, 720, 720, NULL); + SetViewportExtEx(prHDC, 10*GetDeviceCaps(prHDC, LOGPIXELSX), 10*GetDeviceCaps(prHDC, LOGPIXELSY), NULL); +} + + +int Fl_WinAPI_Printer_Driver::start_job (int pagecount, int *frompage, int *topage) +// returns 0 iff OK +{ + if (pagecount == 0) pagecount = 10000; + DWORD commdlgerr; + DOCINFO di; + char docName [256]; + int err = 0; + + abortPrint = FALSE; + memset (&pd, 0, sizeof (PRINTDLG)); + pd.lStructSize = sizeof (PRINTDLG); + pd.hwndOwner = GetForegroundWindow(); + pd.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE | PD_NOSELECTION; + pd.nMinPage = 1; + pd.nMaxPage = pagecount; + BOOL b = PrintDlg (&pd); + if (pd.hwndOwner) { // restore the correct state of mouse buttons and keyboard modifier keys (STR #3221) + WNDPROC windproc = (WNDPROC)GetWindowLongPtrW(pd.hwndOwner, GWLP_WNDPROC); + CallWindowProc(windproc, pd.hwndOwner, WM_ACTIVATEAPP, 1, 0); + } + if (b != 0) { + hPr = pd.hDC; + if (hPr != NULL) { + strcpy (docName, "FLTK"); + memset(&di, 0, sizeof(DOCINFO)); + di.cbSize = sizeof (DOCINFO); + di.lpszDocName = (LPCSTR) docName; + prerr = StartDoc (hPr, &di); + if (prerr < 1) { + abortPrint = TRUE; + //fl_alert ("StartDoc error %d", prerr); + err = 1; + } + } else { + commdlgerr = CommDlgExtendedError (); + fl_alert ("Unable to create print context, error %lu", + (unsigned long) commdlgerr); + err = 1; + } + } else { + err = 1; + } + if(!err) { + if((pd.Flags & PD_PAGENUMS) != 0 ) { + if (frompage) *frompage = pd.nFromPage; + if (topage) *topage = pd.nToPage; + } + else { + if (frompage) *frompage = 1; + if (topage) *topage = pagecount; + } + x_offset = 0; + y_offset = 0; + WIN_SetupPrinterDeviceContext (hPr); + driver()->gc(hPr); + this->set_current(); + } + return err; +} + +void Fl_WinAPI_Printer_Driver::end_job (void) +{ + Fl_Display_Device::display_device()->set_current(); + if (hPr != NULL) { + if (! abortPrint) { + prerr = EndDoc (hPr); + if (prerr < 0) { + fl_alert ("EndDoc error %d", prerr); + } + } + DeleteDC (hPr); + if (pd.hDevMode != NULL) { + GlobalFree (pd.hDevMode); + } + if (pd.hDevNames != NULL) { + GlobalFree (pd.hDevNames); + } + } + hPr = NULL; +} + +void Fl_WinAPI_Printer_Driver::absolute_printable_rect(int *x, int *y, int *w, int *h) +{ + POINT physPageSize; + POINT pixelsPerInch; + XFORM transform; + + if (hPr == NULL) return; + HDC gc = (HDC)driver()->gc(); + GetWorldTransform(gc, &transform); + ModifyWorldTransform(gc, NULL, MWT_IDENTITY); + SetWindowOrgEx(gc, 0, 0, NULL); + + physPageSize.x = GetDeviceCaps(hPr, HORZRES); + physPageSize.y = GetDeviceCaps(hPr, VERTRES); + DPtoLP(hPr, &physPageSize, 1); + *w = physPageSize.x + 1; + *h = physPageSize.y + 1; + pixelsPerInch.x = GetDeviceCaps(hPr, LOGPIXELSX); + pixelsPerInch.y = GetDeviceCaps(hPr, LOGPIXELSY); + DPtoLP(hPr, &pixelsPerInch, 1); + left_margin = (pixelsPerInch.x / 4); + *w -= (pixelsPerInch.x / 2); + top_margin = (pixelsPerInch.y / 4); + *h -= (pixelsPerInch.y / 2); + + *x = left_margin; + *y = top_margin; + origin(x_offset, y_offset); + SetWorldTransform(gc, &transform); +} + +void Fl_WinAPI_Printer_Driver::margins(int *left, int *top, int *right, int *bottom) +{ + int x = 0, y = 0, w = 0, h = 0; + absolute_printable_rect(&x, &y, &w, &h); + if (left) *left = x; + if (top) *top = y; + if (right) *right = x; + if (bottom) *bottom = y; +} + +int Fl_WinAPI_Printer_Driver::printable_rect(int *w, int *h) +{ + int x, y; + absolute_printable_rect(&x, &y, w, h); + return 0; +} + +int Fl_WinAPI_Printer_Driver::start_page (void) +{ + int rsult, w, h; + + rsult = 0; + if (hPr != NULL) { + WIN_SetupPrinterDeviceContext (hPr); + prerr = StartPage (hPr); + if (prerr < 0) { + fl_alert ("StartPage error %d", prerr); + rsult = 1; + } + printable_rect(&w, &h); + origin(0, 0); + fl_clip_region(0); + } + return rsult; +} + +void Fl_WinAPI_Printer_Driver::origin (int deltax, int deltay) +{ + SetWindowOrgEx( (HDC)driver()->gc(), - left_margin - deltax, - top_margin - deltay, NULL); + x_offset = deltax; + y_offset = deltay; +} + +void Fl_WinAPI_Printer_Driver::scale (float scalex, float scaley) +{ + if (scaley == 0.) scaley = scalex; + int w, h; + SetWindowExtEx((HDC)driver()->gc(), (int)(720 / scalex + 0.5), (int)(720 / scaley + 0.5), NULL); + printable_rect(&w, &h); + origin(0, 0); +} + +void Fl_WinAPI_Printer_Driver::rotate (float rot_angle) +{ + XFORM mat; + float angle; + angle = (float) - (rot_angle * M_PI / 180.); + mat.eM11 = cos(angle); + mat.eM12 = sin(angle); + mat.eM21 = - mat.eM12; + mat.eM22 = mat.eM11; + mat.eDx = mat.eDy = 0; + SetWorldTransform((HDC)driver()->gc(), &mat); +} + +int Fl_WinAPI_Printer_Driver::end_page (void) +{ + int rsult; + + rsult = 0; + if (hPr != NULL) { + prerr = EndPage (hPr); + if (prerr < 0) { + abortPrint = TRUE; + fl_alert ("EndPage error %d", prerr); + rsult = 1; + } + } + return rsult; +} + +static int translate_stack_depth = 0; +const int translate_stack_max = 5; +static int translate_stack_x[translate_stack_max]; +static int translate_stack_y[translate_stack_max]; + +static void do_translate(int x, int y, HDC gc) +{ + XFORM tr; + tr.eM11 = tr.eM22 = 1; + tr.eM12 = tr.eM21 = 0; + tr.eDx = (FLOAT) x; + tr.eDy = (FLOAT) y; + ModifyWorldTransform(gc, &tr, MWT_LEFTMULTIPLY); +} + +void Fl_WinAPI_Printer_Driver::translate (int x, int y) +{ + do_translate(x, y, (HDC)driver()->gc()); + if (translate_stack_depth < translate_stack_max) { + translate_stack_x[translate_stack_depth] = x; + translate_stack_y[translate_stack_depth] = y; + translate_stack_depth++; + } +} + +void Fl_WinAPI_Printer_Driver::untranslate (void) +{ + if (translate_stack_depth > 0) { + translate_stack_depth--; + do_translate( - translate_stack_x[translate_stack_depth], - translate_stack_y[translate_stack_depth], (HDC)driver()->gc() ); + } +} + +void Fl_WinAPI_Printer_Driver::origin(int *x, int *y) +{ + Fl_Paged_Device::origin(x, y); +} + +#endif // WIN32 + +// +// End of "$Id$". +// -- cgit v1.2.3