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
This commit is contained in:
Manolo Gouy 2016-03-18 18:20:11 +00:00
parent 3e0e68bb59
commit fa9a33eaee
22 changed files with 256 additions and 355 deletions

View File

@ -36,6 +36,11 @@
or Fl_PostScript_File_Device instead.
*/
class FL_EXPORT Fl_Paged_Device : public Fl_Widget_Surface {
protected:
/** \brief The constructor */
Fl_Paged_Device() : Fl_Widget_Surface(NULL) {};
/** A platform should implement this function to support printing via the Fl_Printer class. */
static Fl_Paged_Device* newPrinterDriver(void);
public:
/**
\brief Possible page formats.
@ -98,10 +103,6 @@ public:
/** \brief width, height and name of all elements of the enum \ref Page_Format.
*/
static const page_format page_formats[NO_PAGE_FORMATS];
protected:
/** \brief The constructor */
Fl_Paged_Device() : Fl_Widget_Surface(NULL) {};
public:
/** \brief The destructor */
virtual ~Fl_Paged_Device() {};
virtual int start_job(int pagecount, int *frompage = NULL, int *topage = NULL);
@ -109,14 +110,9 @@ public:
virtual void margins(int *left, int *top, int *right, int *bottom);
virtual void scale(float scale_x, float scale_y = 0.);
virtual void rotate(float angle);
virtual void print_widget(Fl_Widget* widget, int delta_x = 0, int delta_y = 0) {draw(widget, delta_x, delta_y);}
/** Prints a window with its title bar and frame if any.
\p x_offset and \p y_offset are optional coordinates of where to position the window top left.
Equivalent to print_widget() if \p win is a subwindow or has no border.
Use Fl_Window::decorated_w() and Fl_Window::decorated_h() to get the size of the
printed window.
*/
/** Synonym of draw(Fl_Widget*, int, int) */
void print_widget(Fl_Widget* widget, int delta_x = 0, int delta_y = 0) {draw(widget, delta_x, delta_y);}
/** Synonym of draw_decorated_window(Fl_Window*, int, int) */
void print_window(Fl_Window *win, int x_offset = 0, int y_offset = 0) {
draw_decorated_window(win, x_offset, y_offset);
}

View File

@ -17,29 +17,13 @@
//
/** \file Fl_Printer.H
\brief declaration of classes Fl_Printer, Fl_System_Printer and Fl_PostScript_Printer.
\brief declaration of class Fl_Printer.
*/
#ifndef Fl_Printer_H
#define Fl_Printer_H
#include <FL/x.H>
#include <FL/Fl_Paged_Device.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Pixmap.H>
#include <FL/Fl_RGB_Image.H>
#include <FL/Fl_Bitmap.H>
#include <stdio.h>
#ifdef WIN32
#include <commdlg.h>
#elif defined(__APPLE__) // PORTME: Fl_Surface_Driver ? - platform printer driver
// not needed
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: include files needed for printing support"
#else // X11
#include <FL/Fl_PostScript.H>
#endif
/**
* \brief OS-independent print support.
@ -94,18 +78,17 @@
before creation of the Fl_Printer object.
Use Fl_PostScript_File_Device::file_chooser_title to customize the title of the file chooser dialog that opens
when using the "Print To File" option of the print dialog.
<li>MSWindows platform: Transparent Fl_RGB_Image 's don't print with exact transparency on most printers.
<li>MSWindows platform: Transparent Fl_RGB_Image 's don't print with exact transparency on most printers
(a workaround is to use print_window_part() ).
Fl_RGB_Image 's don't rotate() well.
A workaround is to use the print_window_part() call.
<li>Mac OS X platform: all graphics requests print as on display.
<li>Mac OS X platform: all graphics requests print as on display and accept rotation and scaling.
</ul>
*/
class FL_EXPORT Fl_Printer : public Fl_Paged_Device {
private:
class Helper;
Helper *printer;
Fl_Paged_Device *printer;
public:
/** \brief The constructor */
/** The constructor */
Fl_Printer(void);
int start_job(int pagecount, int *frompage = NULL, int *topage = NULL);
int start_page(void);
@ -124,7 +107,7 @@ public:
void draw_decorated_window(Fl_Window *win, int x_offset, int y_offset);
void set_current(void);
/** \name These attributes are effective under the Xlib platform only.
/** \name These attributes are useful for the Linux/Unix platform only.
\{
*/
static const char *dialog_title;
@ -147,89 +130,10 @@ public:
static const char *property_save;
static const char *property_cancel;
/** \} */
/** \brief The destructor */
/** The destructor */
~Fl_Printer(void);
};
#if defined(__APPLE__)
class Fl_Printer::Helper : public Fl_Paged_Device {
friend class Fl_Printer;
private:
float scale_x;
float scale_y;
float angle; // rotation angle in radians
PMPrintSession printSession;
PMPageFormat pageFormat;
PMPrintSettings printSettings;
protected:
Helper(void);
public:
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);
~Helper(void);
};
#elif defined(WIN32)
class Fl_Printer::Helper : public Fl_Paged_Device {
friend class Fl_Printer;
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);
protected:
Helper(void);
public:
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);
~Helper(void);
};
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: define your own Fl_Printer::Helper class"
class Fl_Printer::Helper : public Fl_Paged_Device {
friend class Fl_Printer;
protected:
Helper(void) { }
};
#else
class Fl_Printer::Helper : public Fl_PostScript_File_Device {
friend class Fl_Printer;
public:
int start_job(int pagecount, int *frompage = NULL, int *topage = NULL);
};
#endif
#endif // Fl_Printer_H
//

View File

@ -69,7 +69,6 @@ public:
virtual Fl_X *makeWindow() { /* FIXME: move Fl_X::make(Fl_Window*) here for OSX, MSWin, and X11 */ return 0; }
virtual void wait_for_expose() {} // TODO: check
virtual void destroy_double_buffer(); // TODO: check
virtual void draw(); // TODO: check
// --- window shape stuff
void shape_pixmap_(Fl_Image* pixmap); // TODO: check

View File

@ -91,10 +91,12 @@ typedef unsigned int NSUInteger;
@class NSCursor;
@class NSOpenGLPixelFormat;
@class NSOpenGLContext;
@class CALayer;
#else
class NSCursor;
class NSOpenGLPixelFormat;
class NSOpenGLContext;
class CALayer;
#endif // __OBJC__
typedef CGContextRef Fl_Offscreen;
@ -198,6 +200,7 @@ public:
static int calc_mac_os_version(void); // computes the fl_mac_os_version global variable
static void clip_to_rounded_corners(CGContextRef gc, int w, int h);
static void complete_copy_pdf_and_tiff(CGContextRef gc, CFMutableDataRef pdfdata);
static void draw_layer_to_context(CALayer *layer, CGContextRef gc, int w, int h);
private:
CGRect* subRect_; // makes sure subwindow remains inside its parent window
// stores 3 binary flags: whether window is mapped to retina display; whether resolution just changed;

View File

@ -281,6 +281,7 @@ else ()
drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx
drivers/GDI/Fl_GDI_Copy_Surface.cxx
drivers/GDI/Fl_GDI_Image_Surface.cxx
Fl_GDI_Printer.cxx
)
set(DRIVER_HEADER_FILES
drivers/WinAPI/Fl_WinAPI_System_Driver.H

View File

@ -28,12 +28,45 @@
extern HWND fl_window;
Fl_Printer::Helper::Helper(void) : Fl_Paged_Device() {
/** 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_Printer::Helper::~Helper(void) {
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();
}
@ -54,7 +87,7 @@ static void WIN_SetupPrinterDeviceContext(HDC prHDC)
}
int Fl_Printer::Helper::start_job (int pagecount, int *frompage, int *topage)
int Fl_WinAPI_Printer_Driver::start_job (int pagecount, int *frompage, int *topage)
// returns 0 iff OK
{
if (pagecount == 0) pagecount = 10000;
@ -115,7 +148,7 @@ int Fl_Printer::Helper::start_job (int pagecount, int *frompage, int *topage)
return err;
}
void Fl_Printer::Helper::end_job (void)
void Fl_WinAPI_Printer_Driver::end_job (void)
{
Fl_Display_Device::display_device()->set_current();
if (hPr != NULL) {
@ -136,7 +169,7 @@ void Fl_Printer::Helper::end_job (void)
hPr = NULL;
}
void Fl_Printer::Helper::absolute_printable_rect(int *x, int *y, int *w, int *h)
void Fl_WinAPI_Printer_Driver::absolute_printable_rect(int *x, int *y, int *w, int *h)
{
POINT physPageSize;
POINT pixelsPerInch;
@ -167,7 +200,7 @@ void Fl_Printer::Helper::absolute_printable_rect(int *x, int *y, int *w, int *h)
SetWorldTransform(gc, &transform);
}
void Fl_Printer::Helper::margins(int *left, int *top, int *right, int *bottom)
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);
@ -177,14 +210,14 @@ void Fl_Printer::Helper::margins(int *left, int *top, int *right, int *bottom)
if (bottom) *bottom = y;
}
int Fl_Printer::Helper::printable_rect(int *w, int *h)
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_Printer::Helper::start_page (void)
int Fl_WinAPI_Printer_Driver::start_page (void)
{
int rsult, w, h;
@ -203,14 +236,14 @@ int Fl_Printer::Helper::start_page (void)
return rsult;
}
void Fl_Printer::Helper::origin (int deltax, int deltay)
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_Printer::Helper::scale (float scalex, float scaley)
void Fl_WinAPI_Printer_Driver::scale (float scalex, float scaley)
{
if (scaley == 0.) scaley = scalex;
int w, h;
@ -219,7 +252,7 @@ void Fl_Printer::Helper::scale (float scalex, float scaley)
origin(0, 0);
}
void Fl_Printer::Helper::rotate (float rot_angle)
void Fl_WinAPI_Printer_Driver::rotate (float rot_angle)
{
XFORM mat;
float angle;
@ -232,7 +265,7 @@ void Fl_Printer::Helper::rotate (float rot_angle)
SetWorldTransform((HDC)driver()->gc(), &mat);
}
int Fl_Printer::Helper::end_page (void)
int Fl_WinAPI_Printer_Driver::end_page (void)
{
int rsult;
@ -263,7 +296,7 @@ static void do_translate(int x, int y, HDC gc)
ModifyWorldTransform(gc, &tr, MWT_LEFTMULTIPLY);
}
void Fl_Printer::Helper::translate (int x, int y)
void Fl_WinAPI_Printer_Driver::translate (int x, int y)
{
do_translate(x, y, (HDC)driver()->gc());
if (translate_stack_depth < translate_stack_max) {
@ -273,7 +306,7 @@ void Fl_Printer::Helper::translate (int x, int y)
}
}
void Fl_Printer::Helper::untranslate (void)
void Fl_WinAPI_Printer_Driver::untranslate (void)
{
if (translate_stack_depth > 0) {
translate_stack_depth--;
@ -281,7 +314,7 @@ void Fl_Printer::Helper::untranslate (void)
}
}
void Fl_Printer::Helper::origin(int *x, int *y)
void Fl_WinAPI_Printer_Driver::origin(int *x, int *y)
{
Fl_Paged_Device::origin(x, y);
}

View File

@ -18,8 +18,13 @@
//
#include <FL/Fl_Printer.H>
#include "config.h"
#ifdef NO_PRINT_SUPPORT
#ifdef FL_PORTING
# pragma message "FL_PORTING: implement print support for your platform, or define NO_PRINT_SUPPORT"
#endif
#if defined(NO_PRINT_SUPPORT)
Fl_Printer::Fl_Printer(void) {
printer = NULL;
@ -107,8 +112,8 @@ const char *Fl_Printer::property_cancel = "Cancel";
Fl_Printer::Fl_Printer(void) {
printer = new Helper();
Fl_Surface_Device::driver(printer->driver());
printer = Fl_Paged_Device::newPrinterDriver();
driver(printer->driver());
}
/**
@ -209,7 +214,7 @@ Fl_Printer::~Fl_Printer(void)
delete printer;
}
#endif // NO_PRINT_SUPPORT
#endif // defined(NO_PRINT_SUPPORT)
//
// End of "$Id$".

View File

@ -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$".

View File

@ -471,6 +471,9 @@ void Fl_Window::draw()
draw_children();
pWindowDriver->draw_end();
# if defined(FLTK_USE_CAIRO)
Fl::cairo_make_current(this); // checkout if an update is necessary
# endif
}

View File

@ -89,37 +89,6 @@ void Fl_Window_Driver::destroy_double_buffer() {
i->other_xid = 0;
}
void Fl_Window_Driver::draw() {
// The following is similar to Fl_Group::draw(), but ...
//
// - draws the box at (0,0), i.e. with x=0 and y=0 instead of x() and y()
// - does NOT draw the label (text)
// - draws the image only if FL_ALIGN_INSIDE is set
//
// Note: The label (text) of top level windows is drawn in the title bar.
// Other windows do not draw their labels at all, unless drawn by their
// parent widgets or by special draw() methods (derived classes).
if (pWindow->damage() & ~FL_DAMAGE_CHILD) { // draw the entire thing
pWindow->draw_box(pWindow->box(),0,0,pWindow->w(),pWindow->h(),pWindow->color()); // draw box with x/y = 0
if (pWindow->image() && (pWindow->align() & FL_ALIGN_INSIDE)) { // draw the image only
Fl_Label l1;
memset(&l1,0,sizeof(l1));
l1.align_ = pWindow->align();
l1.image = pWindow->image();
if (!pWindow->active_r() && l1.image && l1.deimage) l1.image = l1.deimage;
l1.type = pWindow->labeltype();
l1.draw(0,0,pWindow->w(),pWindow->h(),pWindow->align());
}
}
pWindow->draw_children();
# if defined(FLTK_USE_CAIRO)
Fl::cairo_make_current(this); // checkout if an update is necessary
# endif
}
/** Assigns a non-rectangular shape to the window.
This function gives an arbitrary shape (not just a rectangular region) to an Fl_Window.

View File

@ -41,6 +41,7 @@ extern "C" {
#include <FL/Fl_Tooltip.H>
#include <FL/Fl_Printer.H>
#include <FL/Fl_Shared_Image.H>
#include <FL/fl_draw.H>
#include "drivers/Quartz/Fl_Quartz_Graphics_Driver.H"
#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.H"
#include "drivers/Cocoa/Fl_Cocoa_Window_Driver.H"
@ -84,7 +85,7 @@ static unsigned make_current_counts = 0; // if > 0, then Fl_Window::make_current
static NSBitmapImageRep* rect_to_NSBitmapImageRep(Fl_Window *win, int x, int y, int w, int h);
// make this available on all platforms to make code maintainability easier
extern class Fl_Widget *fl_selection_requestor;
/*extern*/ class Fl_Widget *fl_selection_requestor;
int fl_mac_os_version = Fl_X::calc_mac_os_version(); // the version number of the running Mac OS X (e.g., 100604 for 10.6.4)
@ -4330,7 +4331,7 @@ static CALayer *get_titlebar_layer(Fl_Window *win)
}
static void draw_layer_to_context(CALayer *layer, CGContextRef gc, int w, int h)
void Fl_X::draw_layer_to_context(CALayer *layer, CGContextRef gc, int w, int h)
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
CGContextSaveGState(gc);
@ -4358,7 +4359,7 @@ void Fl_Cocoa_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image*& top,
CGColorSpaceRelease(cspace);
CGContextScaleCTM(auxgc, 2, 2);
if (layer) {
draw_layer_to_context(layer, auxgc, pWindow->w(), htop);
Fl_X::draw_layer_to_context(layer, auxgc, pWindow->w(), htop);
} else {
CGImageRef img = Fl_X::CGImage_from_window_rect(pWindow, 0, -htop, pWindow->w(), htop);
CGContextSaveGState(auxgc);
@ -4375,92 +4376,6 @@ void Fl_Cocoa_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image*& top,
}
void Fl_Printer::Helper::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 bx, by, bt;
get_window_frame_sizes(bx, by, bt);
BOOL to_quartz = (this->driver()->has_feature(Fl_Graphics_Driver::NATIVE));
CALayer *layer = get_titlebar_layer(win);
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);
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);
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
}
/* Returns the address of a Carbon function after dynamically loading the Carbon library if needed.
Supports old Mac OS X versions that may use a couple of Carbon calls:
GetKeys used by OS X 10.3 or before (in Fl::get_key())

View File

@ -86,7 +86,7 @@
*/
// make this available on all platforms to make code maintainability easier
extern class Fl_Widget *fl_selection_requestor;
class Fl_Widget *fl_selection_requestor;
// Internal functions
static void fl_clipboard_notify_target(HWND wnd);

View File

@ -272,7 +272,8 @@ GDICPPFILES = \
drivers/GDI/Fl_GDI_Image_Surface.cxx \
drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx \
drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx \
drivers/WinAPI/Fl_WinAPI_System_Driver.cxx
drivers/WinAPI/Fl_WinAPI_System_Driver.cxx \
Fl_GDI_Printer.cxx
PSCPPFILES = \
drivers/PostScript/Fl_PostScript.cxx \

View File

@ -45,9 +45,9 @@
#elif defined(WIN32)
# define FL_CFG_WIN_WIN32
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: please choose a graphics driver library"
# pragma message "FL_PORTING: please choose a printer driver"
#else // X11
# define FL_CFG_GFX_PS
# define FL_CFG_PRN_PS
#endif
#endif

View File

@ -76,7 +76,6 @@ public:
virtual void draw_end();
virtual void shape(const Fl_Image* img);
virtual void draw();
// that one is implemented in Fl_Cocoa.mm because it uses Objective-c
virtual void capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right);
//this one is in Fl_cocoa.mm because it uses Objective-c

View File

@ -99,10 +99,10 @@ void Fl_Cocoa_Window_Driver::flush_overlay()
if ( i->other_xid ) {
fl_begin_offscreen( i->other_xid );
fl_clip_region( 0 );
draw();
pWindow->draw();
fl_end_offscreen();
} else {
draw();
pWindow->draw();
}
}
if (erase_overlay) fl_clip_region(0);
@ -116,12 +116,13 @@ void Fl_Cocoa_Window_Driver::flush_overlay()
void Fl_Cocoa_Window_Driver::draw_begin()
{
CGContextRef gc = (CGContextRef)Fl_Surface_Device::surface()->driver()->gc();
if (shape_data_) {
# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
if (shape_data_->mask && (&CGContextClipToMask != NULL)) {
CGContextClipToMask(fl_gc, CGRectMake(0,0,pWindow->w(),pWindow->h()), shape_data_->mask); // requires Mac OS 10.4
CGContextClipToMask(gc, CGRectMake(0,0,pWindow->w(),pWindow->h()), shape_data_->mask); // requires Mac OS 10.4
}
CGContextSaveGState(fl_gc);
CGContextSaveGState(gc);
# endif
}
}
@ -131,7 +132,8 @@ void Fl_Cocoa_Window_Driver::draw_end()
{
// on OS X, windows have no frame. Before OS X 10.7, to resize a window, we drag the lower right
// corner. This code draws a little ribbed triangle for dragging.
if (fl_mac_os_version < 100700 && fl_gc && !pWindow->parent() && pWindow->resizable() &&
CGContextRef gc = (CGContextRef)Fl_Surface_Device::surface()->driver()->gc();
if (fl_mac_os_version < 100700 && gc && !pWindow->parent() && pWindow->resizable() &&
(!pWindow->size_range_set || pWindow->minh!=pWindow->maxh || pWindow->minw!=pWindow->maxw)) {
int dx = Fl::box_dw(pWindow->box())-Fl::box_dx(pWindow->box());
int dy = Fl::box_dh(pWindow->box())-Fl::box_dy(pWindow->box());
@ -151,7 +153,7 @@ void Fl_Cocoa_Window_Driver::draw_end()
}
}
# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
if (shape_data_) CGContextRestoreGState(fl_gc);
if (shape_data_) CGContextRestoreGState(gc);
# endif
}
@ -240,44 +242,6 @@ void Fl_Cocoa_Window_Driver::shape(const Fl_Image* img) {
#endif
}
void Fl_Cocoa_Window_Driver::draw()
{
CGContextRef gc = (CGContextRef)Fl_Surface_Device::surface()->driver()->gc();
if (shape_data_) {
# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
if (shape_data_->mask && (&CGContextClipToMask != NULL)) {
CGContextClipToMask(gc, CGRectMake(0,0, pWindow->w(), pWindow->h()), shape_data_->mask); // requires Mac OS 10.4
}
CGContextSaveGState(gc);
# endif
}
Fl_Window_Driver::draw();
// on OS X, windows have no frame. Before OS X 10.7, to resize a window, we drag the lower right
// corner. This code draws a little ribbed triangle for dragging.
if (fl_mac_os_version < 100700 && gc && !pWindow->parent() && pWindow->resizable() ) {
int dx = Fl::box_dw(pWindow->box())-Fl::box_dx(pWindow->box());
int dy = Fl::box_dh(pWindow->box())-Fl::box_dy(pWindow->box());
if (dx<=0) dx = 1;
if (dy<=0) dy = 1;
int x1 = pWindow->w()-dx-1, x2 = x1, y1 = pWindow->h()-dx-1, y2 = y1;
Fl_Color c[4] = {
pWindow->color(),
fl_color_average(pWindow->color(), FL_WHITE, 0.7f),
fl_color_average(pWindow->color(), FL_BLACK, 0.6f),
fl_color_average(pWindow->color(), FL_BLACK, 0.8f),
};
int i;
for (i=dx; i<12; i++) {
fl_color(c[i&3]);
fl_line(x1--, y1, x2, y2--);
}
}
# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
if (shape_data_) CGContextRestoreGState(gc);
# endif
}
//
// End of "$Id$".
//

View File

@ -17,7 +17,7 @@
//
#include <FL/Fl_Printer.H>
#include <config.h>
#include <src/config_lib.h>
#include <FL/Fl.H>
#include <FL/fl_ask.H>
#include <FL/fl_draw.H>
@ -1557,15 +1557,21 @@ void Fl_PostScript_File_Device::end_job (void)
#endif // FL_DOXYGEN
#if defined(__APPLE__) // PORTME: Fl_Surface_Driver ? - platform PostScript
#elif defined(WIN32)
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: implement postscript printing"
#else // X11
#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_Printer::Helper::start_job(int pages, int *firstpage, int *lastpage) {
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;
@ -1661,7 +1667,7 @@ int Fl_Printer::Helper::start_job(int pages, int *firstpage, int *lastpage) {
return ps->start_postscript(pages, format, layout); // start printing
}
#endif // ! (defined(__APPLE__) || defined(WIN32) ) // PORTME: Fl_Surface_Driver - platform PostScript
#endif // defined(FL_CFG_PRN_PS)
//

View File

@ -77,7 +77,6 @@ public:
virtual void flush_double();
virtual void flush_overlay();
virtual void draw_begin();
virtual void draw_end();
virtual void shape(const Fl_Image* img);
virtual void icons(const Fl_RGB_Image *icons[], int count);

View File

@ -255,11 +255,6 @@ void Fl_WinAPI_Window_Driver::draw_begin()
}
void Fl_WinAPI_Window_Driver::draw_end()
{
}
void Fl_WinAPI_Window_Driver::flush_single()
{
if (!pWindow->shown()) return;
@ -287,7 +282,7 @@ void Fl_WinAPI_Window_Driver::flush_double()
fl_clip_region(i->region); i->region = 0;
fl_begin_offscreen(i->other_xid);
fl_graphics_driver->clip_region( 0 );
draw();
pWindow->draw();
fl_end_offscreen();
}
@ -317,7 +312,7 @@ void Fl_WinAPI_Window_Driver::flush_overlay()
fl_clip_region(i->region); i->region = 0;
fl_begin_offscreen(i->other_xid);
fl_graphics_driver->clip_region(0);
draw();
pWindow->draw();
fl_end_offscreen();
}

View File

@ -81,10 +81,8 @@ public:
virtual void flush_double();
virtual void flush_overlay();
virtual void draw_begin();
virtual void draw_end();
virtual void shape(const Fl_Image* img);
virtual void draw();
virtual void icons(const Fl_RGB_Image *icons[], int count);
virtual const void *icon() const;
virtual void icon(const void * ic);

View File

@ -148,11 +148,6 @@ void Fl_X11_Window_Driver::draw_begin()
}
void Fl_X11_Window_Driver::draw_end()
{
}
void Fl_X11_Window_Driver::flush_single()
{
if (!pWindow->shown()) return;
@ -394,16 +389,6 @@ void Fl_X11_Window_Driver::combine_mask()
}
void Fl_X11_Window_Driver::draw() {
if (shape_data_) {
if (( shape_data_->lw_ != pWindow->w() || shape_data_->lh_ != pWindow->h() ) && shape_data_->shape_) {
// size of window has changed since last time
combine_mask();
}
}
Fl_Window_Driver::draw();
}
void Fl_X11_Window_Driver::icons(const Fl_RGB_Image *icons[], int count) {
free_icons();

View File

@ -30,6 +30,7 @@ Fl_Image_Surface::Helper::Helper(int w, int h, int high_res) : Fl_Widget_Surface
width = w;
height = h;
previous = 0;
fl_open_display();
offscreen = XCreatePixmap(fl_display, RootWindow(fl_display, fl_screen), w, h, fl_visual->depth);
driver(new Fl_Translated_Xlib_Graphics_Driver());
}